diff --git a/.codespellrc b/.codespellrc index 251af7fcf..adada9132 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,2 +1,2 @@ [codespell] -ignore-words-list = aNULL,brose,doub,Udo,re-use,re-used,registr,shema,commet,Commet +ignore-words-list = aNULL,brose,doub,Udo,re-use,re-used,registr,shema,commet,Commet,Bloks diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..efca66f04 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2025 Jonah Aragon +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +FROM ghcr.io/devture/ansible:14.0.0-r0-3 + +# Install additional packages +RUN apk add --no-cache \ + pwgen + +# Preserve command history across container restarts +RUN SNIPPET="export HISTFILE=/commandhistory/.ash_history" \ + && echo "$SNIPPET" >> "/root/.profile" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..45b130314 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,27 @@ +{ + "name": "matrix-docker-ansible-deploy", + "build": { + "dockerfile": "Dockerfile", + "context": ".." + }, + "postCreateCommand": { + "Fix Volume Permissions": "chown -R $(whoami): /commandhistory" + }, + "mounts": [ + { + "source": "matrix-docker-ansible-deploy-bashhistory", + "target": "/commandhistory", + "type": "volume" + } + ], + "customizations": { + "vscode": { + "extensions": [ + "EditorConfig.EditorConfig", + "redhat.ansible", + "redhat.vscode-yaml", + "ms-python.python" + ] + } + } +} diff --git a/.devcontainer/devcontainer.json.license b/.devcontainer/devcontainer.json.license new file mode 100644 index 000000000..5a4ddcde2 --- /dev/null +++ b/.devcontainer/devcontainer.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2025 Jonah Aragon + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml deleted file mode 100644 index dad8d2cf2..000000000 --- a/.github/dependabot.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: daily diff --git a/.github/renovate.json b/.github/renovate.json index 6a6a83859..dcc8e86ab 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,33 +1,203 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ], - "labels": [ - "dependencies" - ], - "customManagers": [ - { - "customType": "regex", - "managerFilePatterns": [ - "/defaults/main.yml$/" - ], - "matchStrings": [ - "# renovate: datasource=(?[a-z-.]+?) depName=(?[^\\s]+?)(?: (?:lookupName|packageName)=(?[^\\s]+?))?(?: versioning=(?[a-z-0-9]+?))?\\s+[A-Za-z0-9_]+?(?:_version|_tag)\\s*:\\s*[\"']?(?.+?)[\"']?\\s" - ] - } - ], - "packageRules": [ - { - "ignoreUnstable": false, - "versioning": "loose", - "matchSourceUrls": [ - "https://github.com/devture/com.devture.ansible.role{/,}**", - "https://github.com/mother-of-all-self-hosting{/,}**" - ] - } - ], - "pre-commit": { - "enabled": true - } + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended", + "helpers:pinGitHubActionDigests" + ], + "labels": [ + "dependencies" + ], + "branchConcurrentLimit": 5, + "prConcurrentLimit": 3, + "hostRules": [ + { + "matchHost": "https://mau.dev", + "concurrentRequestLimit": 2, + "maxRequestsPerSecond": 2 + }, + { + "matchHost": "https://dock.mau.dev", + "concurrentRequestLimit": 4, + "maxRequestsPerSecond": 4 + } + ], + "customManagers": [ + { + "customType": "regex", + "managerFilePatterns": [ + "/defaults/main.yml$/" + ], + "matchStrings": [ + "# renovate: datasource=(?[a-z-.]+?) depName=(?[^\\s]+?)(?: (?:lookupName|packageName)=(?[^\\s]+?))?(?: versioning=(?[a-z-0-9]+?))?\\s+[A-Za-z0-9_]+?(?:_version|_tag)\\s*:\\s*[\"']?(?.+?)[\"']?\\s" + ] + }, + { + "description": "Helper container images used by the Molecule scenarios. They are pinned once in molecule-shared/vars.yml rather than inline in each role's verify.yml, so this manager keeps that single pin current.", + "customType": "regex", + "managerFilePatterns": [ + "/^molecule-shared/vars\\.yml$/" + ], + "matchStrings": [ + "# renovate: datasource=(?[a-z-.]+?) depName=(?[^\\s]+?)\\s+[A-Za-z0-9_]+?\\s*:\\s*[\"'][^:]+:(?[^\"']+)[\"']" + ] + }, + { + "customType": "regex", + "description": "Update the self-hosted Renovate runner version", + "managerFilePatterns": [ + "/^\\.github\\/workflows\\/renovate\\.yml$/" + ], + "matchStrings": [ + "# renovate: datasource=(?\\S+) depName=(?\\S+) packageName=(?\\S+)\\s+MATRIX_RENOVATE_VERSION: '(?[^']+)'" + ] + } + ], + "packageRules": [ + { + "ignoreUnstable": false, + "versioning": "loose", + "matchSourceUrls": [ + "https://github.com/devture/com.devture.ansible.role{/,}**", + "https://github.com/mother-of-all-self-hosting{/,}**" + ] + }, + { + "description": "mautrix images are dual-tagged (v0.YYMM.PATCH and vYY.MM[.PATCH]). Stick to the v0 scheme: it matches the git tags (needed for self-building) and has a consistent number of components (the calver tags do not, which makes Renovate stop offering updates).", + "matchPackageNames": [ + "dock.mau.dev/mautrix/**" + ], + "allowedVersions": "/^v0\\./" + }, + { + "description": "Automerge version bumps of roles maintained in the MASH organization and of devture roles (via branch push - no PR)", + "matchManagers": [ + "ansible-galaxy" + ], + "matchSourceUrls": [ + "https://github.com/devture/com.devture.ansible.role{/,}**", + "https://github.com/mother-of-all-self-hosting{/,}**" + ], + "automerge": true, + "automergeType": "branch" + }, + { + "description": "Housekeeping updates merge via branch push (no PR, no email); a failure on the branch still surfaces as a PR. i18n/requirements.txt bumps are exercised by the Matrix i18n workflow before merging.", + "matchFileNames": [ + ".github/workflows/close-stale-issues.yml", + ".github/workflows/i18n.yml", + ".github/workflows/lock-threads.yml", + ".github/workflows/matrix.yml", + ".github/workflows/renovate-smoke-test.yml", + ".github/workflows/renovate.yml", + ".github/workflows/update-translations.yml", + "flake.nix", + "flake.lock", + "i18n/requirements.txt", + "mise.toml" + ], + "automerge": true, + "automergeType": "branch" + }, + { + "description": "Automerge updates of the self-hosted Renovate runner (via branch push - no PR)", + "matchManagers": [ + "custom.regex" + ], + "matchDepNames": [ + "matrix-renovate-runner" + ], + "automerge": true, + "automergeType": "branch" + }, + { + "description": "Molecule's own dependencies merge via branch push (no PR, no email). Anything under molecule-shared/ - the helper container images, Postgres, and the Python pins - triggers the Molecule workflow, and a change to a shared file makes it run every scenario, so an update only merges once the whole suite has passed on it. A failure surfaces as a PR instead. This is how a new Postgres major reaches us: the bump runs every scenario against it before anything is merged.", + "matchFileNames": [ + "molecule-shared/**", + ".github/workflows/molecule.yml" + ], + "automerge": true, + "automergeType": "branch" + }, + { + "description": "Automerge patch bumps of components whose role has a Molecule scenario (via branch push - no PR). A bump touches that role's defaults/main.yml, which makes the Molecule workflow run that role's scenario, so the update only merges once the component has been started on the configuration the role renders. Patch is the baseline for every covered role; explicitly approved roles may also appear in the narrower minor rule below. Keep this list in step with the roles that have a scenario - bin/check-molecule-automerge-list.py (patch rule) enforces that.", + "matchFileNames": [ + "roles/custom/matrix-alertmanager-receiver/defaults/main.yml", + "roles/custom/matrix-authentication-service/defaults/main.yml", + "roles/custom/matrix-bot-baibot/defaults/main.yml", + "roles/custom/matrix-bot-draupnir/defaults/main.yml", + "roles/custom/matrix-bot-honoroit/defaults/main.yml", + "roles/custom/matrix-bot-maubot/defaults/main.yml", + "roles/custom/matrix-bot-matrix-reminder-bot/defaults/main.yml", + "roles/custom/matrix-bot-meowlnir/defaults/main.yml", + "roles/custom/matrix-bridge-beeper-line/defaults/main.yml", + "roles/custom/matrix-bridge-heisenbridge/defaults/main.yml", + "roles/custom/matrix-bridge-hookshot/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-bluesky/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-discord/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-gmessages/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-googlechat/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-gvoice/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-linkedin/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-meta-instagram/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-meta-messenger/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-signal/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-slack/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-telegram/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-twitter/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-whatsapp/defaults/main.yml", + "roles/custom/matrix-bridge-postmoogle/defaults/main.yml", + "roles/custom/matrix-bridge-steam/defaults/main.yml", + "roles/custom/matrix-client-element/defaults/main.yml", + "roles/custom/matrix-client-fluffychat/defaults/main.yml", + "roles/custom/matrix-element-admin/defaults/main.yml", + "roles/custom/matrix-element-call/defaults/main.yml", + "roles/custom/matrix-ketesa/defaults/main.yml", + "roles/custom/matrix-livekit-jwt-service/defaults/main.yml", + "roles/custom/matrix-static-files/defaults/main.yml", + "roles/custom/matrix-synapse/defaults/main.yml", + "roles/custom/matrix-synapse-auto-compressor/defaults/main.yml" + ], + "matchUpdateTypes": [ + "patch" + ], + "automerge": true, + "automergeType": "branch" + }, + { + "description": "Automerge minor bumps of explicitly approved components with a weight-bearing Molecule scenario (via branch push - no PR). This list is intentionally narrower than the patch rule: the scenario must exercise enough real behavior to be a useful compatibility gate across a minor release. A failure surfaces as a PR instead. Keep every entry backed by a scenario and the patch rule - bin/check-molecule-automerge-list.py (minor rule) enforces that.", + "matchFileNames": [ + "roles/custom/matrix-authentication-service/defaults/main.yml", + "roles/custom/matrix-bot-honoroit/defaults/main.yml", + "roles/custom/matrix-bot-meowlnir/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-bluesky/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-gmessages/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-googlechat/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-gvoice/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-linkedin/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-slack/defaults/main.yml", + "roles/custom/matrix-bridge-mautrix-twitter/defaults/main.yml", + "roles/custom/matrix-bridge-steam/defaults/main.yml", + "roles/custom/matrix-client-fluffychat/defaults/main.yml", + "roles/custom/matrix-element-admin/defaults/main.yml", + "roles/custom/matrix-element-call/defaults/main.yml", + "roles/custom/matrix-livekit-jwt-service/defaults/main.yml", + "roles/custom/matrix-static-files/defaults/main.yml", + "roles/custom/matrix-synapse-auto-compressor/defaults/main.yml" + ], + "matchUpdateTypes": [ + "minor" + ], + "automerge": true, + "automergeType": "branch" + } + ], + "pre-commit": { + "enabled": true + }, + "nix": { + "enabled": true, + "lockFileMaintenance": { + "enabled": true + } + } } diff --git a/.github/workflows/close-stale-issues.yml b/.github/workflows/close-stale-issues.yml index 78df98cf9..2ab643340 100644 --- a/.github/workflows/close-stale-issues.yml +++ b/.github/workflows/close-stale-issues.yml @@ -19,7 +19,7 @@ jobs: if: github.repository == 'spantaleev/matrix-docker-ansible-deploy' runs-on: ubuntu-latest steps: - - uses: actions/stale@v10 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11 with: ###################################################################### # Issues/PRs diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml new file mode 100644 index 000000000..e379526e5 --- /dev/null +++ b/.github/workflows/i18n.yml @@ -0,0 +1,48 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +name: Matrix i18n + +# Exercises the translation toolchain whenever something under i18n/ changes, +# so that a dependency bump which breaks Sphinx/Babel fails here - before it +# gets merged - rather than in the next scheduled translations run. +on: # yamllint disable-line rule:truthy + push: + paths: + - "i18n/**" + - ".github/workflows/i18n.yml" + pull_request: + paths: + - "i18n/**" + - ".github/workflows/i18n.yml" + workflow_dispatch: + +permissions: + contents: read + +jobs: + extract-translation-templates: + name: Extract translation templates + runs-on: ubuntu-24.04 + + # Same-repository pull requests already run via the push event; + # run pull_request jobs only for pull requests from forks. + if: >- + github.event_name != 'pull_request' + || github.event.pull_request.head.repo.full_name != github.repository + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 + with: + python-version: '3.14' + + - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 + + - uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 + + - name: Extract translation catalog templates (POT) files + run: just --justfile i18n/justfile extract-translation-templates diff --git a/.github/workflows/lock-threads.yml b/.github/workflows/lock-threads.yml index 0cee26857..b715671a2 100644 --- a/.github/workflows/lock-threads.yml +++ b/.github/workflows/lock-threads.yml @@ -23,7 +23,7 @@ jobs: if: github.repository == 'spantaleev/matrix-docker-ansible-deploy' runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v6 + - uses: dessant/lock-threads@89ae32b08ed1a541efecbab17912962a5e38981c # v6 with: add-issue-labels: 'outdated' process-only: 'issues, prs' diff --git a/.github/workflows/matrix.yml b/.github/workflows/matrix.yml index 278791aa2..1800c25bc 100644 --- a/.github/workflows/matrix.yml +++ b/.github/workflows/matrix.yml @@ -26,10 +26,10 @@ jobs: run: pacman -Sy --noconfirm git - name: Check out - uses: actions/checkout@v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Restore prek cache - uses: actions/cache@v5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6 with: path: var/prek key: arch-prek-v1-${{ hashFiles('.pre-commit-config.yaml') }} diff --git a/.github/workflows/molecule.yml b/.github/workflows/molecule.yml new file mode 100644 index 000000000..8484f4eae --- /dev/null +++ b/.github/workflows/molecule.yml @@ -0,0 +1,161 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +name: Molecule + +# Unlike the MASH role repositories, where one repository holds one role, every +# role here lives in the same repository. Running every scenario on every push +# would be unaffordable, so a first job works out which roles the push actually +# touched and the matrix is built from that. A push that changes documentation, +# or a role with no scenario yet, runs nothing at all. +on: # yamllint disable-line rule:truthy + push: + paths: + - "roles/custom/**" + - "molecule-shared/**" + - ".github/workflows/molecule.yml" + pull_request: + paths: + - "roles/custom/**" + - "molecule-shared/**" + - ".github/workflows/molecule.yml" + workflow_dispatch: + inputs: + role: + description: "Single role to test (directory name under roles/custom), or empty for all roles that have a scenario" + required: false + type: string + +permissions: + contents: read + +jobs: + detect: + name: Work out which roles to test + runs-on: ubuntu-latest + + # Same rule as the MASH repositories: a pull request from a branch of this + # repository would otherwise run everything twice, once for the push and + # once for the pull request. + if: >- + github.event_name != 'pull_request' + || github.event.pull_request.head.repo.full_name != github.repository + + outputs: + roles: ${{ steps.detect.outputs.roles }} + + steps: + - name: Check out + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + + - name: Detect roles with a Molecule scenario that this change touches + id: detect + env: + EVENT_NAME: ${{ github.event_name }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} + BEFORE_SHA: ${{ github.event.before }} + INPUT_ROLE: ${{ inputs.role }} + run: | + set -euo pipefail + + have_scenario() { + [ -f "roles/custom/$1/molecule/default/molecule.yml" ] + } + + # An explicit request through workflow_dispatch wins over detection. + if [ -n "${INPUT_ROLE}" ]; then + if have_scenario "${INPUT_ROLE}"; then + printf 'roles=["%s"]\n' "${INPUT_ROLE}" >> "$GITHUB_OUTPUT" + else + echo "No scenario at roles/custom/${INPUT_ROLE}/molecule/default" >&2 + exit 1 + fi + exit 0 + fi + + # A hand-triggered run with no role named, and any run where the diff + # base is unusable (a new branch, a force push, the very first commit), + # falls back to every role that has a scenario. That is the safe + # direction to fail in: too much testing rather than too little. + base="" + case "${EVENT_NAME}" in + pull_request) base="${BASE_SHA}" ;; + push) + if [ -n "${BEFORE_SHA}" ] && [ "${BEFORE_SHA}" != "0000000000000000000000000000000000000000" ] \ + && git cat-file -e "${BEFORE_SHA}^{commit}" 2>/dev/null; then + base="${BEFORE_SHA}" + fi + ;; + esac + + # molecule-shared/ is used by every scenario, so a change there means + # every role has to run, not just the ones whose own files moved. + shared_changed="" + if [ -n "${base}" ]; then + shared_changed="$(git diff --name-only "${base}" HEAD -- 'molecule-shared/*' '.github/workflows/molecule.yml' || true)" + fi + + if [ -n "${base}" ] && [ -z "${shared_changed}" ]; then + changed="$(git diff --name-only "${base}" HEAD -- 'roles/custom/*' || true)" + candidates="$(printf '%s\n' "${changed}" | awk -F/ 'NF>2 {print $3}' | sort -u)" + echo "Changed roles: ${candidates:-none}" + else + if [ -n "${shared_changed}" ]; then + echo "Shared Molecule files changed; considering every role" + fi + candidates="$(find roles/custom -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | sort)" + fi + + selected="" + for role in ${candidates}; do + if have_scenario "${role}"; then + selected="${selected} ${role}" + fi + done + + if [ -z "${selected}" ]; then + echo "Nothing to test" + echo 'roles=[]' >> "$GITHUB_OUTPUT" + exit 0 + fi + + echo "Testing:${selected}" + json="$(printf '%s\n' ${selected} | jq -R . | jq -c -s .)" + echo "roles=${json}" >> "$GITHUB_OUTPUT" + + molecule: + name: "Molecule: ${{ matrix.role }}" + runs-on: ubuntu-latest + + needs: detect + if: needs.detect.outputs.roles != '[]' + + strategy: + matrix: + role: ${{ fromJson(needs.detect.outputs.roles) }} + fail-fast: false + + env: + MOLECULE_DISTRO: ubuntu2604 + PY_COLORS: "1" + ANSIBLE_FORCE_COLOR: "1" + + steps: + - name: Check out + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + + - name: Set up Python + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 + with: + python-version: "3.x" + + - name: Install test dependencies + run: python3 -m pip install -r molecule-shared/requirements.txt + + - name: Run Molecule + working-directory: roles/custom/${{ matrix.role }} + run: molecule test --scenario-name default diff --git a/.github/workflows/renovate-smoke-test.yml b/.github/workflows/renovate-smoke-test.yml new file mode 100644 index 000000000..b2b0945d0 --- /dev/null +++ b/.github/workflows/renovate-smoke-test.yml @@ -0,0 +1,65 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +name: Renovate smoke test + +on: # yamllint disable-line rule:truthy + push: + paths: + - '.github/renovate.json' + - '.github/workflows/renovate-smoke-test.yml' + - '.github/workflows/renovate.yml' + pull_request: + paths: + - '.github/renovate.json' + - '.github/workflows/renovate-smoke-test.yml' + - '.github/workflows/renovate.yml' + workflow_dispatch: + +permissions: + contents: read + +jobs: + validate: + name: Validate config with the pinned Renovate image + runs-on: ubuntu-latest + + # Same-repository pull requests already run via the push event; + # run pull_request jobs only for pull requests from forks. + if: >- + github.event_name != 'pull_request' + || github.event.pull_request.head.repo.full_name != github.repository + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + + - name: Resolve the pinned Renovate version + id: renovate_version + shell: bash + run: | + set -euo pipefail + + mapfile -t versions < <( + sed -n "s/^ MATRIX_RENOVATE_VERSION: '\([^']*\)'$/\1/p" \ + .github/workflows/renovate.yml + ) + + if (( ${#versions[@]} != 1 )) || [[ -z "${versions[0]}" ]]; then + echo 'Could not resolve exactly one pinned Renovate version' >&2 + exit 1 + fi + + echo "version=${versions[0]}" >> "$GITHUB_OUTPUT" + + - name: Validate the Renovate configuration + env: + RENOVATE_VERSION: ${{ steps.renovate_version.outputs.version }} + run: | + docker run --rm \ + --volume "$GITHUB_WORKSPACE:/workspace:ro" \ + --workdir /workspace \ + --entrypoint renovate-config-validator \ + "ghcr.io/renovatebot/renovate:$RENOVATE_VERSION" \ + --strict diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml new file mode 100644 index 000000000..8b521ef80 --- /dev/null +++ b/.github/workflows/renovate.yml @@ -0,0 +1,155 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +name: Renovate + +on: # yamllint disable-line rule:truthy + schedule: + # Discover new updates hourly. Reactive runs below drain active updates. + - cron: '17 * * * *' + workflow_dispatch: + inputs: + dry_run: + description: 'Run without making changes' + required: false + default: true + type: boolean + log_level: + description: 'Renovate log level' + required: false + default: 'info' + type: choice + options: + - info + - debug + - trace + push: + branches: ['master'] + workflow_run: + workflows: ['Matrix CI', 'Matrix i18n', 'Molecule', 'Renovate smoke test'] + types: [completed] + branches: ['renovate/**'] + issues: + types: [edited] + +permissions: + contents: read + +env: + # Mend-hosted Renovate must remain disabled while this automation is enabled. + # A manual dry-run remains available if this switch is disabled during migration. + MATRIX_RENOVATE_AUTOMATION_ENABLED: 'true' + + # renovate: datasource=docker depName=matrix-renovate-runner packageName=ghcr.io/renovatebot/renovate + MATRIX_RENOVATE_VERSION: '44.64.0' + +jobs: + preflight: + name: Decide whether to run Renovate + runs-on: ubuntu-latest + outputs: + should_run: ${{ steps.decision.outputs.should_run }} + + steps: + - name: Evaluate trigger + id: decision + shell: bash + env: + GH_TOKEN: ${{ github.token }} + EVENT_NAME: ${{ github.event_name }} + EVENT_REF: ${{ github.ref }} + MANUAL_DRY_RUN: ${{ inputs.dry_run }} + WORKFLOW_RUN_CONCLUSION: ${{ github.event.workflow_run.conclusion }} + WORKFLOW_RUN_EVENT: ${{ github.event.workflow_run.event }} + ISSUE_TITLE: ${{ github.event.issue.title }} + SENDER_TYPE: ${{ github.event.sender.type }} + run: | + set -euo pipefail + + should_run=false + reason='Automatic Renovate processing is disabled during migration' + + if [[ "$EVENT_NAME" == 'workflow_dispatch' ]]; then + if [[ "$EVENT_REF" != 'refs/heads/master' ]]; then + reason='Manual runs must use the master branch' + elif [[ "$MANUAL_DRY_RUN" == 'true' || "$MATRIX_RENOVATE_AUTOMATION_ENABLED" == 'true' ]]; then + should_run=true + reason='Running manually requested Renovate job' + else + reason='Enable automatic processing before requesting a write run' + fi + elif [[ "$MATRIX_RENOVATE_AUTOMATION_ENABLED" == 'true' ]]; then + case "$EVENT_NAME" in + schedule) + should_run=true + reason='Running scheduled update discovery' + ;; + workflow_run) + if [[ "$WORKFLOW_RUN_CONCLUSION" == 'success' && "$WORKFLOW_RUN_EVENT" == 'push' ]]; then + should_run=true + reason='A Renovate branch passed one of its status-check workflows' + else + reason='The completed check was not a successful Renovate branch push' + fi + ;; + issues) + if [[ "$ISSUE_TITLE" == 'Dependency Dashboard' && "$SENDER_TYPE" == 'User' ]]; then + should_run=true + reason='A user edited the Dependency Dashboard' + else + reason='The issue edit was not a user editing the Dependency Dashboard' + fi + ;; + push) + renovate_branch_count="$( + gh api \ + "repos/$GITHUB_REPOSITORY/git/matching-refs/heads/renovate" \ + --jq 'length' + )" + if (( renovate_branch_count > 0 )); then + should_run=true + reason="master changed while ${renovate_branch_count} Renovate branch(es) exist" + else + reason='master changed, but there are no Renovate branches to process' + fi + ;; + esac + fi + + echo "should_run=$should_run" >> "$GITHUB_OUTPUT" + echo "$reason" + + renovate: + name: Renovate + needs: preflight + if: needs.preflight.outputs.should_run == 'true' + runs-on: ubuntu-latest + environment: main + concurrency: + group: renovate + cancel-in-progress: false + + steps: + - name: Create Renovate App token + id: renovate_token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + client-id: ${{ vars.GH_APP_RENOVATE_CLIENT_ID }} + private-key: ${{ secrets.GH_APP_RENOVATE_PRIVATE_KEY }} + + - name: Run Renovate + uses: renovatebot/github-action@39b914146caeff8cd512e61c8992f1d5913af85c # v46.2.5 + with: + token: ${{ steps.renovate_token.outputs.token }} + renovate-version: ${{ env.MATRIX_RENOVATE_VERSION }} + env: + LOG_LEVEL: ${{ inputs.log_level || 'info' }} + RENOVATE_DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run && 'full' || '' }} + # Permit the self-hosted App to adopt branches created by the Mend-hosted App. + RENOVATE_GIT_IGNORED_AUTHORS: '["29139614+renovate[bot]@users.noreply.github.com"]' + RENOVATE_IGNORE_PR_AUTHOR: 'true' + RENOVATE_PLATFORM: github + RENOVATE_PLATFORM_COMMIT: enabled + RENOVATE_REPOSITORIES: ${{ github.repository }} diff --git a/.github/workflows/update-translations.yml b/.github/workflows/update-translations.yml index 71cbbf985..88b63ad5b 100644 --- a/.github/workflows/update-translations.yml +++ b/.github/workflows/update-translations.yml @@ -6,13 +6,7 @@ name: Update translations on: # yamllint disable-line rule:truthy - push: - branches: - - master - paths: # See include_patterns on conf.py - - 'docs/*.md' - - 'i18n/README.md' - - '*.md' + workflow_dispatch: permissions: contents: write @@ -24,23 +18,23 @@ jobs: name: Update translations runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - - uses: actions/setup-python@v6 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: '3.14' # Setting up recommended prerequisites # See: i18n/README.md - - uses: astral-sh/setup-uv@v7 - - uses: extractions/setup-just@v3 + - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 + - uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4 # TODO: optimize when we start publishing translations and integrate a Weblate instance - name: Update translation catalog templates (POT) files run: just --justfile i18n/justfile extract-translation-templates - name: Create Pull Request - uses: peter-evans/create-pull-request@v8.1.0 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> # Same as committer body: This is an automatic pull request to update translation files. diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f7f23a539..a9277a934 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 + rev: v2.4.3 hooks: - id: codespell args: ["--skip=*.po,*.pot,i18n/"] @@ -24,7 +24,7 @@ repos: hooks: - id: reuse - repo: https://github.com/ansible/ansible-lint - rev: v26.3.0 + rev: v26.8.0 hooks: - id: ansible-lint files: '^roles/custom/' @@ -38,3 +38,9 @@ repos: language: script files: '(examples/vars\.yml|roles/custom/matrix_playbook_migration/defaults/main\.yml)' pass_filenames: false + - id: check-molecule-automerge-list + name: Check the Molecule automerge rules match the roles that have a scenario + entry: bin/check-molecule-automerge-list.py + language: script + files: '(\.github/renovate\.json|bin/check-molecule-automerge-list\.py|roles/custom/[^/]+/molecule/default/molecule\.yml)' + pass_filenames: false diff --git a/.yamllint b/.yamllint index 75da2b702..5fc2c40eb 100644 --- a/.yamllint +++ b/.yamllint @@ -1,5 +1,16 @@ --- extends: default +# Keep this custom configuration compatible with ansible-lint's `yaml` rule. +# See https://docs.ansible.com/projects/lint/rules/yaml/#yamllint-configuration rules: + braces: + min-spaces-inside: 0 + max-spaces-inside: 1 + comments: + min-spaces-from-content: 1 + comments-indentation: false line-length: disable + octal-values: + forbid-explicit-octal: true + forbid-implicit-octal: true diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..1497ef607 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,41 @@ + + +# Guidance for AI agents + +This file gives AI coding agents the minimum context for working on this repository. Human contributors may find it a useful summary too. + +## What this is + +An Ansible playbook that installs and manages a Matrix homeserver and dozens of related services, each running as a Docker container wrapped in a systemd service. + +## Layout + +- `setup.yml`: the main playbook, listing all roles. +- `roles/custom/`: roles maintained in this repository. +- `roles/galaxy/`: external roles, downloaded according to `requirements.yml` via [agru](https://github.com/etkecc/agru) (preferred) or `ansible-galaxy`. Run `just roles` to install them (or `just update` to also pull the playbook itself). Editing these roles locally is fine while preparing or testing a fix, but the changes get wiped on the next roles update, so they must be synced back to the role's upstream repository, followed by a version pin update in `requirements.yml`. +- `group_vars/matrix_servers`: wires roles together (feeding one role's variables into another). Values a role can construct by itself belong in the role's `defaults/main.yml`, not here. +- `docs/`: user-facing documentation, one page per component. +- `molecule-shared/`: files shared by the roles' Molecule scenarios (Python and Ansible dependencies, pinned helper container images). +- `i18n/`: translation infrastructure. Do not edit locale files by hand; they are managed by automation. +- `CHANGELOG.md`: user-facing announcements, newest first. + +## Conventions + +Follow the [style guide for playbook developers](docs/style-guide.md). In particular: + +- Variable prefixes match the role directory name. +- Playbook-extensible list variables use the `_auto` + `_custom` split; `_custom` is reserved for users. +- Renamed or removed variables get a validation entry, so stale user configuration produces an error instead of being silently ignored. Each role deprecates its own variables in its `validate_config.yml`; the `matrix_playbook_migration` role covers eliminated roles and very-early validation, and also gates breaking changes via `matrix_playbook_migration_expected_version` (see the style guide). +- Every file carries SPDX license headers ([REUSE](https://reuse.software/) specification). +- Roles may carry a Molecule scenario, proving the component starts and does not choke on the configuration the role rendered. Run one with `just molecule ` (no argument lists the roles that have one); CI runs only the scenarios of roles a push touched. See [Molecule testing for roles](docs/molecule-testing.md) before writing one - roles here need context a standalone role does not. +- New components must be registered in `setup.yml`, `group_vars/matrix_servers`, `docs/README.md`, `README.md`, `docs/container-images.md`, and get a `CHANGELOG.md` entry. + +## Other notes + +- Documentation examples use `example.com`, `@alice:example.com`, and the other placeholder values listed in the style guide. +- Write role tasks concurrency-safe: use `ansible.builtin.tempfile` for temporary files (removed in an `always` block), never fixed shared paths. +- One logical change per commit. diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e456a286..e3bcc14d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,447 @@ +# 2026-08-20 + +## MatrixRTC transports are advertised in the client well-known again + +This only affects you if you have the [Matrix RTC stack](docs/configuring-playbook-matrix-rtc.md) or [Element Call](docs/configuring-playbook-element-call.md) enabled. + +Yesterday's changelog entry announced that the `org.matrix.msc4143.rtc_foci` property was gone from the `/.well-known/matrix/client` file. That turned out to be premature and has been reverted, so the property is published again as it always was. + +The property is indeed dropped from [MSC4143](https://github.com/matrix-org/matrix-spec-proposals/pull/4143) and [Element Call v0.24.0](https://github.com/element-hq/element-call/releases/tag/v0.24.0) no longer reads it, but Element Web (and likely other clients who move slowly or are otherwise outdated) does not ship that version of Element Call yet. Element Web v1.12.26 bundles Element Call v0.22.0, which still discovers your transport through the well-known property. It cannot use the homeserver's `/_matrix/client/unstable/org.matrix.msc4143/rtc/transports` API instead, because Element Call runs as a widget there and a widget holds no access token, while that API requires authentication. Newer Element Call versions ask their host client for the transports over the widget API ([MSC4515](https://github.com/matrix-org/matrix-spec-proposals/pull/4515)), which is what will eventually make the property unnecessary. + +Dropping the property therefore broke Element Call for Element Web and Element Desktop users, with a `MISSING_MATRIX_RTC_TRANSPORT` error when starting a call. Re-running the playbook (`just install-all`) brings the property back and fixes calls. + +If you worked around this by publishing the property yourself via `matrix_static_files_file_matrix_client_configuration_extension_json`, you can drop that from your `vars.yml` file now. The `matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_custom` variable and its companions are back as well. + +# 2026-08-13 + +## The homeserver root path redirects to clients other than Element Web + +Visiting `https://matrix.example.com/` used to redirect you to [Element Web](docs/configuring-playbook-client-element-web.md), but only if Element Web was the client installed by the playbook. With any of the other web clients (Cinny, Commet, FluffyChat, Hydrogen, SchildiChat, Sable), you would land on a bare Synapse page. + +The redirection now follows whichever of these clients you have enabled. When several are enabled, Element Web wins, followed by the others in the order that [`group_vars/matrix_servers`](group_vars/matrix_servers) lists them. + +To send people somewhere else (or nowhere at all), define `matrix_playbook_public_client_root_redirection_url` in your `vars.yml` file. An empty value disables the redirection. + +## Support for Meowlnir + +The playbook can now install [Meowlnir](https://github.com/maunium/meowlnir), an opinionated Matrix moderation bot, optimized for Synapse. + +Meowlnir joins [Draupnir](docs/configuring-playbook-bot-draupnir.md) and [Mjolnir](docs/configuring-playbook-bot-mjolnir.md) as a 3rd moderation option, speaking the same [policy list](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists) protocol so that it can subscribe to the same community ban lists. Unlike the others, it can override individual policies coming from lists you do not control (by way of an unban policy in a list of your own which is ordered ahead of other policy lists). + +You can run it alongside Draupnir while evaluating it — see the documentation for the caveats, the main one being that both want the [synapse-http-antispam](https://github.com/maunium/synapse-http-antispam) module, which only reports to a single consumer. + +To get started, see the [Setting up Meowlnir](docs/configuring-playbook-bot-meowlnir.md) documentation page. + + +# 2026-08-06 + +## (Backward Compatibility Break) Jitsi no longer uses Colibri WebSockets + +This only affects you if you have [Jitsi](docs/configuring-playbook-jitsi.md) enabled. + +Jitsi has been updated to `stable-11146-1`, which [removes Colibri WebSocket support](https://github.com/jitsi/docker-jitsi-meet/pull/2285) in favour of SCTP data channels. The Jitsi Video Bridge no longer serves HTTP at all, so a few `jitsi_jvb_*` variables are gone. The playbook will tell you which ones, if your configuration still sets them. + +If you run [additional JVBs on other hosts](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md#set-up-additional-jvbs-for-more-video-conferences-optional), the Traefik configuration which routed `/colibri-ws//` to them is now dead and can be removed. Nothing will warn you about that one, as it lives in a free-form `traefik_provider_configuration_extension_yaml` block. + +# 2026-07-28 + +## (Backward Compatibility Break) ntfy users are now declared with hashed passwords + +This only affects you if you have enabled authentication for [ntfy](docs/configuring-playbook-ntfy.md) via `ntfy_credentials`. + +The ntfy role used to create users by invoking `ntfy user` commands against the running container. Since v2.14.0, ntfy can provision users and access-control entries from its own configuration file, so the role now does that instead. Besides being a lot simpler, this fixes passwords containing spaces never arriving intact. + +Replace `ntfy_credentials` with `ntfy_auth_users_custom`, which takes bcrypt password hashes rather than plaintext passwords: + +```yaml +ntfy_auth_users_custom: + - username: alice + password_hash: $2a$10$YLiO8U21sX1uhZamTLJXHuxgVC0Z/GKISibrKCLohPgtG7yIxSk4C + role: admin +``` + +Generate a hash for each of your passwords by running the following command on any machine which has Docker installed. It asks for the password and prints its hash: + +```sh +docker run --rm -it docker.io/binwiederhier/ntfy:latest user hash +``` + +The playbook will let you know if your configuration still uses `ntfy_credentials`. + +Your existing ntfy users are left alone and keep working until you declare them again this way. Note that ntfy manages declared users and access-control entries declaratively, so removing one from your configuration later deletes it from ntfy's user database. + +Users with the `admin` role get access to all topics. Others start with no access at all, and can be granted access to specific topics via `ntfy_auth_access_custom`. It is also now possible to control what unauthenticated visitors may do (`ntfy_auth_default_access`) and whether users may log in at all (`ntfy_enable_login`, which follows your authentication setup by default). See the role's [documentation on access control](https://github.com/mother-of-all-self-hosting/ansible-role-ntfy/blob/main/docs/configuring-ntfy.md#enable-access-control-with-authentication-optional) for details. + +## Support for bridging to LinkedIn via mautrix-linkedin + +Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook now supports bridging to [LinkedIn](https://www.linkedin.com/) via [mautrix-linkedin](https://github.com/mautrix/linkedin). + +Logging in requires copying a request out of your browser's developer tools, and only works with Chrome or another Chrome-based browser. To learn more, see our [Setting up Mautrix LinkedIn bridging](./docs/configuring-playbook-bridge-mautrix-linkedin.md) documentation page. + +This bridge supersedes [beeper-linkedin](./docs/configuring-playbook-bridge-beeper-linkedin.md), which is now considered unmaintained (its [upstream repository](https://github.com/beeper/linkedin) has been archived). The old bridge remains installable, but you may wish to switch. Both bridges claim the same appservice namespaces, so the playbook refuses to install mautrix-linkedin while beeper-linkedin is still enabled. + +## Support for bridging to LINE via beeper-line + +Thanks to [Co van Leeuwen](https://github.com/c00), the playbook can now bridge [LINE](https://line.me/) via [beeper-line](https://github.com/beeper/line), a bridge based on the modern mautrix bridge framework. It supports LINE accounts with Letter Sealing enabled or disabled and bridges messages, media, reactions, replies, receipts, and other common chat features. + +The bridge identifies itself as a LINE Chrome Extension client, so it cannot be used at the same time as the real LINE Chrome Extension. See [Setting up Beeper LINE bridging](docs/configuring-playbook-bridge-beeper-line.md) to get started. + + +# 2026-07-19 + +## Tuwunel now exposes its administration and /_tuwunel API paths + +The [Tuwunel](docs/configuring-playbook-tuwunel.md) role previously routed only the `/_matrix` path through the reverse proxy. It now also exposes the two other API paths that Tuwunel serves. + +The Synapse-compatible administration API (`/_synapse/admin`) powers administration dashboards and moderation bots. As with Synapse and Dendrite, the playbook now exposes it automatically when such a tool is installed: publicly for [Ketesa](docs/configuring-playbook-ketesa.md) or [Element Admin](docs/configuring-playbook-element-admin.md), and on the internal entrypoint for [Draupnir](docs/configuring-playbook-bot-draupnir.md). To expose it yourself, set `matrix_tuwunel_container_labels_public_client_synapse_admin_api_enabled: true` (or the `internal_` variant). + +Tuwunel also serves first-party routes under `/_tuwunel`, including its native OpenID Connect provider endpoints, which the reverse proxy must route for OIDC login to work. This path is now routed on the public entrypoint by default. To keep it off the public entrypoint, set `matrix_tuwunel_container_labels_public_tuwunel_api_enabled: false`. + + +# 2026-07-18 + +## LiveKit Server port configuration must be unambiguous now + +This only affects you if you have configured a LiveKit Server RTC port range (`livekit_server_config_rtc_port_range_start` and `livekit_server_config_rtc_port_range_end`). + +LiveKit only uses one of the two port configuration mechanisms: when a port range is defined, the multiplexed UDP port (`livekit_server_config_rtc_udp_port`) is ignored entirely. Previously, the role would silently render its default UDP port (7882) into the configuration alongside your port range, misleadingly suggesting that both are in effect. + +The role now asks you to make the choice explicit: if you define a port range, unset the UDP port by adding `livekit_server_config_rtc_udp_port: ''` to your `vars.yml` file. A validation error will guide you, if your configuration is affected. + + +# 2026-07-17 + +## prometheus-nginxlog-exporter metric names have changed + +If you have enabled [metrics for nginx logs](docs/configuring-playbook-prometheus-grafana.md) (`prometheus_nginxlog_exporter_enabled: true`), note that the exporter's metric names have changed. + +The exporter's configuration used to ship a leftover `myprefix` placeholder as the metric name prefix, producing metrics like `myprefix_http_response_count_total`. The bundled Grafana dashboard queries unprefixed metric names (`http_response_count_total`), so it could never show any data (reported in [#3380](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3380)). + +Metric names are now unprefixed, matching the bundled dashboard, which should start working. Each metric carries a `namespace` label, whose value is now `nginx` (previously `matrix`); it is configurable via `prometheus_nginxlog_exporter_config_namespace_name`. If you have built custom dashboards or alerts on top of the old `myprefix_*` metric names, adjust them accordingly, or restore the old behavior by setting `prometheus_nginxlog_exporter_config_namespace_metrics_prefix: myprefix` in your `vars.yml` file. + + +# 2026-07-16 + +## (Backward Compatibility Break) Bridge variables have been renamed + +All bridge roles (`roles/custom/matrix-bridge-*`) now use a uniform variable naming scheme, where the variable prefix matches the role directory name. This adopts the naming policy proposed in [#4705](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/4705) and requested in [#5096](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/5096). + +Previously, bridge variable prefixes were all over the place (`matrix_mautrix_telegram_*`, `matrix_heisenbridge_*`, `matrix_steam_bridge_*`, etc.). Now, they all follow the same pattern that bot roles (`matrix_bot__*`) have been using for years: the `matrix-bridge-mautrix-telegram` role uses `matrix_bridge_mautrix_telegram_*` variables, the `matrix-bridge-steam` role uses `matrix_bridge_steam_*` variables, and so on. + +Only Ansible variables were renamed. Systemd service names, container names, `/matrix/*` directories, database names and usernames, and appservice registration contents (tokens, bot usernames) all remain the same. No data migration is necessary and bridges keep working as before, once you rename the variables in your `vars.yml` configuration file. + +The playbook will let you know if your configuration still uses old-style variable names. + +Here is the full rename map: + +| Old variable prefix | New variable prefix | +|---------------------|---------------------| +| `matrix_appservice_discord_` | `matrix_bridge_appservice_discord_` | +| `matrix_appservice_irc_` | `matrix_bridge_appservice_irc_` | +| `matrix_beeper_linkedin_` | `matrix_bridge_beeper_linkedin_` | +| `matrix_heisenbridge_` | `matrix_bridge_heisenbridge_` | +| `matrix_hookshot_` | `matrix_bridge_hookshot_` | +| `matrix_mautrix_androidsms_` | `matrix_bridge_mautrix_wsproxy_androidsms_` | +| `matrix_mautrix_bluesky_` | `matrix_bridge_mautrix_bluesky_` | +| `matrix_mautrix_discord_` | `matrix_bridge_mautrix_discord_` | +| `matrix_mautrix_gmessages_` | `matrix_bridge_mautrix_gmessages_` | +| `matrix_mautrix_googlechat_` | `matrix_bridge_mautrix_googlechat_` | +| `matrix_mautrix_gvoice_` | `matrix_bridge_mautrix_gvoice_` | +| `matrix_mautrix_imessage_` | `matrix_bridge_mautrix_wsproxy_imessage_` | +| `matrix_mautrix_meta_instagram_` | `matrix_bridge_mautrix_meta_instagram_` | +| `matrix_mautrix_meta_messenger_` | `matrix_bridge_mautrix_meta_messenger_` | +| `matrix_mautrix_signal_` | `matrix_bridge_mautrix_signal_` | +| `matrix_mautrix_slack_` | `matrix_bridge_mautrix_slack_` | +| `matrix_mautrix_telegram_` | `matrix_bridge_mautrix_telegram_` | +| `matrix_mautrix_twitter_` | `matrix_bridge_mautrix_twitter_` | +| `matrix_mautrix_whatsapp_` | `matrix_bridge_mautrix_whatsapp_` | +| `matrix_mautrix_wsproxy_` | `matrix_bridge_mautrix_wsproxy_` | +| `matrix_meshtastic_relay_` | `matrix_bridge_meshtastic_relay_` | +| `matrix_mx_puppet_groupme_` | `matrix_bridge_mx_puppet_groupme_` | +| `matrix_mx_puppet_steam_` | `matrix_bridge_mx_puppet_steam_` | +| `matrix_postmoogle_` | `matrix_bridge_postmoogle_` | +| `matrix_rustpush_bridge_` | `matrix_bridge_rustpush_` | +| `matrix_sms_bridge_` | `matrix_bridge_sms_` | +| `matrix_steam_bridge_` | `matrix_bridge_steam_` | +| `matrix_wechat_` | `matrix_bridge_wechat_` | + +A few special cases beyond the prefix map: + +- `matrix_mautrix_signal_wsproxy_syncproxy_connection_string` (a variable of the mautrix-wsproxy role, despite its name) is now `matrix_bridge_mautrix_wsproxy_syncproxy_connection_string` +- `matrix_playbook_migration_matrix_postmoogle_migration_validation_enabled` is now `matrix_playbook_migration_matrix_bridge_postmoogle_migration_validation_enabled` + +You can update your `vars.yml` file automatically with this `sed` command (on macOS, use `sed -i ''` instead of `sed -i`): + +```sh +sed -i \ + -e 's/matrix_appservice_discord_/matrix_bridge_appservice_discord_/g' \ + -e 's/matrix_appservice_irc_/matrix_bridge_appservice_irc_/g' \ + -e 's/matrix_beeper_linkedin_/matrix_bridge_beeper_linkedin_/g' \ + -e 's/matrix_heisenbridge_/matrix_bridge_heisenbridge_/g' \ + -e 's/matrix_hookshot_/matrix_bridge_hookshot_/g' \ + -e 's/matrix_mautrix_androidsms_/matrix_bridge_mautrix_wsproxy_androidsms_/g' \ + -e 's/matrix_mautrix_bluesky_/matrix_bridge_mautrix_bluesky_/g' \ + -e 's/matrix_mautrix_discord_/matrix_bridge_mautrix_discord_/g' \ + -e 's/matrix_mautrix_gmessages_/matrix_bridge_mautrix_gmessages_/g' \ + -e 's/matrix_mautrix_googlechat_/matrix_bridge_mautrix_googlechat_/g' \ + -e 's/matrix_mautrix_gvoice_/matrix_bridge_mautrix_gvoice_/g' \ + -e 's/matrix_mautrix_imessage_/matrix_bridge_mautrix_wsproxy_imessage_/g' \ + -e 's/matrix_mautrix_meta_instagram_/matrix_bridge_mautrix_meta_instagram_/g' \ + -e 's/matrix_mautrix_meta_messenger_/matrix_bridge_mautrix_meta_messenger_/g' \ + -e 's/matrix_mautrix_signal_wsproxy_syncproxy_connection_string/matrix_bridge_mautrix_wsproxy_syncproxy_connection_string/g' \ + -e 's/matrix_mautrix_signal_/matrix_bridge_mautrix_signal_/g' \ + -e 's/matrix_mautrix_slack_/matrix_bridge_mautrix_slack_/g' \ + -e 's/matrix_mautrix_telegram_/matrix_bridge_mautrix_telegram_/g' \ + -e 's/matrix_mautrix_twitter_/matrix_bridge_mautrix_twitter_/g' \ + -e 's/matrix_mautrix_whatsapp_/matrix_bridge_mautrix_whatsapp_/g' \ + -e 's/matrix_mautrix_wsproxy_/matrix_bridge_mautrix_wsproxy_/g' \ + -e 's/matrix_meshtastic_relay_/matrix_bridge_meshtastic_relay_/g' \ + -e 's/matrix_mx_puppet_groupme_/matrix_bridge_mx_puppet_groupme_/g' \ + -e 's/matrix_mx_puppet_steam_/matrix_bridge_mx_puppet_steam_/g' \ + -e 's/matrix_postmoogle_/matrix_bridge_postmoogle_/g' \ + -e 's/matrix_rustpush_bridge_/matrix_bridge_rustpush_/g' \ + -e 's/matrix_sms_bridge_/matrix_bridge_sms_/g' \ + -e 's/matrix_steam_bridge_/matrix_bridge_steam_/g' \ + -e 's/matrix_wechat_/matrix_bridge_wechat_/g' \ + -e 's/matrix_playbook_migration_matrix_postmoogle_migration_validation_enabled/matrix_playbook_migration_matrix_bridge_postmoogle_migration_validation_enabled/g' \ + vars.yml +``` + +The `sed` command only replaces prefixes followed by an underscore, so values that intentionally match old prefixes (like the default database names, e.g. `matrix_mautrix_telegram`) are not affected. + +**Note**: if you have defined your own custom variables whose names embed an old prefix (e.g. `vault_matrix_postmoogle_password` referencing a secret in an Ansible Vault file), the `sed` command renames such references too. Either rename your custom variables to match (including their definitions in encrypted vault files, which `sed` cannot reach), or revert those spots manually. + +# 2026-07-15 + +## Google Voice bridging + +The playbook can now bridge [Google Voice](https://voice.google.com/) via the [mautrix-gvoice](https://github.com/mautrix/gvoice) bridge. Text and media flow both ways, and portal rooms build themselves for your recent conversations. + +Login is by cookie, not a paired phone: you copy the cookies from a browser signed in to voice.google.com and hand them to the bot. Google expires them on its own schedule, so expect to log in again every so often. See [Setting up Mautrix Google Voice bridging](./docs/configuring-playbook-bridge-mautrix-gvoice.md) to get started. + +## matrix-appservice-kakaotalk has been removed from the playbook + +The [matrix-appservice-kakaotalk](./docs/configuring-playbook-bridge-appservice-kakaotalk.md) bridge has been removed from the playbook. This component could only be installed by self-building its source code, and its upstream repository has become unreachable, which makes installation impossible. The bridge was also based on the unmaintained node-kakao library, and there have been reports that using it may get KakaoTalk accounts banned. + +The playbook will let you know if you're using any `matrix_appservice_kakaotalk_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-bridge-appservice-kakaotalk.md#uninstalling-the-component-manually). + +## Dedicated CAPTCHA variables for Matrix Authentication Service + +[Matrix Authentication Service](./docs/configuring-playbook-matrix-authentication-service.md) can now be protected with CAPTCHA (ReCaptcha v2, Cloudflare Turnstile, or hCaptcha) via dedicated variables, instead of going through `matrix_authentication_service_configuration_extension_yaml`. See the [captcha documentation](./docs/configuring-captcha.md#matrix-authentication-service) for details. + +# 2026-07-14 + +## The playbook no longer ships a custom welcome page for Element Web + +Element Web [redesigned its welcome page](https://github.com/element-hq/element-web/pull/33211) (the screen shown at `/#/welcome` before logging in) into a built-in component and no longer loads a custom `welcome.html` file by default. Since the playbook upgraded to an Element Web version containing that change (spring 2026), the custom welcome page the playbook installed (and the variables customizing it) had silently stopped having any effect. + +The playbook now embraces the new upstream behavior and no longer ships its own `welcome.html`. The following variables have been removed and the playbook will let you know if you're still using them: `matrix_client_element_welcome_headline`, `matrix_client_element_welcome_text`, `matrix_client_element_welcome_logo_link` and `matrix_client_element_page_template_welcome_path`. + +Most welcome page customizations keep working, because they go through Element Web's branding configuration, which the new welcome page still honors: + +- a custom logo, via `matrix_client_element_welcome_logo` (or `matrix_client_element_branding_auth_header_logo_url`) +- a custom background, via `matrix_client_element_branding_welcome_background_url` + +If you need a fully custom welcome page, you can self-host an HTML page and point Element Web at it, like this: + +```yaml +matrix_client_element_configuration_extension_json: | + { + "embedded_pages": { + "welcome_url": "https://example.com/my-welcome.html" + } + } +``` + +## BorgBackup now includes Synapse's local thumbnails + +For Synapse servers, the built-in [BorgBackup](./docs/configuring-playbook-backup-borg.md) integration no longer excludes the media store's `local_thumbnails` directory from backups. + +Synapse only generates thumbnails of local media at upload time (unless `dynamic_thumbnails` is enabled, which the playbook does not do), and there is no tooling to regenerate them. Restoring a backup made with the previous exclusion list therefore left all previously uploaded local images without thumbnails. The [official Synapse backup guide](https://element-hq.github.io/synapse/latest/usage/administration/backups.html) recommends backing this directory up, and the playbook now follows that recommendation. + +Expect your backups to grow somewhat, depending on how much image media your local users have uploaded. If you prefer the old behavior, you can redefine `backup_borg_location_exclude_patterns` in your `vars.yml`. + +# 2026-07-12 + +## matrix-registration-bot has been removed from the playbook + +The [matrix-registration-bot](./docs/configuring-playbook-bot-matrix-registration-bot.md) service has been removed from the playbook, as it has been unmaintained. + +The playbook will let you know if you're using any `matrix_bot_matrix_registration_bot_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-bot-matrix-registration-bot.md#uninstalling-the-component-manually). + +## Continuwuity v26 no longer supports LDAP + +The playbook now installs [Continuwuity](./docs/configuring-playbook-continuwuity.md) v26, a major upgrade from the v0.5.x series which **removes LDAP authentication support** (see the [v26.6.0 release notes](https://forgejo.ellis.link/continuwuation/continuwuity/releases/tag/v26.6.0)). + +The playbook never exposed dedicated variables for Continuwuity's LDAP support, so most people are unaffected. However, if you had enabled LDAP via `matrix_continuwuity_environment_variables_extension` or a custom configuration template, you'll need to migrate to another authentication method, such as the newly introduced [OpenID Connect support](https://continuwuity.org/guides/oidc). + +# 2026-06-29 + +## Support for running on Synology DSM + +Thanks to [cksit](https://github.com/cksit), the playbook can now run on [Synology DSM](https://www.synology.com/dsm) 7 and later. + +Synology hosts are detected automatically (via `/etc/synoinfo.conf`), so other systems are unaffected. On DSM, the playbook uses the platform's native user management (`synouser`/`synogroup`), works around a Docker SDK incompatibility, and installs a small boot-fix service that handles a few DSM-specific boot quirks. + +To get started, see the new [Configuring Synology DSM](./docs/configuring-playbook-synology.md) documentation page. + +## Mautrix bridges now expose their API (for Mautrix Manager and similar tools) + +The playbook now exposes the HTTP API of each [mautrix](https://github.com/mautrix) bridge, so tools like [Mautrix Manager](https://github.com/mautrix/manager) can help you log into them. This is especially useful for [mautrix-gmessages](./docs/configuring-playbook-bridge-mautrix-gmessages.md): Google has removed its QR-code login, leaving a [manual cookie-extraction flow](https://docs.mau.fi/bridges/go/gmessages/authentication.html) that tools like Mautrix Manager can streamline. + +The API is exposed at `https://matrix.example.com/bridges/SERVICENAME` (for example, `https://matrix.example.com/bridges/gmessages`) and is advertised via a new `/.well-known/matrix/mautrix` file, so compatible tools can discover your bridges automatically. Such tools authenticate with your own Matrix access token, so no bridge secret needs to be shared with them. + +This affects all mautrix bridges based on the new bridge framework (bluesky, gmessages, meta-instagram, meta-messenger, signal, slack, telegram, twitter and whatsapp) and is enabled by default. + +To learn more (including how to turn it off), see the [Expose the bridge's API](./docs/configuring-playbook-bridge-mautrix-bridges.md#expose-the-bridges-api-for-mautrix-manager-and-similar-tools) section on our common mautrix bridges documentation page. + +# 2026-06-28 + +## baibot now supports Venice, our recommended provider + +[baibot](./docs/configuring-playbook-bot-baibot.md) now ships a preset for the [Venice](./docs/configuring-playbook-bot-baibot.md#venice) provider, and it's the one we recommend. It's the most capable provider baibot supports (text generation with vision, file inputs and web search, speech-to-text, text-to-speech, and image generation and editing), and the only one that runs inference with no logging and no training on your data. + +Enabling it takes a preset toggle and an API key: + +```yaml +matrix_bot_baibot_config_agents_static_definitions_venice_enabled: true + +matrix_bot_baibot_config_agents_static_definitions_venice_config_api_key: "YOUR_API_KEY_HERE" +``` + +[OpenAI](https://openai.com/) and baibot's other providers remain fully supported. To get started, see the [Setting up baibot](./docs/configuring-playbook-bot-baibot.md#venice) documentation page. + +# 2026-06-24 + +## Support for bridging to iMessage via RustPush + +Thanks to [jasonlaguidice](https://github.com/jasonlaguidice), the playbook now supports bridging to [iMessage](https://support.apple.com/messages) via a new [RustPush](https://github.com/OpenBubbles/rustpush)-based bridge ([jasonlaguidice/imessage](https://github.com/jasonlaguidice/imessage)). + +Unlike the existing [mautrix-wsproxy](./docs/configuring-playbook-bridge-mautrix-wsproxy.md) iMessage bridge, this one talks directly to Apple's push notification service, so it needs neither a running Mac nor a wsproxy on the homeserver. Each user supplies a hardware key extracted from a Mac through the bridge bot's login flow. + +To learn more, see our [Setting up RustPush (iMessage) bridging](./docs/configuring-playbook-bridge-rustpush.md) documentation page. + +# 2026-05-24 + +## matrix-ldap-registration-proxy has been removed from the playbook + +The [matrix-ldap-registration-proxy](./docs/configuring-playbook-matrix-ldap-registration-proxy.md) service has been removed from the playbook, as the source code and the container image have become unavailable. + +The playbook will let you know if you're using any `matrix_ldap_registration_proxy_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-matrix-ldap-registration-proxy.md#uninstalling-the-component-manually). + +# 2026-05-23 + +## Go-NEB has been removed from the playbook + +[Go-NEB](./docs/configuring-playbook-bot-go-neb.md) has been removed from the playbook, as it has been discontinued since June 2023. + +The playbook will let you know if you're using any `matrix_bot_go_neb_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the bot manually](./docs/configuring-playbook-bot-go-neb.md#uninstalling-go-neb-manually). + +# 2026-05-19 + +## matrix-registration has been removed from the playbook + +The [matrix-registration](./docs/configuring-playbook-matrix-registration.md) service has been removed from the playbook, as it has been unmaintained (archived) since November, 2025. + +The playbook will let you know if you're using any `matrix_registration_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-matrix-registration.md#uninstalling-the-component-manually). + +# 2026-05-18 + +## LiveKit Server has been upgraded to v1.12.0 + +The playbook now ships [LiveKit Server](./docs/configuring-playbook-livekit-server.md) v1.12.0. See the [upstream release notes](https://github.com/livekit/livekit/releases/tag/v1.12.0) for details. + +This release tightens TURN security: + +- **TURN credentials now carry a TTL** (default: 300 seconds), exposed via `livekit_server_config_turn_ttl_seconds`. +- **TURN no longer relays traffic to restricted peer CIDRs** (loopback, link-local, multicast, private, unspecified) by default. If your setup legitimately requires it, list the ranges in `livekit_server_config_turn_allow_restricted_peer_cidrs`. + + For example, to allow TURN to reach the common [RFC1918](https://www.rfc-editor.org/rfc/rfc1918) private ranges, add to your `vars.yml`: + ```yaml + livekit_server_config_turn_allow_restricted_peer_cidrs: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + ``` + + Adjust the ranges to match your network. To deny specific CIDRs (taking precedence over the allow list above), use `livekit_server_config_turn_deny_peer_cidrs` in the same shape. + + +# 2026-05-07 + +## Tuwunel support + +Thanks to [Jason Volk](https://github.com/jevolk), the playbook now supports the [Tuwunel](./docs/configuring-playbook-tuwunel.md) homeserver as an optional alternative to Synapse. + +Tuwunel is a fork of [conduwuit](./docs/configuring-playbook-conduwuit.md) written in Rust. The former conduwuit maintainer [endorses Tuwunel as conduwuit's successor](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/5200#issuecomment-4396211185). Like [Continuwuity](./docs/configuring-playbook-continuwuity.md), Tuwunel continues development on top of conduwuit's database format. + +Existing installations do **not** need to be updated. **Synapse is still the default homeserver implementation** installed by the playbook. + +People that used to run conduwuit may wish to [migrate from conduwuit to Tuwunel](./docs/configuring-playbook-tuwunel.md#migrating-from-conduwuit) via the new `tuwunel-migrate-from-conduwuit` tag, which performs an in-place binary-swap migration that reads the conduwuit database directly. + +**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse/Conduit/Dendrite/Continuwuity to Tuwunel) without data loss. The exception is conduwuit, due to the shared database format. + + +# 2026-04-24 + +## Support for bridging to Meshtastic via meshtastic-matrix-relay + +Thanks to [luschmar](https://github.com/luschmar), the playbook now supports bridging to [Meshtastic](https://meshtastic.org/) mesh networks via [meshtastic-matrix-relay](https://github.com/jeremiah-k/meshtastic-matrix-relay) (mmrelay). + +To learn more, see our [Setting up a Matrix <-> Meshtastic bridge](./docs/configuring-playbook-bridge-meshtastic-relay.md) documentation page. + +## (BC Break) mautrix-telegram has been rewritten in Go (bridgev2) + +The [mautrix-telegram](./docs/configuring-playbook-bridge-mautrix-telegram.md) bridge has been [rewritten in Go](https://mau.fi/blog/2026-04-mautrix-release/) on top of the [bridgev2](https://docs.mau.fi/bridges/go/) architecture. See the [upstream v26.04 release notes](https://github.com/mautrix/telegram/releases/tag/v0.2604.0) for what changed in the bridge itself (shared-portal behavior, management-room state, new features, etc.). + +**Most users won't have to do anything.** If you use the playbook's integrated Postgres (the default) and haven't customized telegram-bridge variables beyond `matrix_mautrix_telegram_api_id` and `matrix_mautrix_telegram_api_hash`, just re-run the playbook; the bridge will migrate itself on first start. Taking a backup beforehand is still a good idea. + +⚠️ **SQLite users: do not upgrade yet.** Upstream v0.2604.0 has a [known bug in the legacy SQLite migration](https://github.com/mautrix/telegram/releases/tag/v0.2604.0) that can corrupt your data. The playbook detects this case and will refuse to proceed. Either switch to Postgres first (set `matrix_mautrix_telegram_database_engine: postgres`; the playbook handles the pgloader migration), or wait for the next upstream release. + +Playbook-specific things to know. The playbook will fail loudly if you're affected: + +- Many `matrix_mautrix_telegram_*` variables have been **removed** (web-login endpoint, lottieconverter, username/alias/displayname templates, filter-mode, bot-token relaybot, Shared-Secret-Auth map). The deprecation check will tell you exactly what to rename or drop when you run the playbook. +- **Old-style relaybot users** (`matrix_mautrix_telegram_bot_token`): switch to the common [mautrix bridge relay mode](./docs/configuring-playbook-bridge-mautrix-bridges.md#enable-relay-mode-optional) via `matrix_mautrix_telegram_bridge_relay_enabled: true`. +- **Shared-Secret-Auth double-puppeting users**: switch to [Appservice Double Puppet](./docs/configuring-playbook-appservice-double-puppet.md); the playbook wires it up automatically. +- **Custom `matrix_mautrix_telegram_bridge_permissions`**: map `relaybot` to `relay`, `puppeting` to `user`, `full` to `user`. Validated at playbook time. + +# 2026-04-03 + +## (BC Break) Synapse Admin (fork by etke.cc) is now Ketesa + +Synapse Admin has been rebranded to **[Ketesa](https://github.com/etkecc/ketesa)** — a landmark release that introduces a new identity, a full UI redesign, mobile-first layout, and deep Matrix Authentication Service (MAS) integration. For the full story behind the rename and a tour of what's new, see the [Ketesa v1.0.0 announcement](https://etke.cc/blog/introducing-ketesa/). + +Ketesa is a zero-configuration drop-in replacement for Synapse Admin: no server-side changes required, just update the role variables. + +The `matrix-synapse-admin` role has been **renamed** to `matrix-ketesa`. All `matrix_synapse_admin_*` variables must be **renamed** to `matrix_ketesa_*` in your `vars.yml`. + +Additionally, the **Docker image** changed from `ghcr.io/etkecc/synapse-admin` to `ghcr.io/etkecc/ketesa`. The default path prefix remains `/synapse-admin` for backward compatibility — updating to `/ketesa` is recommended but not required. + +The playbook will automatically detect leftover `matrix_synapse_admin_*` variables and fail with a helpful message listing what needs to be renamed. + +The playbook handles reverse-proxy routing for subpath deployments (e.g. `/ketesa`), including MAS-enabled setups — though OIDC auth flows on real servers still have some rough edges. Feedback is appreciated in [#ketesa:etke.cc](https://matrix.to/#/#ketesa:etke.cc). + +See the [Ketesa documentation](docs/configuring-playbook-ketesa.md) for details. + +# 2026-04-02 + +## (BC Break) Draupnir for all Self Service Provisioning is now disabled by default + +💡 If you don't use [Draupnir for all](./docs/configuring-playbook-appservice-draupnir-for-all.md), then this breaking change does not concern you.. + +[Draupnir for all](./docs/configuring-playbook-appservice-draupnir-for-all.md) now ships with `allowSelfServiceProvisioning: false` as default upstream and in this playbook. + +This means users can no longer provision Draupnir instances by inviting the appservice bot unless you explicitly opt in. + +Manual provisioning by administrators is now the recommended approach. You do not want to enable Self Service Provisioning unless you have additional custom safeguards like those used by asgard.chat in place. + +If you want to enable Self Service Provisioning, add the following to your `vars.yml`: + +```yaml +matrix_appservice_draupnir_for_all_configuration_extension_yaml: | + allowSelfServiceProvisioning: true +``` + # 2026-03-23 ## Migration validation system introduced diff --git a/Makefile b/Makefile index 9ac77bb07..137e17062 100644 --- a/Makefile +++ b/Makefile @@ -2,11 +2,14 @@ # # SPDX-License-Identifier: AGPL-3.0-or-later -.PHONY: roles lint +.PHONY: roles lint add-inventory-host help: ## Show this help. @grep -F -h "##" $(MAKEFILE_LIST) | grep -v grep | sed -e 's/\\$$//' | sed -e 's/##//' +add-inventory-host: ## Adds a new host to the inventory, creating the inventory files if necessary (e.g. `make add-inventory-host domain=example.com ip=1.2.3.4`) + @./bin/add-inventory-host.sh "$(domain)" "$(ip)" + roles: ## Pull roles rm -rf roles/galaxy ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force diff --git a/README.md b/README.md index c859b2026..2f8cc1a20 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## 🎯 Purpose -This [Ansible](https://www.ansible.com/) playbook is meant to help you run your own [Matrix](http://matrix.org/) homeserver, along with the [various services](#supported-services) related to that. +This [Ansible](https://www.ansible.com/) playbook is meant to help you run your own [Matrix](http://matrix.org/) homeserver, along with the [various services](#-supported-services) related to that. That is, it lets you join the Matrix network using your own user ID like `@alice:example.com`, all hosted on your own server (see [prerequisites](docs/prerequisites.md)). @@ -53,6 +53,7 @@ The homeserver is the backbone of your Matrix system. Choose one from the follow | [Synapse](https://github.com/element-hq/synapse) | ✅ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network | [Link](docs/configuring-playbook-synapse.md) | | [Conduit](https://conduit.rs) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Conduit is a lightweight open-source server implementation of the Matrix Specification with a focus on easy setup and low system requirements | [Link](docs/configuring-playbook-conduit.md) | | [continuwuity](https://continuwuity.org) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. | [Link](docs/configuring-playbook-continuwuity.md) | +| [Tuwunel](https://matrix-construct.github.io/tuwunel/) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Tuwunel is the official successor to conduwuit. | [Link](docs/configuring-playbook-tuwunel.md) | | [Dendrite](https://github.com/element-hq/dendrite) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Dendrite is a second-generation Matrix homeserver written in Go, an alternative to Synapse. | [Link](docs/configuring-playbook-dendrite.md) | ### Clients @@ -64,9 +65,10 @@ Web clients for Matrix that you can host on your own domains. | [Element Web](https://github.com/element-hq/element-web) | ✅ | Default Matrix web client, configured to connect to your own Synapse server | [Link](docs/configuring-playbook-client-element-web.md) | | [Hydrogen](https://github.com/element-hq/hydrogen-web) | ❌ | Lightweight Matrix client with legacy and mobile browser support | [Link](docs/configuring-playbook-client-hydrogen.md) | | [Cinny](https://github.com/ajbura/cinny) | ❌ | Simple, elegant and secure web client | [Link](docs/configuring-playbook-client-cinny.md) | -| [Sable](https://github.com/7w1/sable) | ❌ | Simple, elegant and secure web client | [Link](docs/configuring-playbook-client-sable.md) | +| [Sable](https://github.com/SableClient/Sable) | ❌ | Simple, elegant and secure web client | [Link](docs/configuring-playbook-client-sable.md) | | [SchildiChat Web](https://schildi.chat/) | ❌ | Based on Element Web, with a more traditional instant messaging experience | [Link](docs/configuring-playbook-client-schildichat-web.md) | | [FluffyChat Web](https://fluffychat.im/) | ❌ | The cutest messenger in Matrix | [Link](docs/configuring-playbook-client-fluffychat-web.md) | +| [Commet](https://github.com/commetchat/commet) | ❌ | Matrix web client | [Link](docs/configuring-playbook-client-commet.md) | ### Server Components @@ -91,8 +93,6 @@ Extend and modify how users are authenticated on your homeserver. | [matrix-synapse-rest-auth](https://github.com/ma1uta/matrix-synapse-rest-password-provider) (advanced) | ❌ | REST authentication password provider module | [Link](docs/configuring-playbook-rest-auth.md) | |[matrix-synapse-shared-secret-auth](https://github.com/devture/matrix-synapse-shared-secret-auth) (advanced) | ❌ | Password provider module | [Link](docs/configuring-playbook-shared-secret-auth.md) | | [matrix-synapse-ldap3](https://github.com/matrix-org/matrix-synapse-ldap3) (advanced) | ❌ | LDAP Auth password provider module | [Link](docs/configuring-playbook-ldap-auth.md) | -| [matrix-ldap-registration-proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy) (advanced) | ❌ | Proxy that handles Matrix registration requests and forwards them to LDAP | [Link](docs/configuring-playbook-matrix-ldap-registration-proxy.md) | -| [matrix-registration](https://github.com/ZerataX/matrix-registration) | ❌ | Simple python application to have a token based Matrix registration | [Link](docs/configuring-playbook-matrix-registration.md) | | [Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service) | ❌ | Service to verify details of a user based on an Open ID token | [Link](docs/configuring-playbook-user-verification-service.md) | | [synapse-simple-antispam](https://github.com/t2bot/synapse-simple-antispam) (advanced) | ❌ | Spam checker module | [Link](docs/configuring-playbook-synapse-simple-antispam.md) | @@ -116,22 +116,25 @@ Bridges can be used to connect your Matrix installation with third-party communi | [mautrix-slack](https://github.com/mautrix/slack) | ❌ | Bridge to [Slack](https://slack.com/) | [Link](docs/configuring-playbook-bridge-mautrix-slack.md) | | [mautrix-telegram](https://github.com/mautrix/telegram) | ❌ | Bridge to [Telegram](https://telegram.org/) | [Link](docs/configuring-playbook-bridge-mautrix-telegram.md) | | [mautrix-gmessages](https://github.com/mautrix/gmessages) | ❌ | Bridge to [Google Messages](https://messages.google.com/) | [Link](docs/configuring-playbook-bridge-mautrix-gmessages.md) | +| [mautrix-gvoice](https://github.com/mautrix/gvoice) | ❌ | Bridge to [Google Voice](https://voice.google.com/) | [Link](docs/configuring-playbook-bridge-mautrix-gvoice.md) | +| [mautrix-linkedin](https://github.com/mautrix/linkedin) | ❌ | Bridge to [LinkedIn](https://www.linkedin.com/) | [Link](docs/configuring-playbook-bridge-mautrix-linkedin.md) | | [mautrix-whatsapp](https://github.com/mautrix/whatsapp) | ❌ | Bridge to [WhatsApp](https://www.whatsapp.com/) | [Link](docs/configuring-playbook-bridge-mautrix-whatsapp.md) | | [mautrix-wsproxy](https://github.com/mautrix/wsproxy) | ❌ | Bridge to Android SMS or Apple iMessage | [Link](docs/configuring-playbook-bridge-mautrix-wsproxy.md) | +| [matrix-rustpush-bridge](https://github.com/jasonlaguidice/imessage) | ❌ | Bridge to [iMessage](https://support.apple.com/messages) via Apple Push Notification service | [Link](docs/configuring-playbook-bridge-rustpush.md) | | [mautrix-bluesky](https://github.com/mautrix/bluesky) | ❌ | Bridge to [Bluesky](https://bsky.social/) | [Link](docs/configuring-playbook-bridge-mautrix-bluesky.md) | | [mautrix-twitter](https://github.com/mautrix/twitter) | ❌ | Bridge to [Twitter](https://twitter.com/) | [Link](docs/configuring-playbook-bridge-mautrix-twitter.md) | | [mautrix-googlechat](https://github.com/mautrix/googlechat) | ❌ | Bridge to [Google Chat](https://en.wikipedia.org/wiki/Google_Chat) | [Link](docs/configuring-playbook-bridge-mautrix-googlechat.md) | -| [mautrix-meta](https://github.com/mautrix/instagram) | ❌ | Bridge to [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/) | Link for [Messenger](docs/configuring-playbook-bridge-mautrix-meta-messenger.md) / [Instagram](docs/configuring-playbook-bridge-mautrix-meta-instagram.md) | +| [mautrix-meta](https://github.com/mautrix/meta) | ❌ | Bridge to [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/) | Link for [Messenger](docs/configuring-playbook-bridge-mautrix-meta-messenger.md) / [Instagram](docs/configuring-playbook-bridge-mautrix-meta-instagram.md) | | [mautrix-signal](https://github.com/mautrix/signal) | ❌ | Bridge to [Signal](https://www.signal.org/) | [Link](docs/configuring-playbook-bridge-mautrix-signal.md) | -| [beeper-linkedin](https://github.com/beeper/linkedin) | ❌ | Bridge to [LinkedIn](https://www.linkedin.com/) | [Link](docs/configuring-playbook-bridge-beeper-linkedin.md) | +| [beeper-line](https://github.com/beeper/line) | ❌ | Bridge to [LINE](https://line.me/) | [Link](docs/configuring-playbook-bridge-beeper-line.md) | | [matrix-appservice-irc](https://github.com/matrix-org/matrix-appservice-irc) | ❌ | Bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat) | [Link](docs/configuring-playbook-bridge-appservice-irc.md) | -| [matrix-appservice-kakaotalk](https://src.miscworks.net/fair/matrix-appservice-kakaotalk) | ❌ | Bridge to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG) | [Link](docs/configuring-playbook-bridge-appservice-kakaotalk.md) | | [matrix-appservice-discord](https://github.com/matrix-org/matrix-appservice-discord) | ❌ | Bridge to [Discord](https://discordapp.com/) | [Link](docs/configuring-playbook-bridge-appservice-discord.md) | | [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) | ❌ | Bridge for generic webhooks and multiple project management services, such as GitHub, GitLab, Figma, and Jira in particular | [Link](docs/configuring-playbook-bridge-hookshot.md) | | [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) | ❌ | Bridge to SMS | [Link](docs/configuring-playbook-bridge-matrix-bridge-sms.md) | | [matrix-steam-bridge](https://github.com/jasonlaguidice/matrix-steam-bridge) | ❌ | Bridge to [Steam](https://steampowered.com/) | [Link](docs/configuring-playbook-bridge-steam.md) | | [matrix-wechat](https://github.com/duo/matrix-wechat) | ❌ | Bridge to [WeChat](https://www.wechat.com/) | [Link](docs/configuring-playbook-bridge-wechat.md) | | [Heisenbridge](https://github.com/hifi/heisenbridge) | ❌ | Bouncer-style bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat) | [Link](docs/configuring-playbook-bridge-heisenbridge.md) | +| [meshtastic-matrix-relay](https://github.com/jeremiah-k/meshtastic-matrix-relay) | ❌ | Bridge to [Meshtastic](https://meshtastic.org/) mesh networks | [Link](docs/configuring-playbook-bridge-meshtastic-relay.md) | | [mx-puppet-groupme](https://gitlab.com/xangelix-pub/matrix/mx-puppet-groupme) | ❌ | Bridge to [GroupMe](https://groupme.com/) | [Link](docs/configuring-playbook-bridge-mx-puppet-groupme.md) | | [mx-puppet-steam](https://codeberg.org/icewind/mx-puppet-steam) | ❌ | Bridge to [Steam](https://steamapp.com/) | [Link](docs/configuring-playbook-bridge-mx-puppet-steam.md) | | [Postmoogle](https://github.com/etkecc/postmoogle) | ❌ | Email to Matrix bridge | [Link](docs/configuring-playbook-bridge-postmoogle.md) | @@ -144,11 +147,11 @@ Bots provide various additional functionality to your installation. | ---- | -------- | ----------- | ------------- | | [baibot](https://github.com/etkecc/baibot) | ❌ | Bot that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you | [Link](docs/configuring-playbook-bot-baibot.md) | | [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot) | ❌ | Bot for scheduling one-off & recurring reminders and alarms | [Link](docs/configuring-playbook-bot-matrix-reminder-bot.md) | -| [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot) | ❌ | Bot for invitations by creating and managing registration tokens | [Link](docs/configuring-playbook-bot-matrix-registration-bot.md) | | [maubot](https://github.com/maubot/maubot) | ❌ | Plugin-based Matrix bot system | [Link](docs/configuring-playbook-bot-maubot.md) | | [Honoroit](https://github.com/etkecc/honoroit) | ❌ | Helpdesk bot | [Link](docs/configuring-playbook-bot-honoroit.md) | | [Mjolnir](https://github.com/matrix-org/mjolnir) | ❌ | Moderation tool for Matrix | [Link](docs/configuring-playbook-bot-mjolnir.md) | | [Draupnir](https://github.com/the-draupnir-project/Draupnir) | ❌ | Moderation tool for Matrix (Fork of Mjolnir) | [Link](docs/configuring-playbook-bot-draupnir.md) (for [appservice mode](docs/configuring-playbook-appservice-draupnir-for-all.md))| +| [Meowlnir](https://github.com/maunium/meowlnir) | ❌ | Moderation tool for Matrix, running in appservice mode | [Link](docs/configuring-playbook-bot-meowlnir.md) | | [Buscarron](https://github.com/etkecc/buscarron) | ❌ | Web forms (HTTP POST) to Matrix | [Link](docs/configuring-playbook-bot-buscarron.md) | ### Administration @@ -159,7 +162,7 @@ Services that help you in administrating and monitoring your Matrix installation | ---- | -------- | ----------- | ------------- | | [matrix-alertmanager-receiver](https://github.com/metio/matrix-alertmanager-receiver) | ❌ | Prometheus' [Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/) client | [Link](docs/configuring-playbook-alertmanager-receiver.md) | | [Matrix Authentication Service](https://github.com/element-hq/matrix-authentication-service/) | ❌ | OAuth 2.0 and OpenID Provider server | [Link](docs/configuring-playbook-matrix-authentication-service.md) | -| [synapse-admin](https://github.com/etkecc/synapse-admin) | ❌ | Web UI tool for administrating users and rooms on your Matrix server | [Link](docs/configuring-playbook-synapse-admin.md) | +| [Ketesa](https://github.com/etkecc/ketesa) | ❌ | Fully-featured web UI for administrating your Matrix homeserver — users, rooms, media, sessions, and more | [Link](docs/configuring-playbook-ketesa.md) | | Metrics and Graphs | ❌ | Consists of the [Prometheus](https://prometheus.io) time-series database server, the Prometheus [node-exporter](https://prometheus.io/docs/guides/node-exporter/) host metrics exporter, and the [Grafana](https://grafana.com/) web UI, with [prometheus-nginxlog-exporter](https://github.com/martin-helmich/prometheus-nginxlog-exporter/) being available too | [Link](docs/configuring-playbook-prometheus-grafana.md) (for [prometheus-nginxlog-exporter](docs/configuring-playbook-prometheus-grafana.md#enable-metrics-and-graphs-for-nginx-logs-optional)) | | [Borg](https://borgbackup.org) | ❌ | Backups | [Link](docs/configuring-playbook-backup-borg.md) | | [rageshake](https://github.com/matrix-org/rageshake) | ❌ | Bug report server | [Link](docs/configuring-playbook-rageshake.md) | diff --git a/bin/add-inventory-host.sh b/bin/add-inventory-host.sh new file mode 100755 index 000000000..9c1bedd2d --- /dev/null +++ b/bin/add-inventory-host.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +# Adds a new host to the inventory, based on the example files in `examples/`: +# - creates `inventory/hosts` (or adds the host to it, if it already exists) +# - creates `inventory/host_vars/matrix.DOMAIN/vars.yml` with strong secrets generated automatically +# +# Existing configuration for the same host is never overwritten - the script refuses to run instead. +# +# Usage: bin/add-inventory-host.sh +# +# - is the base domain (`example.com`), not the Matrix server hostname (`matrix.example.com`) +# - is the server's external IP address or domain name + +set -euo pipefail + +base_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +if [ $# -ne 2 ]; then + echo "Usage: $0 " >&2 + echo "Example: $0 example.com 1.2.3.4" >&2 + exit 1 +fi + +domain="$1" +server_address="$2" + +if ! printf '%s' "${domain}" | grep -Eq '^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)+$'; then + echo "Error: '${domain}' does not look like a valid domain name" >&2 + exit 1 +fi + +if ! printf '%s' "${server_address}" | grep -Eq '^[A-Za-z0-9.:_-]+$'; then + echo "Error: '${server_address}' does not look like a valid server address (IP address or domain name)" >&2 + exit 1 +fi + +case "${domain}" in + matrix.*) + echo "Warning: you likely need to pass your base domain (example.com), not the Matrix server hostname (matrix.example.com)." >&2 + echo "Proceeding anyway. Your Matrix server hostname will be: matrix.${domain}" >&2 + ;; +esac + +matrix_hostname="matrix.${domain}" +hosts_file="${base_path}/inventory/hosts" +vars_dir="${base_path}/inventory/host_vars/${matrix_hostname}" +vars_file="${vars_dir}/vars.yml" +hosts_entry="${matrix_hostname} ansible_host=${server_address} ansible_ssh_user=root" + +if [ -e "${vars_dir}" ]; then + echo "Error: ${vars_dir} already exists. Refusing to overwrite it." >&2 + exit 1 +fi + +if [ -f "${hosts_file}" ]; then + if ! grep -q '^\[matrix_servers\]' "${hosts_file}"; then + echo "Error: ${hosts_file} exists, but does not contain a [matrix_servers] section." >&2 + echo "Unrecognized inventory format. Add the host to it manually:" >&2 + echo "${hosts_entry}" >&2 + exit 1 + fi + + matrix_hostname_pattern="$(printf '%s' "${matrix_hostname}" | sed 's|\.|\\.|g')" + if grep -Eq "^${matrix_hostname_pattern}([[:space:]]|$)" "${hosts_file}"; then + echo "Error: ${hosts_file} already contains an entry for ${matrix_hostname}. Refusing to modify it." >&2 + exit 1 + fi +fi + +generate_secret() { + if command -v pwgen >/dev/null 2>&1; then + pwgen -s 64 1 + elif command -v openssl >/dev/null 2>&1; then + openssl rand -base64 192 | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 64 + else + head -c 4096 /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 64 + fi +} + +generic_secret_key="$(generate_secret)" +postgres_password="$(generate_secret)" + +for secret in "${generic_secret_key}" "${postgres_password}"; do + if [ "${#secret}" -lt 64 ]; then + echo "Error: failed to generate a secret" >&2 + exit 1 + fi +done + +mkdir -p "${vars_dir}" + +sed \ + -e "s|^matrix_domain:.*|matrix_domain: ${domain}|" \ + -e "s|^matrix_homeserver_generic_secret_key:.*|matrix_homeserver_generic_secret_key: '${generic_secret_key}'|" \ + -e "s|^postgres_connection_password:.*|postgres_connection_password: '${postgres_password}'|" \ + "${base_path}/examples/vars.yml" > "${vars_file}" + +if [ -f "${hosts_file}" ]; then + # Insert the new host right after the [matrix_servers] section header. + hosts_file_tmp="$(mktemp "${hosts_file}.XXXXXX")" + awk -v entry="${hosts_entry}" '{print} $0 ~ /^\[matrix_servers\]/ && !done {print entry; done=1}' \ + "${hosts_file}" > "${hosts_file_tmp}" + mv "${hosts_file_tmp}" "${hosts_file}" +else + sed \ + -e "s|^matrix\.example\.com .*|${hosts_entry}|" \ + "${base_path}/examples/hosts" > "${hosts_file}" +fi + +echo "Added host ${matrix_hostname} to the inventory:" +echo "- ${hosts_file}" +echo "- ${vars_file}" +echo "" +echo "Secrets were generated automatically for matrix_homeserver_generic_secret_key and postgres_connection_password." +echo "Review and adjust these files before installing." diff --git a/bin/check-molecule-automerge-list.py b/bin/check-molecule-automerge-list.py new file mode 100755 index 000000000..1215cd319 --- /dev/null +++ b/bin/check-molecule-automerge-list.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +"""Keeps Molecule-backed automerge rules in step with the available scenarios. + +.github/renovate.json automerges patch bumps for every role with a scenario. A narrower list of +explicitly approved roles also automerges minor bumps. In both cases, the bump runs that role's +Molecule scenario before merging, so the reasoning only holds while the role actually has one. + +The patch list must exactly match the scenarios. The minor list must be a subset of it: omission is +an explicit policy choice, while an extra entry would merge a minor bump without the required gate. +""" + +import json +import pathlib +import sys + +REPO = pathlib.Path(__file__).resolve().parent.parent +RENOVATE = REPO / ".github" / "renovate.json" +PATCH_RULE_MARKER = "bin/check-molecule-automerge-list.py (patch rule)" +MINOR_RULE_MARKER = "bin/check-molecule-automerge-list.py (minor rule)" + + +def find_rule(config: dict, marker: str) -> dict | None: + rules = [r for r in config.get("packageRules", []) if marker in r.get("description", "")] + if len(rules) != 1: + print(f"Expected exactly one rule mentioning {marker}, found {len(rules)}.", file=sys.stderr) + return None + return rules[0] + + +def listed_roles(rule: dict, label: str) -> set[str] | None: + listed = set() + for name in rule.get("matchFileNames", []): + parts = pathlib.PurePosixPath(name).parts + if parts[:2] == ("roles", "custom") and parts[3:] == ("defaults", "main.yml"): + listed.add(parts[2]) + else: + print(f"Unexpected entry in the Molecule {label} automerge rule: {name}", file=sys.stderr) + return None + return listed + + +def main() -> int: + with_scenario = { + p.parts[-4] for p in (REPO / "roles" / "custom").glob("*/molecule/default/molecule.yml") + } + + config = json.loads(RENOVATE.read_text()) + patch_rule = find_rule(config, PATCH_RULE_MARKER) + minor_rule = find_rule(config, MINOR_RULE_MARKER) + if patch_rule is None or minor_rule is None: + return 1 + + patch_roles = listed_roles(patch_rule, "patch") + minor_roles = listed_roles(minor_rule, "minor") + if patch_roles is None or minor_roles is None: + return 1 + + errors = False + if set(patch_rule.get("matchUpdateTypes", [])) != {"patch"}: + print("The Molecule patch automerge rule must match only patch updates.", file=sys.stderr) + errors = True + if set(minor_rule.get("matchUpdateTypes", [])) != {"minor"}: + print("The Molecule minor automerge rule must match only minor updates.", file=sys.stderr) + errors = True + + automerged_without_scenario = sorted(patch_roles - with_scenario) + scenario_without_automerge = sorted(with_scenario - patch_roles) + + if automerged_without_scenario: + print( + "These roles automerge patch bumps but have no Molecule scenario, so nothing would\n" + "exercise the bump before it merges. Remove them from the rule in\n" + ".github/renovate.json, or give them a scenario:", + file=sys.stderr, + ) + for role in automerged_without_scenario: + print(f" {role}", file=sys.stderr) + + if scenario_without_automerge: + print( + "These roles have a Molecule scenario but are not in the automerge rule in\n" + ".github/renovate.json, so their patch bumps still need a button press:", + file=sys.stderr, + ) + for role in scenario_without_automerge: + print(f" {role}", file=sys.stderr) + + minor_without_scenario = sorted(minor_roles - with_scenario) + minor_without_patch = sorted(minor_roles - patch_roles) + + if minor_without_scenario: + print( + "These roles automerge minor bumps but have no Molecule scenario:", + file=sys.stderr, + ) + for role in minor_without_scenario: + print(f" {role}", file=sys.stderr) + + if minor_without_patch: + print( + "These roles automerge minor bumps but are missing from the patch rule:", + file=sys.stderr, + ) + for role in minor_without_patch: + print(f" {role}", file=sys.stderr) + + return 1 if any( + [ + errors, + automerged_without_scenario, + scenario_without_automerge, + minor_without_scenario, + minor_without_patch, + ] + ) else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/bin/check-molecule-automerge-list.py.license b/bin/check-molecule-automerge-list.py.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/bin/check-molecule-automerge-list.py.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/bin/molecule-clean.sh b/bin/molecule-clean.sh new file mode 100755 index 000000000..0b104785e --- /dev/null +++ b/bin/molecule-clean.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# Removes what `just molecule` leaves under var/. +# +# Called through `just molecule-clean [--idle-days N]`. +# +# Two things accumulate. The per-role Ansible homes are ~7 MB each and are +# rewritten on every run rather than growing, so they are bounded by the number +# of roles that have a scenario. The shared virtualenv is the bulk of it (over +# 500 MB) and is recreated on the next run, which costs a pip install. +# +# Usage: +# just molecule-clean # everything, after showing what and how much +# just molecule-clean --idle-days 14 # only what has not been touched in 14 days +# just molecule-clean --yes # skip the confirmation +# +# --idle-days is what makes this safe to run unattended: a scenario you ran this +# morning keeps its cache, and only roles you have not touched in a while lose +# theirs. + +set -euo pipefail + +repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +var_dir="${repo_dir}/var" + +idle_days="" +assume_yes="false" + +while [ $# -gt 0 ]; do + case "$1" in + --idle-days) + idle_days="${2:-}" + if ! [[ "${idle_days}" =~ ^[0-9]+$ ]]; then + echo "--idle-days needs a whole number of days" >&2 + exit 1 + fi + shift 2 + ;; + --yes|-y) + assume_yes="true" + shift + ;; + *) + echo "Unknown argument: $1" >&2 + echo "Usage: just molecule-clean [--idle-days N] [--yes]" >&2 + exit 1 + ;; + esac +done + +# Only ever the two directories bin/molecule.sh creates, named explicitly. `var/` +# holds other things and must never be removed wholesale. +targets=() +for candidate in "${var_dir}/molecule-ansible-home" "${var_dir}/molecule-venv"; do + [ -d "${candidate}" ] || continue + + if [ -n "${idle_days}" ] && [ -z "$(find "${candidate}" -maxdepth 0 -mtime "+${idle_days}")" ]; then + continue + fi + + targets+=("${candidate}") +done + +if [ ${#targets[@]} -eq 0 ]; then + if [ -n "${idle_days}" ]; then + echo "Nothing idle for more than ${idle_days} day(s)." + else + echo "Nothing to clean." + fi + exit 0 +fi + +echo "Would remove:" +for target in "${targets[@]}"; do + printf ' %s %s\n' "$(du -sh "${target}" | cut -f1)" "${target/#$HOME/\~}" +done + +if [ "${assume_yes}" != "true" ]; then + read -r -p "Remove these? [y/N] " reply + case "${reply}" in + y|Y|yes|YES) ;; + *) echo "Left alone."; exit 0 ;; + esac +fi + +for target in "${targets[@]}"; do + rm -rf "${target}" + echo "Removed ${target/#$HOME/\~}" +done + +echo "The virtualenv is recreated on the next \`just molecule\` run." diff --git a/bin/molecule-clean.sh.license b/bin/molecule-clean.sh.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/bin/molecule-clean.sh.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/bin/molecule.sh b/bin/molecule.sh new file mode 100755 index 000000000..87e7e4cc8 --- /dev/null +++ b/bin/molecule.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# Runs a role's Molecule scenario locally. +# +# Called through `just molecule [role] [args...]`. With no role, lists the roles +# that have a scenario. +# +# The same scenarios run in CI (.github/workflows/molecule.yml), but running one +# here is the faster loop while writing or fixing a role: CI only tells you after +# a push, and only about the roles that push touched. +# +# Deliberately NOT wired into prek. A run takes minutes, pulls container images +# and needs a working Docker - which is fine when you ask for it, and not fine on +# every commit. +# +# Usage: +# just molecule # list roles that have a scenario +# just molecule matrix-alertmanager-receiver +# just molecule matrix-alertmanager-receiver converge # any molecule subcommand +# +# Environment: +# MOLECULE_DISTRO base image to test on (default: ubuntu2604) + +set -euo pipefail + +repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +roles_dir="${repo_dir}/roles/custom" +venv_dir="${repo_dir}/var/molecule-venv" + +list_roles() { + find "${roles_dir}" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' \ + | while read -r candidate; do + if [ -f "${roles_dir}/${candidate}/molecule/default/molecule.yml" ]; then + echo "${candidate}" + fi + done \ + | sort +} + +role="${1:-}" + +if [ -z "${role}" ]; then + echo "Roles with a Molecule scenario:" + found="$(list_roles)" + if [ -z "${found}" ]; then + echo " (none yet)" + else + printf ' %s\n' ${found} + fi + echo + echo "Run one with: just molecule " + exit 0 +fi + +shift || true + +if [ ! -f "${roles_dir}/${role}/molecule/default/molecule.yml" ]; then + echo "No Molecule scenario at roles/custom/${role}/molecule/default" >&2 + echo >&2 + echo "Roles that have one:" >&2 + list_roles | sed 's/^/ /' >&2 + exit 1 +fi + +# The virtualenv lives under var/, which is gitignored, and is shared by every +# role - the dependencies are the same for all of them. +if [ ! -x "${venv_dir}/bin/molecule" ]; then + echo "Creating the Molecule virtualenv in ${venv_dir/#$HOME/\~} ..." + python3 -m venv "${venv_dir}" + "${venv_dir}/bin/pip" install --quiet --upgrade pip + "${venv_dir}/bin/pip" install --quiet -r "${repo_dir}/molecule-shared/requirements.txt" +fi + +# Galaxy content is installed with `force: true` on every run, so two scenarios +# running at once will re-extract collections and roles into the same directory +# and pull them out from under each other mid-play. It shows up as a collection +# that was working moments earlier going missing: +# +# the connection plugin 'community.docker.docker' was not found +# +# ANSIBLE_HOME relocates both `collections/` and `roles/`, so one variable is +# enough to give each role its own. The scenarios' ANSIBLE_ROLES_PATH follows it. +# +# Unset in CI, where it falls back to ~/.ansible - each role runs in its own job +# there, so there is nothing to collide with and nothing to gain from isolation. +export ANSIBLE_HOME="${ANSIBLE_HOME:-${repo_dir}/var/molecule-ansible-home/${role}}" + +export MOLECULE_DISTRO="${MOLECULE_DISTRO:-ubuntu2604}" +export PY_COLORS="${PY_COLORS:-1}" +export ANSIBLE_FORCE_COLOR="${ANSIBLE_FORCE_COLOR:-1}" + +echo "Running Molecule for ${role} on ${MOLECULE_DISTRO} ..." +cd "${roles_dir}/${role}" + +if [ $# -eq 0 ]; then + exec "${venv_dir}/bin/molecule" test --scenario-name default +fi + +exec "${venv_dir}/bin/molecule" "$@" --scenario-name default diff --git a/bin/molecule.sh.license b/bin/molecule.sh.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/bin/molecule.sh.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/bin/rebuild-mautrix-meta-instagram.sh b/bin/rebuild-mautrix-meta-instagram.sh deleted file mode 100755 index 406f92463..000000000 --- a/bin/rebuild-mautrix-meta-instagram.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash - -# SPDX-FileCopyrightText: 2024 Slavi Pantaleev -# -# SPDX-License-Identifier: AGPL-3.0-or-later - -set -euxo pipefail - -# This script rebuilds the mautrix-meta-instagram Ansible role, using the mautrix-meta-messenger role as a source. - -if [ $# -eq 0 ]; then - echo "Error: No argument supplied. Please provide the path to the roles/custom directory." - exit 1 -fi - -roles_path=$1 - -messenger_role_path=$roles_path/matrix-bridge-mautrix-meta-messenger -instagram_role_path=$roles_path/matrix-bridge-mautrix-meta-instagram - -if [ ! -d $messenger_role_path ]; then - echo "Cannot find: $messenger_role_path" - exit 1 -fi - -if [ -d $instagram_role_path ]; then - rm -rf $instagram_role_path -fi - -cp -ar $messenger_role_path $instagram_role_path - -find "$instagram_role_path" -type f | while read -r file; do - sed --in-place 's/matrix_mautrix_meta_messenger_/matrix_mautrix_meta_instagram_/g' "$file" - sed --in-place 's/mautrix-meta-messenger/mautrix-meta-instagram/g' "$file" -done - -sed --in-place 's/matrix_mautrix_meta_instagram_meta_mode: \(.*\)/matrix_mautrix_meta_instagram_meta_mode: instagram/g' $instagram_role_path/defaults/main.yml -sed --in-place 's/matrix_mautrix_meta_instagram_identifier: \(.*\)/matrix_mautrix_meta_instagram_identifier: matrix-mautrix-meta-instagram/g' $instagram_role_path/defaults/main.yml - -# Create the README.md file with the license header -cat > $instagram_role_path/README.md << 'EOF' - -EOF - -echo "" >> $instagram_role_path/README.md -echo "# matrix-mautrix-meta-instagram" >> $instagram_role_path/README.md -echo "" >> $instagram_role_path/README.md -echo "This bridge role is derived from the matrix-mautrix-meta-messenger Ansible role via automatic changes (see \`just rebuild-mautrix-meta-instagram\` or \`bin/rebuild-mautrix-meta-instagram.sh\`)." >> $instagram_role_path/README.md -echo "" >> $instagram_role_path/README.md -echo "If you'd like to make a change to this role, consider making it to the \`matrix-mautrix-meta-messenger\` role instead." >> $instagram_role_path/README.md diff --git a/collections/requirements.yml b/collections/requirements.yml index 483ed156a..ac8a6152d 100644 --- a/collections/requirements.yml +++ b/collections/requirements.yml @@ -1,4 +1,25 @@ --- +# This file is not used by the playbook's standard CLI installation flow. +# Roles are pulled via `make roles` / `just roles`, which call +# `ansible-galaxy install -r requirements.yml -p roles/galaxy/`. +# Collections are not installed by that command, and the playbook relies +# on whatever `community.*` collections ship with the user's `ansible` +# package (which has been recent enough for years). +# +# This file exists for AWX / Ansible Automation Platform users, which +# auto-detect `collections/requirements.yml` during project sync and +# install the listed collections. See: +# https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/87a2240dc +# +# CLI users do not need to install anything from this file. If you are +# using AWX and a collection version below the floor declared here is +# present, AWX will upgrade it. + collections: - name: community.general - name: community.docker + # `community.docker.docker_image_pull` and `community.docker.docker_image_build` + # are used by some roles (e.g. matrix-bot-draupnir, + # matrix-appservice-draupnir-for-all) and are first available in + # community.docker 3.6.0 (Jan 2024 / Ansible 9.2.0). + version: ">=3.6.0" diff --git a/docs/README.md b/docs/README.md index 266fad593..d3aabd2dc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -76,6 +76,8 @@ If your server and services experience issues, feel free to come to [our support - [Alternative architectures](alternative-architectures.md) +- [Configuring Synology DSM](configuring-playbook-synology.md) + - [Container images used by the playbook](container-images.md) - [Obtaining an Access Token](obtaining-access-tokens.md) @@ -88,6 +90,8 @@ If your server and services experience issues, feel free to come to [our support - [Self-building](self-building.md) +- [Style guide for playbook developers](style-guide.md) + - [Uninstalling](uninstalling.md) - [Updating users passwords](updating-users-passwords.md) diff --git a/docs/ansible.md b/docs/ansible.md index fb67c3838..7c5417ba6 100644 --- a/docs/ansible.md +++ b/docs/ansible.md @@ -39,6 +39,18 @@ If using the `pip` method, do note that the `ansible-playbook` binary may not be **Note**: Both of the above methods are a bad way to run system software such as Ansible. If you find yourself needing to resort to such hacks, please consider reporting a bug to your distribution and/or switching to a sane distribution, which provides up-to-date software. +## SSH host key and passphrase prompts + +If Ansible fails with `Host key verification failed` (or a similar `Data could not be sent to remote host` error) without asking you to confirm the SSH host key of your server, you're likely on Ansible 2.21 or later. + +Since Ansible 2.21, forked workers call `setsid()` and thus lose the controlling terminal. SSH cannot open `/dev/tty` anymore, so it can no longer ask you to confirm an unknown host key or prompt you for the passphrase of an SSH key. + +To fix host key errors, connect to the server once (e.g. `ssh root@matrix.example.com`) and confirm the host key. Ansible runs after that will find it in your `known_hosts` file. + +If your SSH key is protected by a passphrase, load it into an [ssh-agent](https://man.openbsd.org/ssh-agent) (e.g. `ssh-add ~/.ssh/id_ed25519`), so that SSH does not need to prompt for the passphrase. + +**Note**: if you're [using Ansible via Docker](#using-ansible-via-docker), host keys of previously unknown hosts are accepted automatically, so only the passphrase advice above applies to you. For the agent to be reachable inside the container, share its socket by adding `--mount type=bind,src=$SSH_AUTH_SOCK,dst=/ssh-agent --env SSH_AUTH_SOCK=/ssh-agent` to `docker run`. If the key is already loaded into the agent, you do not need to mount the SSH key file into the container at all. + ## Using Ansible via Docker Alternatively, you can run Ansible inside a Docker container (powered by the [ghcr.io/devture/ansible](https://github.com/devture/docker-ansible/pkgs/container/ansible) Docker image). @@ -50,6 +62,8 @@ This ensures that: You can either [run Ansible in a container on the Matrix server itself](#running-ansible-in-a-container-on-the-matrix-server-itself) or [run Ansible in a container on another computer (not the Matrix server)](#running-ansible-in-a-container-on-another-computer-not-the-matrix-server). +💡 If you use [Visual Studio Code](https://code.visualstudio.com/) or [GitHub Codespaces](https://github.com/features/codespaces), the playbook also ships a [dev container](https://containers.dev/) configuration (see the `.devcontainer/` directory) based on this same Ansible Docker image, which can prepare such a containerized Ansible environment for you automatically. + ### Running Ansible in a container on the Matrix server itself To run Ansible in a (Docker) container on the Matrix server itself, you need to have a working Docker installation. Docker is normally installed by the playbook, so this may be a bit of a chicken and egg problem. To solve it: @@ -74,7 +88,7 @@ docker run \ -w /work \ --mount type=bind,src=`pwd`,dst=/work \ --entrypoint=/bin/sh \ -ghcr.io/devture/ansible:11.6.0-r0-0 +ghcr.io/devture/ansible:14.0.0-r0-3 ``` Once you execute the above command, you'll be dropped into a `/work` directory inside a Docker container. The `/work` directory contains the playbook's code. @@ -95,7 +109,7 @@ docker run \ --mount type=bind,src=`pwd`,dst=/work \ --mount type=bind,src=$HOME/.ssh/id_ed25519,dst=/root/.ssh/id_ed25519,ro \ --entrypoint=/bin/sh \ -ghcr.io/devture/ansible:11.6.0-r0-0 +ghcr.io/devture/ansible:14.0.0-r0-3 ``` The above command tries to mount an SSH key (`$HOME/.ssh/id_ed25519`) into the container (at `/root/.ssh/id_ed25519`). If your SSH key is at a different path (not in `$HOME/.ssh/id_ed25519`), adjust that part. diff --git a/docs/configuring-captcha.md b/docs/configuring-captcha.md index a5ad1085d..5b20a6d90 100644 --- a/docs/configuring-captcha.md +++ b/docs/configuring-captcha.md @@ -15,6 +15,8 @@ Captcha can be enabled for this home server. This file explains how to do that. The captcha mechanism used is Google's [ReCaptcha](https://www.google.com/recaptcha/). This requires API keys from Google. If your homeserver is Dendrite then [hCapcha](https://www.hcaptcha.com) can be used instead. +If you are using [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md), captcha is configured there instead (it handles registration), and [Cloudflare Turnstile](https://www.cloudflare.com/application-services/products/turnstile/) is supported as well. See [Matrix Authentication Service](#matrix-authentication-service) below. + ## ReCaptcha ### Getting keys @@ -61,3 +63,16 @@ matrix_dendrite_client_api_recaptcha_api_js_url: 'https://js.hcaptcha.com/1/api. matrix_dendrite_client_api_recaptcha_form_field: 'h-captcha-response' matrix_dendrite_client_api_recaptcha_sitekey_class: 'h-captcha' ``` + +## Matrix Authentication Service + +When [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) is enabled, registration and other account operations are handled by it, so captcha protection is configured there (the Synapse and Dendrite settings above do not apply). + +Matrix Authentication Service supports [ReCaptcha v2](http://www.google.com/recaptcha/admin), [Cloudflare Turnstile](https://www.cloudflare.com/application-services/products/turnstile/) and [hCaptcha](https://dashboard.hcaptcha.com/sites/new). Obtain a site/secret key pair from your chosen service, then add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: + +```yaml +# Valid values: recaptcha_v2, cloudflare_turnstile, hcaptcha +matrix_authentication_service_config_captcha_service: recaptcha_v2 +matrix_authentication_service_config_captcha_site_key: 'YOUR_SITE_KEY' +matrix_authentication_service_config_captcha_secret_key: 'YOUR_SECRET_KEY' +``` diff --git a/docs/configuring-ipv6.md b/docs/configuring-ipv6.md index 80f425f8e..d8535b0b7 100644 --- a/docs/configuring-ipv6.md +++ b/docs/configuring-ipv6.md @@ -109,7 +109,7 @@ If you do have an IPv6 address, it's still worth [using curl](#with-curl) to con The `devture_systemd_docker_base_ipv6_enabled` setting controls whether container networks will be created with IPv6 support. Changing this setting subsequently requires manual work (deleting all container networks). -See [I've changed the `devture_systemd_docker_base_ipv6_enabled` setting, but it doesn't seem to have any effect](#i-ve-changed-the-devture_systemd_docker_base_ipv6_enabled-setting-but-it-doesn-t-seem-to-have-any-effect). +See [I've changed the `devture_systemd_docker_base_ipv6_enabled` setting, but it doesn't seem to have any effect](#ive-changed-the-devture_systemd_docker_base_ipv6_enabled-setting-but-it-doesnt-seem-to-have-any-effect). #### I've changed the `devture_systemd_docker_base_ipv6_enabled` setting, but it doesn't seem to have any effect. diff --git a/docs/configuring-playbook-appservice-draupnir-for-all.md b/docs/configuring-playbook-appservice-draupnir-for-all.md index 8827f759c..fce711584 100644 --- a/docs/configuring-playbook-appservice-draupnir-for-all.md +++ b/docs/configuring-playbook-appservice-draupnir-for-all.md @@ -1,4 +1,5 @@ +```yaml +matrix_bot_draupnir_configuration_extension_yaml: | + pollReports: true +``` ### Extending the configuration @@ -212,7 +270,7 @@ ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-use `just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. -- If you change the bot password (`matrix_bot_draupnir_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_draupnir_password` to let the bot know its new password. +- If you change the bot password (`matrix_bot_draupnir_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_draupnir_password` to let the bot know its new password. ## Usage diff --git a/docs/configuring-playbook-bot-go-neb.md b/docs/configuring-playbook-bot-go-neb.md index 9762176c6..2c58ff925 100644 --- a/docs/configuring-playbook-bot-go-neb.md +++ b/docs/configuring-playbook-bot-go-neb.md @@ -1,267 +1,26 @@ -# Setting up Go-NEB (optional, unmaintained) +# Setting up Go-NEB (optional, removed) -**Note**: [Go-NEB](https://github.com/matrix-org/go-neb) is now an archived (**unmaintained**) project. We recommend not bothering with installing it. While not a 1:1 replacement, the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md). Consider using that bot instead of this one. +🪦 The playbook used to be able to install and configure [Go-NEB](https://github.com/matrix-org/go-neb), but no longer includes this component as it has been discontinued. -The playbook can install and configure [Go-NEB](https://github.com/matrix-org/go-neb) for you. +While not a 1:1 replacement, the bot's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md). -Go-NEB is a Matrix bot written in Go. It is the successor to Matrix-NEB, the original Matrix bot written in Python. +## Uninstalling Go-NEB manually -See the project's [documentation](https://github.com/matrix-org/go-neb/blob/master/README.md) to learn what it does and why it might be useful to you. - -## Prerequisites - -### Register the bot account - -The playbook does not automatically create users for you. You **need to register the bot user manually** before setting up the bot. - -Generate a strong password for the bot. You can create one with a command like `pwgen -s 64 1`. - -You can use the playbook to [register a new user](registering-users.md): +If you still have the Go-NEB component installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server: ```sh -ansible-playbook -i inventory/hosts setup.yml --extra-vars='username=bot.go-neb password=PASSWORD_FOR_THE_BOT admin=no' --tags=register-user -``` - -### Obtain an access token - -The bot requires an access token to be able to connect to your homeserver. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md). - -> [!WARNING] -> Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone. - -## Adjusting DNS records - -By default, this playbook installs Go-NEB on the `goneb.` subdomain (`goneb.example.com`) and requires you to create a CNAME record for `goneb`, which targets `matrix.example.com`. - -When setting, replace `example.com` with your own. - -## Adjusting the playbook configuration - -To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file. Make sure to replace `ACCESS_TOKEN_FOR_GONEB_HERE` and `ACCESS_TOKEN_FOR_ANOTHER_GONEB_HERE` with the ones created [above](#obtain-an-access-token). - -```yaml -matrix_bot_go_neb_enabled: true - -# You need at least 1 client. -# Use the access token you obtained in the step above. -matrix_bot_go_neb_clients: - - UserID: "@goneb:{{ matrix_domain }}" - AccessToken: "ACCESS_TOKEN_FOR_GONEB_HERE" - DeviceID: "DEVICE1" - HomeserverURL: "{{ matrix_addons_homeserver_client_api_url }}" - Sync: true - AutoJoinRooms: true - DisplayName: "Go-NEB!" - AcceptVerificationFromUsers: [":{{ matrix_domain }}"] - - - UserID: "@another_goneb:{{ matrix_domain }}" - AccessToken: "ACCESS_TOKEN_FOR_ANOTHER_GONEB_HERE" - DeviceID: "DEVICE2" - HomeserverURL: "{{ matrix_addons_homeserver_client_api_url }}" - Sync: false - AutoJoinRooms: false - DisplayName: "Go-NEB!" - AcceptVerificationFromUsers: ["^@admin:{{ matrix_domain }}"] - -# Optional, for use with the github_cmd, github_webhooks or jira services -matrix_bot_go_neb_realms: - - ID: "github_realm" - Type: "github" - Config: {} # No need for client ID or Secret as Go-NEB isn't generating OAuth URLs - -# Optional. The list of *authenticated* sessions which Go-NEB is aware of. -matrix_bot_go_neb_sessions: - - SessionID: "your_github_session" - RealmID: "github_realm" - UserID: "@alice:{{ matrix_domain }}" # This needs to be the username of the person that's allowed to use the !github commands - Config: - # Populate these fields by generating a "Personal Access Token" on github.com - AccessToken: "YOUR_GITHUB_ACCESS_TOKEN" - Scopes: "admin:org_hook,admin:repo_hook,repo,user" - -# The list of services which Go-NEB is aware of. -# Delete or modify this list as appropriate. -# See the docs for /configureService for the full list of options: -# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureServiceRequest -# You need at least 1 service. -matrix_bot_go_neb_services: - - ID: "echo_service" - Type: "echo" - UserID: "@goneb:{{ matrix_domain }}" - Config: {} - -# Can be obtained from https://developers.giphy.com/dashboard/ - - ID: "giphy_service" - Type: "giphy" - UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client - Config: - api_key: "qwg4672vsuyfsfe" - use_downsized: false - -# This service has been dead for over a year :/ - - ID: "guggy_service" - Type: "guggy" - UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client - Config: - api_key: "2356saaqfhgfe" - -# API Key via https://developers.google.com/custom-search/v1/introduction -# CX via http://www.google.com/cse/manage/all -# https://stackoverflow.com/questions/6562125/getting-a-cx-id-for-custom-search-google-api-python -# 'Search the entire web' and 'Image search' enabled for best results - - ID: "google_service" - Type: "google" - UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client - Config: - api_key: "AIzaSyA4FD39m9" - cx: "AIASDFWSRRtrtr" - -# Obtain a key via https://api.imgur.com/oauth2/addclient -# Select "oauth2 without callback url" - - ID: "imgur_service" - Type: "imgur" - UserID: "@imgur:{{ matrix_domain }}" # requires a Syncing client - Config: - client_id: "AIzaSyA4FD39m9" - client_secret: "somesecret" - - - ID: "wikipedia_service" - Type: "wikipedia" - UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client - Config: - - - ID: "rss_service" - Type: "rssbot" - UserID: "@another_goneb:{{ matrix_domain }}" - Config: - feeds: - "http://lorem-rss.herokuapp.com/feed?unit=second&interval=60": - rooms: ["!qporfwt:{{ matrix_domain }}"] - must_include: - author: - - author1 - description: - - lorem - - ipsum - must_not_include: - title: - - Lorem - - Ipsum - - - ID: "github_cmd_service" - Type: "github" - UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client - Config: - RealmID: "github_realm" - - # Make sure your BASE_URL can be accessed by Github! - - ID: "github_webhook_service" - Type: "github-webhook" - UserID: "@another_goneb:{{ matrix_domain }}" - Config: - RealmID: "github_realm" - ClientUserID: "@alice:{{ matrix_domain }}" # needs to be an authenticated user so Go-NEB can create webhooks. Check the UserID field in the github_realm in matrix_bot_go_neb_sessions. - Rooms: - "!qporfwt:example.com": - Repos: - "element-hq/synapse": - Events: ["push", "issues"] - "matrix-org/dendron": - Events: ["pull_request"] - "!aaabaa:example.com": - Repos: - "element-hq/synapse": - Events: ["push", "issues"] - "matrix-org/dendron": - Events: ["pull_request"] +systemctl disable --now matrix-bot-go-neb.service - - ID: "slackapi_service" - Type: "slackapi" - UserID: "@slackapi:{{ matrix_domain }}" - Config: - Hooks: - "hook1": - RoomID: "!qporfwt:example.com" - MessageType: "m.text" # default is m.text - - - ID: "alertmanager_service" - Type: "alertmanager" - UserID: "@alertmanager:{{ matrix_domain }}" - Config: - # This is for information purposes only. It should point to Go-NEB path as follows: - # `/services/hooks/` - # Where in this case "service ID" is "alertmanager_service" - # Make sure your BASE_URL can be accessed by the Alertmanager instance! - webhook_url: "http://localhost/services/hooks/YWxlcnRtYW5hZ2VyX3NlcnZpY2U" - # Each room will get the notification with the alert rendered with the given template - rooms: - "!qporfwt:example.com": - text_template: "{% raw %}{{range .Alerts -}} [{{ .Status }}] {{index .Labels \"alertname\" }}: {{index .Annotations \"description\"}} {{ end -}}{% endraw %}" - html_template: "{% raw %}{{range .Alerts -}} {{ $severity := index .Labels \"severity\" }} {{ if eq .Status \"firing\" }} {{ if eq $severity \"critical\"}} [FIRING - CRITICAL] {{ else if eq $severity \"warning\"}} [FIRING - WARNING] {{ else }} [FIRING - {{ $severity }}] {{ end }} {{ else }} [RESOLVED] {{ end }} {{ index .Labels \"alertname\"}} : {{ index .Annotations \"description\"}} source
{{end -}}{% endraw %}" - msg_type: "m.text" # Must be either `m.text` or `m.notice` -``` - -### Adjusting the Go-NEB URL (optional) - -By tweaking the `matrix_bot_go_neb_hostname` and `matrix_bot_go_neb_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one. - -Example additional configuration for your `vars.yml` file: - -```yaml -# Switch to the domain used for Matrix services (`matrix.example.com`), -# so we won't need to add additional DNS records for Go-NEB. -matrix_bot_go_neb_hostname: "{{ matrix_server_fqn_matrix }}" - -# Expose under the /go-neb subpath -matrix_bot_go_neb_path_prefix: /go-neb +rm -rf /matrix/go-neb ``` - -After changing the domain, **you may need to adjust your DNS** records to point the Go-NEB domain to the Matrix server. - -If you've decided to reuse the `matrix.` domain, you won't need to do any extra DNS configuration. - -### Extending the configuration - -There are some additional things you may wish to configure about the bot. - -Take a look at: - -- `roles/custom/matrix-bot-go-neb/defaults/main.yml` for some variables that you can customize via your `vars.yml` file -- `roles/custom/matrix-bot-go-neb/templates/config.yaml.j2` for the bot's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_go_neb_configuration_extension_yaml` variable - -## Installing - -After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below: - - -```sh -ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start -``` - -The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` - -`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. - -## Usage - -To use the bot, invite it to any existing Matrix room (`/invite @bot.go-neb:example.com` where `example.com` is your base domain, not the `matrix.` domain). Make sure you are granted with the sufficient permission if you are not the room owner. - -Basic usage is like this: `!echo hi` or `!imgur puppies` or `!giphy matrix` - -If you enabled the github_cmd service, send `!github help` to the bot in the room to see the available commands. - -You can also refer to the upstream [Documentation](https://github.com/matrix-org/go-neb). - -## Troubleshooting - -As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-go-neb`. diff --git a/docs/configuring-playbook-bot-honoroit.md b/docs/configuring-playbook-bot-honoroit.md index 967ea0050..6325ba935 100644 --- a/docs/configuring-playbook-bot-honoroit.md +++ b/docs/configuring-playbook-bot-honoroit.md @@ -78,7 +78,7 @@ ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-use `just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. -- If you change the bot password (`matrix_bot_honoroit_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_honoroit_password` to let the bot know its new password. +- If you change the bot password (`matrix_bot_honoroit_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_honoroit_password` to let the bot know its new password. ## Usage diff --git a/docs/configuring-playbook-bot-matrix-registration-bot.md b/docs/configuring-playbook-bot-matrix-registration-bot.md index 706ea5991..d1c96587d 100644 --- a/docs/configuring-playbook-bot-matrix-registration-bot.md +++ b/docs/configuring-playbook-bot-matrix-registration-bot.md @@ -1,103 +1,34 @@ -# Setting up matrix-registration-bot (optional) +# Setting up matrix-registration-bot (optional, removed) -The playbook can install and configure [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot) for you. +🪦 The playbook used to be able to install and configure [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot), but no longer includes this component, as it has been unmaintained. -The bot allows you to easily **create and manage registration tokens** aka. invitation codes. It can be used for an invitation-based server, where you invite someone by sending them a registration token (tokens look like this: `rbalQ0zkaDSRQCOp`). They can register as per normal but have to provide a valid registration token in the final step of the registration process. +## Uninstalling the component manually -See the project's [documentation](https://github.com/moan0s/matrix-registration-bot/blob/master/README.md) to learn what it does and why it might be useful to you. +If you still have matrix-registration-bot installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server: -## Adjusting the playbook configuration - -To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: - -```yaml -matrix_bot_matrix_registration_bot_enabled: true - -# By default, the playbook will set use the bot with a username like this: `@bot.matrix-registration-bot:example.com`. -# Uncomment and adjust this part if you'd like to use a username different than the default -# matrix_bot_matrix_registration_bot_matrix_user_id_localpart: bot.matrix-registration-bot - -# Generate a strong password for the bot. You can create one with a command like `pwgen -s 64 1`. -matrix_bot_matrix_registration_bot_bot_password: PASSWORD_FOR_THE_BOT - -# Enables registration -matrix_synapse_enable_registration: true - -# Restrict registration to users with a token -matrix_synapse_registration_requires_token: true - -# Set an optional command prefix for the bot. This can be any arbitrary string, including whitespace. -# Example: "!regbot " -matrix_bot_matrix_registration_bot_bot_prefix: "" -``` - -The bot account will be created automatically. - -### Extending the configuration - -There are some additional things you may wish to configure about the bot. - -Take a look at: - -- `roles/custom/matrix-bot-matrix-registration-bot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file -- `roles/custom/matrix-bot-matrix-registration-bot/templates/config.yaml.j2` for the bridge's default configuration - -## Installing - -After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below: - - ```sh -ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-users-created,start -``` - -**Notes**: - -- The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account. - -- The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` - - `just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. - -- If you change the bot password (`matrix_bot_matrix_registration_bot_bot_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_matrix_registration_bot_bot_password` to let the bot know its new password. - -## Usage - -To use the bot, start a chat with `@bot.matrix-registration-bot:example.com` (where `example.com` is your base domain, not the `matrix.` domain). - -Send `help` to the bot to see the available commands. - -You can also refer to the upstream [Usage documentation](https://github.com/moan0s/matrix-registration-bot#supported-commands). - -If you have any questions, or if you need help setting it up, read the [troubleshooting guide](https://github.com/moan0s/matrix-registration-bot/blob/main/docs/troubleshooting.md) or join [#matrix-registration-bot:hyteck.de](https://matrix.to/#/#matrix-registration-bot:hyteck.de). - -To clean the cache (session & encryption data) after you changed the bot's username, changed the login method from access_token to password etc… you can use: - -```sh -just run-tags bot-matrix-registration-bot-clean-cache -``` - -## Troubleshooting - -As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-matrix-registration-bot`. - -### Increase logging verbosity - -The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: +systemctl disable --now matrix-bot-matrix-registration-bot.service -```yaml -# Valid values: ERROR, INFO, DEBUG -matrix_bot_matrix_registration_bot_logging_level: DEBUG +rm -rf /matrix/matrix-registration-bot ``` diff --git a/docs/configuring-playbook-bot-matrix-reminder-bot.md b/docs/configuring-playbook-bot-matrix-reminder-bot.md index 9661ed6fa..4302c7266 100644 --- a/docs/configuring-playbook-bot-matrix-reminder-bot.md +++ b/docs/configuring-playbook-bot-matrix-reminder-bot.md @@ -57,7 +57,7 @@ ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-use `just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. -- If you change the bot password (`matrix_bot_matrix_reminder_bot_matrix_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_matrix_reminder_bot_matrix_user_password` to let the bot know its new password. +- If you change the bot password (`matrix_bot_matrix_reminder_bot_matrix_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_matrix_reminder_bot_matrix_user_password` to let the bot know its new password. ## Usage diff --git a/docs/configuring-playbook-bot-maubot.md b/docs/configuring-playbook-bot-maubot.md index 367a3aaac..2ddc1c2c6 100644 --- a/docs/configuring-playbook-bot-maubot.md +++ b/docs/configuring-playbook-bot-maubot.md @@ -103,7 +103,7 @@ ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-use `just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. -- If you change the bot password (`matrix_bot_maubot_initial_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_maubot_initial_password` to let the bot know its new password. +- If you change the bot password (`matrix_bot_maubot_initial_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_maubot_initial_password` to let the bot know its new password. ## Usage diff --git a/docs/configuring-playbook-bot-meowlnir.md b/docs/configuring-playbook-bot-meowlnir.md new file mode 100644 index 000000000..5d0c153d5 --- /dev/null +++ b/docs/configuring-playbook-bot-meowlnir.md @@ -0,0 +1,409 @@ + + +# Setting up Meowlnir (optional) + +The playbook can install and configure the [Meowlnir](https://github.com/maunium/meowlnir) moderation bot for you. + +See the project's [documentation](https://docs.mau.fi/meowlnir/) to learn what it does and why it might be useful to you. + +Meowlnir is an alternative to [Draupnir](configuring-playbook-bot-draupnir.md) and [Mjolnir](configuring-playbook-bot-mjolnir.md). It speaks the same [policy list](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists) protocol, so it can subscribe to the same community ban lists, but it differs from them in a few ways that may matter to you: + +- It runs as an **appservice** and hosts **multiple bots**, each with its own management room. They live in Meowlnir's database, not its configuration file, but you still [declare them in your `vars.yml` file](#declaring-bots). +- It can **override a policy coming from a list you do not control**, via unban policies combined with the ordering of your watched lists. See [Overriding a policy from someone else's list](#overriding-a-policy-from-someone-elses-list). +- It is written in Go and is optimized for Synapse, using its database and admin APIs directly. + +Meowlnir and Draupnir can run side by side, but not usefully in the *same* room: whichever bot you are migrating away from still watches the same community lists, so it re-applies the very bans your unban policies remove. Migrate room by room. See [Trialling Meowlnir alongside another bot](#trialling-meowlnir-alongside-another-bot). + +## Prerequisites + +### Postgres + +Meowlnir stores its state in a Postgres database. The playbook creates one for you automatically when using the integrated Postgres server. + +### Adjusting DNS records + +**No DNS changes are necessary.** Meowlnir is reached by the homeserver over the container network, and the paths it optionally serves publicly (abuse reports and the policy server) are routed on your existing `matrix.example.com` domain. + +## Adjusting the playbook configuration + +To enable Meowlnir, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: + +```yaml +matrix_bot_meowlnir_enabled: true +``` + +### Declaring bots + +That gets the service running, but Meowlnir does nothing until it has at least one bot. Declare the ones you want and the playbook creates them for you: + +```yaml +matrix_bot_meowlnir_bots_custom: + - username: meowlnir_bot + displayname: Meowlnir + avatar_url: "" + management_room_auto_create: true + management_rooms: [] + # Left out, the initial managers default to `matrix_bot_meowlnir_initial_managers`, + # which is defined in terms of `matrix_admin`. + # Uncomment to override that for this bot, or if neither variable is set. + # initial_managers: + # - "@alice:example.com" + # - "@bob:example.com" +``` + +| Field | Required | Notes | +|---|---|---| +| `username` | yes | The localpart of the bot's Matrix user. Awkward to change later, so choose it carefully. | +| `displayname` | yes | The name shown in rooms. Safe to change at any time. | +| `avatar_url` | yes | An `mxc://` URI, or `""` for no avatar. | +| `management_room_auto_create` | yes | Whether the playbook creates the bot's management room. Mutually exclusive with a non-empty `management_rooms`. | +| `management_rooms` | yes | Rooms you have created yourself, `[]` when auto-creating. See [Supplying your own management room](#supplying-your-own-management-room). | +| `initial_managers` | no | Who to invite to an auto-created room. Defaults to the instance-wide list below. | + +Usernames have to start with `meowlnir_` (the value of `matrix_bot_meowlnir_user_prefix`), so that bots fall inside the user namespace the homeserver lets Meowlnir operate. + +Changing `displayname` or `avatar_url` and re-running updates the bot in place. The comparison is against Meowlnir's own record, so profile edits made directly from a Matrix client are not reverted. + +#### Initial managers + +With `management_room_auto_create: true`, the playbook creates each bot's management room and invites its initial managers to it. You only need to accept the room invitation. + +`matrix_admin` is a single playbook variable which affects all bridges and bots, so setting it is usually a better move than setting anything specific to this role — **if it is already configured in your `vars.yml` file, there is nothing to do here**. If neither `matrix_admin` nor `matrix_bot_meowlnir_initial_managers` are set, the playbook would tell you about it. + +A per-bot `initial_managers` replaces the instance-wide list. Declaring it empty means nobody, which fails the run for a bot relying on `management_room_auto_create`. + +The list is consulted only while the room is being created. Adding a name to it later invites nobody, because the room already exists — invite and promote further moderators from inside the room instead, as described in [Who can command a bot](#who-can-command-a-bot). + +#### Rooms the playbook creates + +The bot creates the room with the `trusted_private_chat` preset, which gives every invitee the standing to command it. This is an additional room creator on room versions supporting [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289) (like v12) and power level 100 on older room versions. Creator status cannot be revoked subsequently. + +The room's encryption follows `matrix_bot_meowlnir_config_encryption_enable`, and its name and topic come from `matrix_bot_meowlnir_management_room_name` and `matrix_bot_meowlnir_management_room_topic`. + +### Supplying your own management room + +If you would rather own the room outright, create it yourself and declare it instead. The bot is then merely an administrator in a room you created: + +```yaml +matrix_bot_meowlnir_bots_custom: + - username: meowlnir_bot + displayname: Meowlnir + avatar_url: "" + management_room_auto_create: false + management_rooms: + - id: "!qporfwt:example.com" + encrypted: false +``` + +An empty, invite-only room is fine. The order matters, because **each step depends on the one before it**: + +1. Declare the room and run the playbook. Do not invite the bot beforehand. +2. The playbook creates the bot and tells Meowlnir about the room. Meowlnir would try to join right away, but will fail for invite-only rooms (a harmless error in the log). +3. Invite the bot. It accepts the invitation, because the room is already marked as a management room for it. +4. Give it power level 50 or more (ideally 100), so that it can store its protected rooms and watched lists there. + +Meowlnir supports several management rooms per bot, and `encrypted` is set per room. Marking a room encrypted only means something when [End-to-End Encryption support](#end-to-end-encryption-support) is switched on, which it is not by default. + +### Several management rooms for one bot + +Protected rooms, watched policy lists, protection settings and who may command the bot are properties of **a management room**, not of the bot. A room can be protected from exactly one management room, so moving a room means `!rooms unprotect` in the old room and `!rooms protect` in the new one, with its settings and subscriptions set up again there. + +That is how you hand one room to another moderator without giving them power over everything else the bot moderates: a second management room, the room moved into it, and power level 50 for them there. That last part is revocable, unlike the creator status everyone invited at creation time receives. + +Splitting rooms up this way does not split two other things: + +- The variables which name a single management room (`matrix_bot_meowlnir_synapse_http_antispam_management_room_id`, `matrix_bot_meowlnir_config_meowlnir_report_room`, `matrix_bot_meowlnir_config_meowlnir_room_ban_room`) keep pointing at the room you named there. +- A policy list can be written to from any management room watching it, and its policies apply in every room those management rooms protect. Give a delegated management room a list of its own with `!lists create`. + +Create the room with `meowlnir-create-management-room` (see [Inspecting and driving Meowlnir directly](#inspecting-and-driving-meowlnir-directly)), then add its ID to `management_rooms` and re-run the playbook, which is what registers it with Meowlnir. + +#### Switching a bot from an auto-created room to declared ones + +Auto-creation makes exactly one room, and since it is not declared anywhere, [pruning](#bots-which-are-no-longer-declared) leaves such a bot's rooms alone. Declaring a second room means taking over the declaration of all of them: list what Meowlnir knows about with `/matrix/meowlnir/bin/meowlnir-bots`, set `management_room_auto_create: false`, put **every** one of those rooms under `management_rooms`, and re-run the playbook. + +> [!WARNING] +> A room left out of that list is unregistered on the next run. Nothing is destroyed, but the bot stops taking commands there and stops protecting the rooms attached to it, until you declare the room again. + +### Who can command a bot + +**Management room membership alone is not enough**, which is different from what [Draupnir](configuring-playbook-bot-draupnir.md) does, where everyone in the management room can issue commands. + +Meowlnir decides who may drive a bot from power levels in its management room: anyone who can send the `fi.mau.meowlnir.watched_lists` state event (power level 50 by default), plus the room's creators. + +### Bots which are no longer declared + +The bot list (`matrix_bot_meowlnir_bots_custom`) is authoritative. Removing entries from there will make the playbook unregister them with the Meowlnir instance. + +Removal only adjusts Meowlnir's own records. A removed bot's Matrix user remains activated and stays in the rooms it had joined. A removed management room leaves the room and the bot's membership in it intact - it's just that Meowlnir stops taking commands there. + +Removal happens under the same `ensure-matrix-users-created` tag that creates bots. It's one Ansible tag for "synchronizing the bots state" (creation, changes, and removal). + +To turn removal off entirely, set `matrix_bot_meowlnir_bots_pruning_enabled: false`. As a safety measure, the playbook refuses to prune when *no* bots are declared at all; override that with `matrix_bot_meowlnir_bots_pruning_on_empty_roster_enabled: true`. + +### Trialling Meowlnir alongside another bot + +Meowlnir has a dry-run mode in which it does everything except take moderation actions: + +```yaml +matrix_bot_meowlnir_config_meowlnir_dry_run: true +``` + +> [!WARNING] +> Dry run does not cover the [synapse-http-antispam](#enabling-synapse-http-antispam-support) integration. It suppresses actions Meowlnir takes itself (bans, server ACLs, rejecting pending invites), but the verdicts it hands back to Synapse still block invites and joins. Leave that integration off while trialling. + +Do not expect dry run to preview what Meowlnir would do in rooms another policy-list bot already moderates. Meowlnir only acts on users who are *in* a room, and the other bot has already removed everyone its lists match, so the preview comes out empty. Dry run also skips the power level check described under [Protecting a room](#protecting-a-room), so it will not surface a permissions problem either. + +### Abuse reports + +Meowlnir can intercept the report endpoints of the client-server API, so that abuse reports are delivered to a management room. This requires integration with the reverse proxy in front of the homeserver, which the playbook sets up for you when using Traefik: + +```yaml +matrix_bot_meowlnir_config_reporting_enabled: true + +# The management room that receives the reports. +matrix_bot_meowlnir_config_meowlnir_report_room: "!qporfwt:example.com" +``` + +Only the `v3` report endpoints are routed to Meowlnir. Requests to the legacy `r0` endpoints continue to reach the homeserver, because Meowlnir does not serve them. + +### Enabling synapse-http-antispam support + +Meowlnir can block invites and joins before they happen. This requires the [synapse-http-antispam](https://github.com/maunium/synapse-http-antispam) module, which the playbook can enable for you: + +```yaml +matrix_bot_meowlnir_synapse_http_antispam_enabled: true + +# The management room whose policies the module consults. +matrix_bot_meowlnir_synapse_http_antispam_management_room_id: "!qporfwt:example.com" +``` + +> [!WARNING] +> The playbook wires the module up to a single consumer, so this cannot be enabled at the same time as `matrix_bot_draupnir_config_web_synapseHTTPAntispam_enabled`. The playbook fails the run if both are enabled. + +With the module in place, you can also block invitations to specific users outright, which is useful for accounts that attract spam: + +```yaml +matrix_bot_meowlnir_config_antispam_block_invites_to_custom: + - "@alice:example.com" +``` + +Such an invitation can still be let through case by case with the `!allow-invite` command. + +### End-to-End Encryption support + +To let Meowlnir's bots participate in encrypted rooms: + +```yaml +matrix_bot_meowlnir_config_encryption_enable: true +``` + +When using Synapse, the playbook turns on the experimental features this depends on (`msc2409_to_device_messages_enabled` and `msc3202_transaction_extensions`) for you. + +### Policy server (MSC4284) + +Meowlnir can act as a [policy server](https://github.com/matrix-org/matrix-spec-proposals/pull/4284), letting rooms ask it to vet events before they are accepted: + +```yaml +matrix_bot_meowlnir_policy_server_enabled: true +``` + +This exposes `/_matrix/policy` on your Matrix federation endpoint, so that other servers participating in a room can reach it. + +That only stands the policy server up, though — no room is put behind it until you say so from the management room: + +``` +!policyserver enable !qporfwt:example.com +``` + +Given no room, `enable` applies to every protected room. Rooms which are not protected are skipped, with `Skipped ... as it is not a protected room`, so [protect a room](#protecting-a-room) before enabling it here. `!policyserver` on its own reports whether the policy server is available and prints its public key, and `!policyserver disable` reverses the change. + +The playbook derives a stable signing key for you from `matrix_homeserver_generic_secret_key`. If you would rather use an independently generated one, produce it with the command below and set it as `matrix_bot_meowlnir_config_policy_server_signing_key`: + +```sh +python3 -c "import os, base64; print('ed25519 policy_server ' + base64.b64encode(os.urandom(32)).decode().rstrip('='))" +``` + +### Synapse admin API access (optional) + +A few of Meowlnir's features go through Synapse's admin API, not the client-server API — suspending or deactivating users, and deleting rooms during a takedown. Those calls require the caller to be a Synapse **server admin**, which bots are not by default, so they come back as `M_FORBIDDEN` ("You are not a server admin"). Nothing else is affected: bans, server ACLs, protecting rooms and watching policy lists all go through the client-server API, where a sufficient power level is the only requirement. + +To grant that access, point each bot at a token belonging to a server admin: + +```yaml +matrix_bot_meowlnir_config_meowlnir_admin_tokens: + "@meowlnir_bot:example.com": "ADMIN_TOKEN_HERE" +``` + +The key is the bot the token is used for; the token itself belongs to an administrator account, not to the bot. + +If you have more than one management room, note that room bans are only processed in the one named by `matrix_bot_meowlnir_config_meowlnir_room_ban_room`, and ignored elsewhere. + +Where the token comes from depends on how your homeserver authenticates. Ordinarily you [obtain an access token](obtaining-access-tokens.md) for an account which is a Synapse server admin. When [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) is enabled, Synapse no longer decides who is an admin, so the token has to be issued by MAS with admin privileges: + +```sh +/matrix/matrix-authentication-service/bin/mas-cli manage issue-compatibility-token --yes-i-want-to-grant-synapse-admin-privileges alice +``` + +Note that bot users are created by the appservice and are not known to Matrix Authentication Service, so the token cannot be issued for the bot itself — use an administrator account. + +### Access to the Synapse database (optional) + +Some room takedown features rely on Meowlnir reading room IDs directly from the Synapse database. Upstream expects a user with read-only permissions, which the playbook does not create. Enabling the integration below hands Meowlnir the same credentials Synapse itself uses, which also grant write access: + +```yaml +matrix_bot_meowlnir_synapse_database_integration_enabled: true +``` + +If you would rather not do that, create a read-only Postgres user yourself and point Meowlnir at it with `matrix_bot_meowlnir_synapse_database_uri`. + +### Adopting an existing Meowlnir installation + +If you already run Meowlnir outside the playbook and want to bring it under this role, two things need attention before the first run. + +Your bots exist in Meowlnir's database but not in your `vars.yml` file, and [pruning](#bots-which-are-no-longer-declared) is on by default, so the first run would remove them. Declare them in `matrix_bot_meowlnir_bots_custom` — with `management_room_auto_create: false` and their existing rooms under `management_rooms` — or set `matrix_bot_meowlnir_bots_pruning_enabled: false`. + +If the installation uses encryption, also copy the `pickle_key` from its old configuration file into `matrix_bot_meowlnir_config_encryption_pickle_key`. The crypto store cannot be read with a different key than it was written with, so leaving the playbook's default in place costs your bots their existing encryption sessions. + +### Extending the configuration + +There are some additional things you may wish to configure about the bot. + +Take a look at: + +- `roles/custom/matrix-bot-meowlnir/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_meowlnir_configuration_extension_yaml` variable + +> [!WARNING] +> Do not set any of Meowlnir's secrets to the literal value `generate`. Meowlnir re-runs its configuration upgrader on every start, so a `generate` placeholder would produce a brand new secret on every restart. The playbook derives stable values for you, and fails the run if it finds a `generate` placeholder. + +## Installing + +After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below: + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-users-created,start +``` + +With `management_room_auto_create`, you then have an invitation waiting for you — accept it and start sending commands. If you supplied the management room yourself, carry on from step 3 of [Supplying your own management room](#supplying-your-own-management-room): invite the bot, then give it power level 50 or more. + +**Notes**: + +- The `ensure-matrix-users-created` tag is what creates the bots declared in `matrix_bot_meowlnir_bots_custom`, registers their management rooms, and removes the ones you no longer declare. It deliberately does not run as part of `setup-all`, so that installing onto a server whose database you are about to restore from a backup does not write anything. + +- Re-running is safe and idempotent, so adding a bot later is a matter of extending the list and running the same command again. + +- If the homeserver turns out to be running without Meowlnir's appservice registration (which is the normal state of affairs on the run that first enables Meowlnir), the playbook restarts the homeserver during bot provisioning, so that everything completes in a single run. + +- The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` + +## Usage + +You can refer to the upstream [documentation](https://docs.mau.fi/meowlnir/) for a more detailed usage guide. + +Below is a **non-exhaustive quick-start guide** for the impatient. + +### Inspecting and driving Meowlnir directly + +The playbook drives Meowlnir's management API for you based on `matrix_bot_meowlnir_bots_custom`, which is the recommended way. For anything it does not cover, helper scripts are installed under `/matrix/meowlnir/bin`, which find the management secret and reach the API inside the container: + +```sh +# Show the bots, their management rooms, protected rooms and watched policy lists +/matrix/meowlnir/bin/meowlnir-bots + +# Call any endpoint: meowlnir-api [JSON body] +/matrix/meowlnir/bin/meowlnir-api GET /_meowlnir/v1/bots + +# Create another management room for an existing bot, with the given users able to command it there +/matrix/meowlnir/bin/meowlnir-create-management-room meowlnir_bot @alice:example.com + +# Ask the homeserver who Meowlnir's appservice token belongs to. +# A 401 response means the homeserver is running without Meowlnir's appservice registration, which is also what Meowlnir's own "Failed to connect to homeserver" log messages usually mean. +/matrix/meowlnir/bin/meowlnir-whoami +``` + +`meowlnir-create-management-room` prints the new room's ID, which you then register with `meowlnir-api PUT /_meowlnir/v1/management_room/`. + +See the upstream [bot creation documentation](https://docs.mau.fi/meowlnir/bot-create.html) for the full set of endpoints. Bear in mind that bots you create this way are not declared in your `vars.yml` file, so the next playbook run will remove them again (see [Bots which are no longer declared](#bots-which-are-no-longer-declared)). + +If you have enabled encryption, each bot also needs verifying once. That step is left manual because it returns a recovery key you need to store somewhere safe: + +```sh +/matrix/meowlnir/bin/meowlnir-api POST /_meowlnir/v1/bot/meowlnir_bot/verify '{"generate": true}' +``` + +### Protecting a room + +Invite the bot to a room, give it a power level high enough to act (see below), and then tell it to protect the room by sending this command to its management room: + +``` +!rooms protect !qporfwt:example.com +``` + +If the bot has more than one management room, send this to the one that should own the room: a room can only be protected from a single management room. See [Several management rooms for one bot](#several-management-rooms-for-one-bot). + +Meowlnir refuses to protect a room unless its power level reaches that room's own `ban` and `redact` levels (50 in a default room). That is only enough for user bans, though: writing `m.room.server_acl` usually requires 100, and without it the server rules in your watched lists have no effect — which is most of what a list like [CME](https://matrix.to/#/%23community-moderation-effort-bl:neko.dev) carries. **Give the bot power level 100** unless you only care about user bans. + +Set the power level *before* protecting the room. Meowlnir re-sends server ACLs when it starts and when a watched list changes, but not when its own power level goes up subsequently, so raising it afterwards leaves the room without ACLs until you restart the bot (`systemctl restart matrix-bot-meowlnir` or via the playbook's Ansible `start` tag). + +### Subscribing to a policy list + +Policy lists are maintained in Matrix rooms. Popular public ones are: + +- `#community-moderation-effort-bl:neko.dev` +- `#huginn-muninn-active-threats:feline.support` + +Subscribe to one by sending the following command to the management room: + +``` +!lists subscribe #community-moderation-effort-bl:neko.dev cme +``` + +The last argument is a shortcode, which you use to refer to the list in later commands. + +### Overriding a policy from someone else's list + +This is the main capability Meowlnir has that Draupnir does not. + +When several watched lists carry a policy for the same user, **the first match wins**, and "first" means the order in which the lists are watched. So to be able to override a community list's ban, your own list has to come before it. + +`!lists subscribe` appends, which makes subscription order the precedence order. Subscribe to your own list first, and to community lists afterwards: + +``` +!lists create my-ban-exceptions +!lists subscribe #community-moderation-effort-bl:neko.dev cme +``` + +> [!NOTE] +> To subscribe somewhere other than the end of the list, pass `--insert-before `. + +You can then publish an unban policy into your own list, which takes precedence over the community list's ban: + +``` +!add-unban my-bans @alice:example.com false-positive +``` + +> [!NOTE] +> Unlike `!ban`, the `!add-unban` command does not treat its reason as a trailing argument, so a reason containing spaces is discarded. Use a single word (or hyphenate) until that is fixed upstream. + +> [!IMPORTANT] +> An unban policy stops a ban from being **re-applied**; it does not undo one that is already in place unless Meowlnir applied it itself and still has it on record. A ban placed by a human moderator, or by the Draupnir or Mjolnir you are migrating away from, stays. Unban such a user once by hand — from then on the policy keeps them unbanned, while you remain subscribed to the list that banned them. + +Use `!match @alice:example.com` to see which policies currently apply to a user and which list each came from. + +> [!NOTE] +> Unban policies use a Meowlnir-specific recommendation (`fi.mau.meowlnir.unban`) which is not part of the Matrix specification. If you publish your policy list for other people to subscribe to, subscribers running Draupnir or Mjolnir will ignore your unban policies. + +There is also a blunter, server-wide escape hatch for policies that are too wide to tolerate at all — `matrix_bot_meowlnir_config_meowlnir_hacky_rule_filter_custom`, which makes Meowlnir ignore any policy matching the listed entities. + +## Troubleshooting + +As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by running a command like `journalctl -fu matrix-bot-meowlnir`. + +If bots appear to do nothing, check that they have an Administrator power level in the rooms they are meant to protect, and that the room has been added with `!rooms protect`. + +If commands in a management room get no reply at all, check the bot's power level *there* too — it needs at least 50 to record its own configuration. + +A bare `!lists` returns nothing in a management room which has never had a policy list. That is an upstream bug and it clears as soon as you subscribe to one; `!lists subscribe` works from the start. diff --git a/docs/configuring-playbook-bot-mjolnir.md b/docs/configuring-playbook-bot-mjolnir.md index 5455ffe47..6e6b57e9b 100644 --- a/docs/configuring-playbook-bot-mjolnir.md +++ b/docs/configuring-playbook-bot-mjolnir.md @@ -15,6 +15,8 @@ The playbook can install and configure the [Mjolnir](https://github.com/matrix-o See the project's [documentation](https://github.com/matrix-org/mjolnir/blob/main/README.md) to learn what it does and why it might be useful to you. +**Note**: you can also use the [Draupnir](configuring-playbook-bot-draupnir.md) or [Meowlnir](configuring-playbook-bot-meowlnir.md) bots, which speak the same [policy list](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists) protocol. + ## Prerequisites ### Register the bot account @@ -46,7 +48,7 @@ This can be done using Synapse's [Admin APIs](https://element-hq.github.io/synap **Note**: access to the APIs is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, doing so is not recommended for additional security. See [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints). -The APIs can also be accessed via [Synapse Admin](https://github.com/etkecc/synapse-admin), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md). +The APIs can also be accessed via [Ketesa](https://github.com/etkecc/ketesa), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md). #### Add the configuration @@ -198,7 +200,7 @@ ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start `just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. -- If you change the Pantalaimon's password (`matrix_bot_mjolnir_pantalaimon_password` in your `vars.yml` file) subsequently, its credentials on the homeserver won't be updated automatically. If you'd like to change the password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_mjolnir_pantalaimon_password` to let Pantalaimon know its new password. +- If you change the Pantalaimon's password (`matrix_bot_mjolnir_pantalaimon_password` in your `vars.yml` file) subsequently, its credentials on the homeserver won't be updated automatically. If you'd like to change the password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_mjolnir_pantalaimon_password` to let Pantalaimon know its new password. ## Usage diff --git a/docs/configuring-playbook-bridge-appservice-discord.md b/docs/configuring-playbook-bridge-appservice-discord.md index 6c4f77a73..98a8c950c 100644 --- a/docs/configuring-playbook-bridge-appservice-discord.md +++ b/docs/configuring-playbook-bridge-appservice-discord.md @@ -26,9 +26,9 @@ Create a Discord Application [here](https://discordapp.com/developers/applicatio To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_appservice_discord_enabled: true -matrix_appservice_discord_client_id: "YOUR DISCORD APP CLIENT ID" -matrix_appservice_discord_bot_token: "YOUR DISCORD APP BOT TOKEN" +matrix_bridge_appservice_discord_enabled: true +matrix_bridge_appservice_discord_client_id: "YOUR DISCORD APP CLIENT ID" +matrix_bridge_appservice_discord_bot_token: "YOUR DISCORD APP BOT TOKEN" # As of Synapse 1.90.0, uncomment to enable the backwards compatibility (https://matrix-org.github.io/synapse/latest/upgrade#upgrading-to-v1900) that this bridge needs. # Note: This deprecated method is considered insecure. @@ -44,7 +44,7 @@ There are some additional things you may wish to configure about the bridge. Take a look at: - `roles/custom/matrix-bridge-appservice-discord/defaults/main.yml` for some variables that you can customize via your `vars.yml` file -- `roles/custom/matrix-bridge-appservice-discord/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_appservice_discord_configuration_extension_yaml` variable +- `roles/custom/matrix-bridge-appservice-discord/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_appservice_discord_configuration_extension_yaml` variable ## Installing @@ -65,7 +65,7 @@ The shortcut commands with the [`just` program](just.md) are also available: `ju Self-service bridging allows you to bridge specific and existing Matrix rooms to specific Discord rooms. To enable it, add the following configuration to your `vars.yml` file: ```yaml -matrix_appservice_discord_bridge_enableSelfServiceBridging: true +matrix_bridge_appservice_discord_bridge_enableSelfServiceBridging: true ``` **Note**: If self-service bridging is not enabled, `!discord help` commands will return no results. @@ -91,14 +91,14 @@ All Matrix rooms created this way are **listed publicly** by default, and you wi To disable portal bridging, add the following configuration to your `vars.yml` file: ```yaml -matrix_appservice_discord_bridge_disablePortalBridging: true +matrix_bridge_appservice_discord_bridge_disablePortalBridging: true ``` ### Usage To get started with Portal Bridging: -1. To invite the bot to Discord, retrieve the invite link from the `{{ matrix_appservice_discord_config_path }}/invite_link` file on the server (this defaults to `/matrix/appservice-discord/config/invite_link`). You need to peek at the file on the server via SSH, etc., because it's not available via HTTP(S). +1. To invite the bot to Discord, retrieve the invite link from the `{{ matrix_bridge_appservice_discord_config_path }}/invite_link` file on the server (this defaults to `/matrix/appservice-discord/config/invite_link`). You need to peek at the file on the server via SSH, etc., because it's not available via HTTP(S). 2. Room addresses follow this syntax: `#_discord__`. You can easily find the guild and channel IDs by logging into Discord in a browser and opening the desired channel. The URL will have this format: `discord.com/channels//`. 3. Once you have figured out the appropriate room address, you can join by doing `/join #_discord__` in your Matrix client. @@ -124,7 +124,7 @@ As with all other services, you can find the logs in [systemd-journald](https:// The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file (adapt to your needs) and re-run the playbook: ```yaml -matrix_appservice_discord_configuration_extension_yaml: | +matrix_bridge_appservice_discord_configuration_extension_yaml: | logging: # What level should the logger output to the console at. console: "info" # Valid values: silent, error, warn, http, info, verbose, silly diff --git a/docs/configuring-playbook-bridge-appservice-irc.md b/docs/configuring-playbook-bridge-appservice-irc.md index f4eb9eb47..a2d5710be 100644 --- a/docs/configuring-playbook-bridge-appservice-irc.md +++ b/docs/configuring-playbook-bridge-appservice-irc.md @@ -20,9 +20,9 @@ See the project's [documentation](https://github.com/matrix-org/matrix-appservic To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_appservice_irc_enabled: true +matrix_bridge_appservice_irc_enabled: true -matrix_appservice_irc_ircService_servers: +matrix_bridge_appservice_irc_ircService_servers: irc.example.com: name: "ExampleNet" port: 6697 @@ -76,7 +76,7 @@ There are some additional things you may wish to configure about the bridge. Take a look at: - `roles/custom/matrix-bridge-appservice-irc/defaults/main.yml` for some variables that you can customize via your `vars.yml` file -- `roles/custom/matrix-bridge-appservice-irc/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_appservice_irc_configuration_extension_yaml` variable +- `roles/custom/matrix-bridge-appservice-irc/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_appservice_irc_configuration_extension_yaml` variable ## Installing @@ -104,7 +104,7 @@ As with all other services, you can find the logs in [systemd-journald](https:// The default logging level for this component is `debug`, and the log is output to the console only. If you want to change the verbosity or enable logging to a file, add the following configuration to your `vars.yml` file (adapt to your needs) and re-run the playbook: ```yaml -matrix_appservice_irc_configuration_extension_yaml: | +matrix_bridge_appservice_irc_configuration_extension_yaml: | logging: # Level to log on console/logfile. # Valid values: error, warn, info, debug diff --git a/docs/configuring-playbook-bridge-appservice-kakaotalk.md b/docs/configuring-playbook-bridge-appservice-kakaotalk.md index 99ebc1ef0..1d48c1163 100644 --- a/docs/configuring-playbook-bridge-appservice-kakaotalk.md +++ b/docs/configuring-playbook-bridge-appservice-kakaotalk.md @@ -1,75 +1,26 @@ -# Setting up Appservice Kakaotalk bridging (optional) +# Setting up Appservice Kakaotalk bridging (optional, removed) -The playbook can install and configure [matrix-appservice-kakaotalk](https://src.miscworks.net/fair/matrix-appservice-kakaotalk) for you, for bridging to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG). This bridge is based on [node-kakao](https://github.com/storycraft/node-kakao) (now unmaintained) and some [mautrix-facebook](https://github.com/mautrix/facebook) code. +🪦 The playbook used to be able to install and configure [matrix-appservice-kakaotalk](https://src.miscworks.net/fair/matrix-appservice-kakaotalk) (a bridge to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG)), but no longer includes this component. -See the project's [documentation](https://src.miscworks.net/fair/matrix-appservice-kakaotalk/src/branch/master/README.md) to learn what it does and why it might be useful to you. +The bridge could only be installed by self-building its source code, and its upstream repository has become unreachable, which makes installation impossible. The bridge was also based on the now-unmaintained [node-kakao](https://github.com/storycraft/node-kakao) library, and there have been reports that using it may get your Kakaotalk account banned. -> [!WARNING] -> There have been recent reports (~2022-09-16) that **using this bridge may get your account banned**. +## Uninstalling the component manually -## Prerequisite (optional) +If you still have matrix-appservice-kakaotalk installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server: -### Enable Shared Secret Auth - -If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) for this playbook. - -See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting. - -**Note**: double puppeting with the Shared Secret Auth works at the time of writing, but is deprecated and will stop working in the future. - -## Adjusting the playbook configuration - -To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: - -```yaml -matrix_appservice_kakaotalk_enabled: true -``` - -### Extending the configuration - -There are some additional things you may wish to configure about the bridge. - -Take a look at: - -- `roles/custom/matrix-bridge-appservice-kakaotalk/defaults/main.yml` for some variables that you can customize via your `vars.yml` file -- `roles/custom/matrix-bridge-appservice-kakaotalk/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_appservice_kakaotalk_configuration_extension_yaml` variable - -## Installing - -After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below: - - ```sh -ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start -``` - -The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` - -`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. - -## Usage - -To use the bridge, you need to start a chat with `@kakaotalkbot:example.com` (where `example.com` is your base domain, not the `matrix.` domain). - -You then need to send `login --save EMAIL_OR_PHONE_NUMBER` to the bridge bot to enable bridging for your Kakaotalk account. The `--save` flag may be omitted, if you'd rather not save your password. - -## Troubleshooting - -As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-appservice-kakaotalk`. - -### Increase logging verbosity +systemctl disable --now matrix-appservice-kakaotalk.service -The default logging level for this component is `WARNING`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: +systemctl disable --now matrix-appservice-kakaotalk-node.service -```yaml -matrix_appservice_kakaotalk_logging_level: DEBUG +rm -rf /matrix/appservice-kakaotalk ``` diff --git a/docs/configuring-playbook-bridge-beeper-line.md b/docs/configuring-playbook-bridge-beeper-line.md new file mode 100644 index 000000000..a1ebf073e --- /dev/null +++ b/docs/configuring-playbook-bridge-beeper-line.md @@ -0,0 +1,101 @@ + + +# Setting up Beeper LINE bridging (optional) + +Refer to the common guide for configuring mautrix bridges: [Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md) + +The playbook can install and configure [beeper-line](https://github.com/beeper/line) for you, for bridging to [LINE](https://line.me/). + +See the project's [documentation](https://github.com/beeper/line/blob/main/README.md) to learn what it does and which features it supports. + +## Prerequisites + +### Prepare your LINE account + +The bridge logs in with the email address configured in your LINE account. If your account does not have an email address, set one in the LINE mobile app under **Settings** → **Account** → **Email address** before trying to log in. + +The bridge identifies itself to LINE as a Chrome Extension client. LINE only permits one active Chrome Extension session, so the bridge and the real LINE Chrome Extension cannot be used at the same time. Logging in with either one invalidates the other session. + +### Enable Appservice Double Puppet (optional) + +If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) for this playbook. + +See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the common mautrix bridge guide for details. + +## Adjusting the playbook configuration + +To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: + +```yaml +matrix_bridge_beeper_line_enabled: true +``` + +### Using another container image + +Upstream does not publish container images publicly, as its CI only pushes them to Beeper's private registry. The playbook therefore uses [`docker.io/crispyduck/beeper-line`](https://hub.docker.com/r/crispyduck/beeper-line) by default, which is a community-maintained image built from the upstream source. + +That image is only available for the amd64 architecture. On other architectures, the playbook self-builds the image from source automatically. + +To use an image that you have built and published elsewhere, override the complete image name: + +```yaml +matrix_bridge_beeper_line_container_image_self_build: false +matrix_bridge_beeper_line_container_image: docker.io/example/beeper-line:latest +``` + +The role can also build the bridge directly from a Git repository on the Matrix server: + +```yaml +matrix_bridge_beeper_line_container_image_self_build: true +matrix_bridge_beeper_line_container_image_self_build_repo: https://github.com/beeper/line.git +matrix_bridge_beeper_line_container_image_self_build_branch: main +``` + +Self-building requires more time and resources on the server than pulling a prebuilt image. + +### Extending the configuration + +There are additional things you may wish to configure about the bridge. + +See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the common mautrix bridge guide for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [relay mode](configuring-playbook-bridge-mautrix-bridges.md#enable-relay-mode-optional), and the [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional). + +When following the common guide, replace `_mautrix_SERVICENAME_` in variable names with `_beeper_line_`. + +## Installing + +After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below: + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + +The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`. + +`just install-all` is useful for maintaining your setup quickly when its components remain unchanged. If you adjust your `vars.yml` to remove other components, run `just setup-all` so those components are uninstalled. + +## Usage + +To use the bridge, start a chat with `@linebot:example.com` (where `example.com` is your base domain, not the `matrix.` domain). + +Send `login` and enter your LINE email address and password when prompted. The bridge then shows you a PIN code, which you need to enter into the LINE app on your mobile device to approve the new session. + +## Troubleshooting + +As with all other services, you can find the logs in systemd-journald by logging in to the server with SSH and running: + +```sh +journalctl -fu matrix-beeper-line +``` + +### Increase logging verbosity + +The default logging level for this component is `warn`. To increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: + +```yaml +# Valid values: fatal, error, warn, info, debug, trace +matrix_bridge_beeper_line_logging_level: debug +``` diff --git a/docs/configuring-playbook-bridge-beeper-linkedin.md b/docs/configuring-playbook-bridge-beeper-linkedin.md index 4016b0b37..c841b2f3f 100644 --- a/docs/configuring-playbook-bridge-beeper-linkedin.md +++ b/docs/configuring-playbook-bridge-beeper-linkedin.md @@ -8,7 +8,9 @@ SPDX-FileCopyrightText: 2024 - 2025 Suguru Hirahara SPDX-License-Identifier: AGPL-3.0-or-later --> -# Setting up Beeper Linkedin bridging (optional) +# Setting up Beeper Linkedin bridging (optional, unmaintained) + +**Note**: this bridge is unmaintained. Its [upstream repository](https://github.com/beeper/linkedin) has been archived and has not seen a change since March 2025. For bridging to LinkedIn, consider using the [mautrix-linkedin](configuring-playbook-bridge-mautrix-linkedin.md) bridge instead, which is actively maintained and also supported by the playbook. The playbook can install and configure [beeper-linkedin](https://github.com/beeper/linkedin) for you, for bridging to [LinkedIn](https://www.linkedin.com/) Messaging. This bridge is based on the mautrix-python framework and can be configured in a similar way to the mautrix bridges. @@ -29,7 +31,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_beeper_linkedin_enabled: true +matrix_bridge_beeper_linkedin_enabled: true ``` ### Extending the configuration @@ -68,7 +70,7 @@ As with all other services, you can find the logs in [systemd-journald](https:// The default logging level for this component is `WARNING`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: ```yaml -matrix_beeper_linkedin_logging_level: DEBUG +matrix_bridge_beeper_linkedin_logging_level: DEBUG ``` ### Bridge asking for 2FA even if you don't have 2FA enabled diff --git a/docs/configuring-playbook-bridge-heisenbridge.md b/docs/configuring-playbook-bridge-heisenbridge.md index 552a90635..746e03d57 100644 --- a/docs/configuring-playbook-bridge-heisenbridge.md +++ b/docs/configuring-playbook-bridge-heisenbridge.md @@ -25,26 +25,26 @@ If you wish to adjust it, see the section [below](#adjusting-the-heisenbridge-ur To enable Heisenbridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_heisenbridge_enabled: true +matrix_bridge_heisenbridge_enabled: true # Setting the owner is optional as the first local user to DM `@heisenbridge:example.com` will be made the owner. # If you are not using a local user you must set it as otherwise you can't DM it at all. -matrix_heisenbridge_owner: "@alice:{{ matrix_domain }}" +matrix_bridge_heisenbridge_owner: "@alice:{{ matrix_domain }}" # Uncomment to enable identd on host port 113/TCP (optional) -# matrix_heisenbridge_identd_enabled: true +# matrix_bridge_heisenbridge_identd_enabled: true ``` ### Adjusting the Heisenbridge URL (optional) -By tweaking the `matrix_heisenbridge_hostname` and `matrix_heisenbridge_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one. +By tweaking the `matrix_bridge_heisenbridge_hostname` and `matrix_bridge_heisenbridge_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one. Example additional configuration for your `vars.yml` file: ```yaml # Change the default hostname and path prefix -matrix_heisenbridge_hostname: heisenbridge.example.com -matrix_heisenbridge_path_prefix: / +matrix_bridge_heisenbridge_hostname: heisenbridge.example.com +matrix_bridge_heisenbridge_path_prefix: / ``` If you've changed the default hostname, you may need to create a CNAME record for the Heisenbridge domain (`heisenbridge.example.com`), which targets `matrix.example.com`. diff --git a/docs/configuring-playbook-bridge-hookshot.md b/docs/configuring-playbook-bridge-hookshot.md index 021558ddc..55c02f7f4 100644 --- a/docs/configuring-playbook-bridge-hookshot.md +++ b/docs/configuring-playbook-bridge-hookshot.md @@ -29,20 +29,23 @@ You need to download the private key file, if you will install the file manually Add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file. Make sure to replace `GITHUB_PRIVATE_KEY_HERE` with the one created [above](#download-github-app-private-key). ```yaml -matrix_hookshot_enabled: true +matrix_bridge_hookshot_enabled: true # Uncomment to enable end-to-bridge encryption. # See: https://matrix-org.github.io/matrix-hookshot/latest/advanced/encryption.html -# matrix_hookshot_encryption_enabled: true +# matrix_bridge_hookshot_encryption_enabled: true # Uncomment and paste the contents of GitHub app private key to enable GitHub bridge. # Alternatively, you can use one of the other methods explained below on the "Manage GitHub Private Key with aux role" section. -# matrix_hookshot_github_private_key: "GITHUB_PRIVATE_KEY_HERE" +# matrix_bridge_hookshot_github_private_key: "GITHUB_PRIVATE_KEY_HERE" ``` -For each of the services (GitHub, GitLab, Jira, Figma, and generic webhooks) fill in the respective variables `matrix_hookshot_service_*` listed in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml) as required. +> [!NOTE] +> End-to-bridge encryption requires the homeserver to support (and have enabled) [MSC2409](https://github.com/matrix-org/matrix-spec-proposals/pull/2409) and [MSC3202](https://github.com/matrix-org/matrix-spec-proposals/pull/3202). When using Synapse, the playbook turns on the experimental features this depends on (`msc2409_to_device_messages_enabled` and `msc3202_transaction_extensions`) for you. On other homeserver implementations, you need to arrange for this yourself. -Take special note of the `matrix_hookshot_*_enabled` variables. Services that need no further configuration are enabled by default (GitLab and generic webhooks), while you must first add the required configuration and enable the others (GitHub, Jira, and Figma). +For each of the services (GitHub, GitLab, Jira, Figma, and generic webhooks) fill in the respective variables `matrix_bridge_hookshot_service_*` listed in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml) as required. + +Take special note of the `matrix_bridge_hookshot_*_enabled` variables. Services that need no further configuration are enabled by default (GitLab and generic webhooks), while you must first add the required configuration and enable the others (GitHub, Jira, and Figma). ### Extending the configuration @@ -51,7 +54,7 @@ There are some additional things you may wish to configure about the bridge. Take a look at: - `roles/custom/matrix-bridge-hookshot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file -- `roles/custom/matrix-bridge-hookshot/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_hookshot_configuration_extension_yaml` and `matrix_hookshot_registration_extension_yaml` variables +- `roles/custom/matrix-bridge-hookshot/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_hookshot_configuration_extension_yaml` and `matrix_bridge_hookshot_registration_extension_yaml` variables Refer the [official instructions](https://matrix-org.github.io/matrix-hookshot/latest/setup.html) and the comments in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml) to learn what the individual options do. @@ -96,31 +99,31 @@ Unless indicated otherwise, the following endpoints are reachable on your `matri | Listener | Default path | Variable | Used as | |---|---|---|---| -| - | `/hookshot/webhooks/` | `matrix_hookshot_webhook_endpoint` | Webhook-prefix, which affects all webhook-related URLs below | -| generic | `/hookshot/webhooks/webhook` | `matrix_hookshot_generic_endpoint` | Generic webhooks | -| github oauth | `/hookshot/webhooks/oauth` | `matrix_hookshot_github_oauth_endpoint` | GitHub "Callback URL" | -| jira oauth | `/hookshot/webhooks/jira/oauth` | `matrix_hookshot_jira_oauth_endpoint` | Jira OAuth | -| figma endpoint | `/hookshot/webhooks/figma/webhook` | `matrix_hookshot_figma_endpoint` | Figma | -| appservice | `/hookshot/_matrix/app/` | `matrix_hookshot_appservice_endpoint` | Matrix server | -| widgets | `/hookshot/widgetapi/` | `matrix_hookshot_widgets_endpoint` | Widgets | +| - | `/hookshot/webhooks/` | `matrix_bridge_hookshot_webhook_endpoint` | Webhook-prefix, which affects all webhook-related URLs below | +| generic | `/hookshot/webhooks/webhook` | `matrix_bridge_hookshot_generic_endpoint` | Generic webhooks | +| github oauth | `/hookshot/webhooks/oauth` | `matrix_bridge_hookshot_github_oauth_endpoint` | GitHub "Callback URL" | +| jira oauth | `/hookshot/webhooks/jira/oauth` | `matrix_bridge_hookshot_jira_oauth_endpoint` | Jira OAuth | +| figma endpoint | `/hookshot/webhooks/figma/webhook` | `matrix_bridge_hookshot_figma_endpoint` | Figma | +| appservice | `/hookshot/_matrix/app/` | `matrix_bridge_hookshot_appservice_endpoint` | Matrix server | +| widgets | `/hookshot/widgetapi/` | `matrix_bridge_hookshot_widgets_endpoint` | Widgets | -Also see the various `matrix_hookshot_container_labels_*` variables in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml), which expose URLs publicly. +Also see the various `matrix_bridge_hookshot_container_labels_*` variables in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml), which expose URLs publicly. -The different listeners are also reachable *internally* in the docker-network via the container's name (configured by `matrix_hookshot_container_url`) and on different ports (e.g. `matrix_hookshot_appservice_port`). Read [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml) in detail for more info. +The different listeners are also reachable *internally* in the docker-network via the container's name (configured by `matrix_bridge_hookshot_container_url`) and on different ports (e.g. `matrix_bridge_hookshot_appservice_port`). Read [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml) in detail for more info. ### Manage GitHub Private Key with aux role The GitHub bridge requires you to install a private key file. This can be done in multiple ways: -- copy the *contents* of the downloaded file and set the variable `matrix_hookshot_github_private_key` to the contents (see example in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml)). -- somehow copy the file to the path `{{ matrix_hookshot_base_path }}/{{ matrix_hookshot_github_private_key_file }}` (default: `/matrix/hookshot/private-key.pem`) on the server manually. +- copy the *contents* of the downloaded file and set the variable `matrix_bridge_hookshot_github_private_key` to the contents (see example in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml)). +- somehow copy the file to the path `{{ matrix_bridge_hookshot_base_path }}/{{ matrix_bridge_hookshot_github_private_key_file }}` (default: `/matrix/hookshot/private-key.pem`) on the server manually. - use the [`aux` role](https://github.com/mother-of-all-self-hosting/ansible-role-aux) to copy the file from an arbitrary path on your ansible client to the correct path on the server. -To use the `aux` role, make sure the `matrix_hookshot_github_private_key` variable is empty. Then add the following configuration to your `vars.yml` file: +To use the `aux` role, make sure the `matrix_bridge_hookshot_github_private_key` variable is empty. Then add the following configuration to your `vars.yml` file: ```yaml aux_file_definitions: - - dest: "{{ matrix_hookshot_base_path }}/{{ matrix_hookshot_github_private_key_file }}" + - dest: "{{ matrix_bridge_hookshot_base_path }}/{{ matrix_bridge_hookshot_github_private_key_file }}" content: "{{ lookup('file', '/path/to/your-github-private-key.pem') }}" mode: '0400' owner: "{{ matrix_user_name }}" @@ -139,23 +142,23 @@ To enable the metrics, add the following configuration to your `vars.yml` file: ```yaml # Expose metrics (locally, on the container network). -matrix_hookshot_metrics_enabled: true +matrix_bridge_hookshot_metrics_enabled: true ``` **To collect metrics from an external Prometheus server**, besides enabling metrics as described above, you will also need to enable metrics exposure on `https://matrix.example.com/metrics/hookshot` by adding the following configuration to your `vars.yml` file: ```yaml -matrix_hookshot_metrics_proxying_enabled: true +matrix_bridge_hookshot_metrics_proxying_enabled: true ``` By default metrics are exposed publicly **without** password-protection. To password-protect the metrics with dedicated credentials, add the following configuration to your `vars.yml` file: ```yaml -matrix_hookshot_container_labels_metrics_middleware_basic_auth_enabled: true -matrix_hookshot_container_labels_metrics_middleware_basic_auth_users: '' +matrix_bridge_hookshot_container_labels_metrics_middleware_basic_auth_enabled: true +matrix_bridge_hookshot_container_labels_metrics_middleware_basic_auth_users: '' ``` -To `matrix_hookshot_container_labels_metrics_middleware_basic_auth_users`, set the Basic Authentication credentials (raw `htpasswd` file content) used to protect the endpoint. See https://doc.traefik.io/traefik/middlewares/http/basicauth/#users for details about it. +To `matrix_bridge_hookshot_container_labels_metrics_middleware_basic_auth_users`, set the Basic Authentication credentials (raw `htpasswd` file content) used to protect the endpoint. See https://doc.traefik.io/traefik/middlewares/http/basicauth/#users for details about it. **Note**: alternatively, you can use `matrix_metrics_exposure_enabled` to expose all services on this `/metrics/*` feature, and you can use `matrix_metrics_exposure_http_basic_auth_enabled` and `matrix_metrics_exposure_http_basic_auth_users` to password-protect the metrics of them. See [this section](configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) for more information. @@ -175,5 +178,5 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # Valid values: error, warn, info, debug -matrix_hookshot_logging_level: debug +matrix_bridge_hookshot_logging_level: debug ``` diff --git a/docs/configuring-playbook-bridge-matrix-bridge-sms.md b/docs/configuring-playbook-bridge-matrix-bridge-sms.md index f6c5482dc..c3d733dba 100644 --- a/docs/configuring-playbook-bridge-matrix-bridge-sms.md +++ b/docs/configuring-playbook-bridge-matrix-bridge-sms.md @@ -21,23 +21,23 @@ The bridge uses [android-sms-gateway-server](https://github.com/RebekkaMa/androi To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_sms_bridge_enabled: true +matrix_bridge_sms_enabled: true # (optional but recommended) a room ID to a default room -matrix_sms_bridge_default_room: "" +matrix_bridge_sms_default_room: "" # (optional but recommended) configure your server location -matrix_sms_bridge_default_region: DE -matrix_sms_bridge_default_timezone: Europe/Berlin +matrix_bridge_sms_default_region: DE +matrix_bridge_sms_default_timezone: Europe/Berlin # Settings to connect to android-sms-gateway-server -matrix_sms_bridge_provider_android_baseurl: https://192.168.24.24:9090 -matrix_sms_bridge_provider_android_username: admin -matrix_sms_bridge_provider_android_password: supeSecretPassword +matrix_bridge_sms_provider_android_baseurl: https://192.168.24.24:9090 +matrix_bridge_sms_provider_android_username: admin +matrix_bridge_sms_provider_android_password: supeSecretPassword # (optional) if your android-sms-gateway-server uses a self signed vertificate, the bridge needs a "truststore". This can be the certificate itself. -matrix_sms_bridge_provider_android_truststore_local_path: android-sms-gateway-server.p12 -matrix_sms_bridge_provider_android_truststore_password: 123 +matrix_bridge_sms_provider_android_truststore_local_path: android-sms-gateway-server.p12 +matrix_bridge_sms_provider_android_truststore_password: 123 ``` ### Extending the configuration @@ -46,7 +46,7 @@ There are some additional things you may wish to configure about the bridge. Take a look at: -- `roles/custom/matrix-bridge-sms/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_sms_bridge_configuration_extension_yaml` variable +- `roles/custom/matrix-bridge-sms/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_sms_configuration_extension_yaml` variable ## Installing diff --git a/docs/configuring-playbook-bridge-mautrix-bluesky.md b/docs/configuring-playbook-bridge-mautrix-bluesky.md index 3a9c07303..db5d32de0 100644 --- a/docs/configuring-playbook-bridge-mautrix-bluesky.md +++ b/docs/configuring-playbook-bridge-mautrix-bluesky.md @@ -27,7 +27,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_bluesky_enabled: true +matrix_bridge_mautrix_bluesky_enabled: true ``` ### Extending the configuration @@ -70,5 +70,5 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_bluesky_logging_level: 'debug' +matrix_bridge_mautrix_bluesky_logging_level: 'debug' ``` diff --git a/docs/configuring-playbook-bridge-mautrix-bridges.md b/docs/configuring-playbook-bridge-mautrix-bridges.md index 26ea8f778..efcbc1647 100644 --- a/docs/configuring-playbook-bridge-mautrix-bridges.md +++ b/docs/configuring-playbook-bridge-mautrix-bridges.md @@ -21,12 +21,12 @@ To enable the bridge, add the following configuration to your `inventory/host_va ```yaml # Replace SERVICENAME with one of: twitter, discord, signal, googlechat, etc. -matrix_mautrix_SERVICENAME_enabled: true +matrix_bridge_mautrix_SERVICENAME_enabled: true ``` -**Note**: for bridging to Meta's Messenger or Instagram, you would need to add `meta` with an underscore symbol (`_`) or hyphen (`-`) based on the context as prefix to each `SERVICENAME`; add `_` to variables (as in `matrix_mautrix_meta_messenger_configuration_extension_yaml` for example) and `-` to paths of the configuration files (as in `roles/custom/matrix-bridge-mautrix-meta-messenger/templates/config.yaml.j2`), respectively. +**Note**: for bridging to Meta's Messenger or Instagram, you would need to add `meta` with an underscore symbol (`_`) or hyphen (`-`) based on the context as prefix to each `SERVICENAME`; add `_` to variables (as in `matrix_bridge_mautrix_meta_messenger_configuration_extension_yaml` for example) and `-` to paths of the configuration files (as in `roles/custom/matrix-bridge-mautrix-meta-messenger/templates/config.yaml.j2`), respectively. -There are some additional things you may wish to configure about the bridge before you continue. Each bridge may have additional requirements besides `_enabled: true`. For example, the mautrix-telegram bridge (our documentation page about it is [here](configuring-playbook-bridge-mautrix-telegram.md)) requires the `matrix_mautrix_telegram_api_id` and `matrix_mautrix_telegram_api_hash` variables to be defined. Refer to each bridge's individual documentation page for details about enabling bridges. +There are some additional things you may wish to configure about the bridge before you continue. Each bridge may have additional requirements besides `_enabled: true`. For example, the mautrix-telegram bridge (our documentation page about it is [here](configuring-playbook-bridge-mautrix-telegram.md)) requires the `matrix_bridge_mautrix_telegram_api_id` and `matrix_bridge_mautrix_telegram_api_hash` variables to be defined. Refer to each bridge's individual documentation page for details about enabling bridges. ### Configure bridge permissions (optional) @@ -43,7 +43,7 @@ If you don't define the `matrix_admin` in your configuration (e.g. `matrix_admin **Alternatively** (more verbose, but allows multiple admins to be configured), you can do the same on a per-bridge basis with: ```yaml -matrix_mautrix_SERVICENAME_configuration_extension_yaml: | +matrix_bridge_mautrix_SERVICENAME_configuration_extension_yaml: | bridge: permissions: '@alice:{{ matrix_domain }}': admin @@ -67,8 +67,8 @@ matrix_bridges_encryption_default: true **Alternatively**, for a specific bridge: ```yaml -matrix_mautrix_SERVICENAME_bridge_encryption_enabled: true -matrix_mautrix_SERVICENAME_bridge_encryption_default: true +matrix_bridge_mautrix_SERVICENAME_bridge_encryption_enabled: true +matrix_bridge_mautrix_SERVICENAME_bridge_encryption_default: true ``` ### Enable relay mode (optional) @@ -86,16 +86,16 @@ matrix_bridges_relay_enabled: true **Alternatively**, for a specific bridge: ```yaml -matrix_mautrix_SERVICENAME_configuration_extension_yaml: | +matrix_bridge_mautrix_SERVICENAME_configuration_extension_yaml: | bridge: relay: enabled: true ``` -You can only have one `matrix_mautrix_SERVICENAME_configuration_extension_yaml` definition in `vars.yml` per bridge, so if you need multiple pieces of configuration there, just merge them like this: +You can only have one `matrix_bridge_mautrix_SERVICENAME_configuration_extension_yaml` definition in `vars.yml` per bridge, so if you need multiple pieces of configuration there, just merge them like this: ```yaml -matrix_mautrix_SERVICENAME_configuration_extension_yaml: | +matrix_bridge_mautrix_SERVICENAME_configuration_extension_yaml: | bridge: relay: enabled: true @@ -115,7 +115,7 @@ Use `!prefix set-pl 100` to be able for the bot to modify room settings and invi By default, only admins are allowed to set themselves as relay users. To allow anyone on your homeserver to set themselves as relay users, add the following configuration to your `vars.yml` file: ```yaml -matrix_mautrix_SERVICENAME_bridge_relay_admin_only: false +matrix_bridge_mautrix_SERVICENAME_bridge_relay_admin_only: false ``` ### Set the bot's username (optional) @@ -123,7 +123,7 @@ matrix_mautrix_SERVICENAME_bridge_relay_admin_only: false To set the bot's username, add the following configuration to your `vars.yml` file: ```yaml -matrix_mautrix_SERVICENAME_appservice_bot_username: "BOTNAME" +matrix_bridge_mautrix_SERVICENAME_appservice_bot_username: "BOTNAME" ``` ### Configure the logging level (optional) @@ -131,13 +131,42 @@ matrix_mautrix_SERVICENAME_appservice_bot_username: "BOTNAME" To specify the logging level, add the following configuration to your `vars.yml` file: ```yaml -matrix_mautrix_SERVICENAME_logging_level: warn +matrix_bridge_mautrix_SERVICENAME_logging_level: warn ``` Replace `warn` with one of the following to control the verbosity of the logs generated: `trace`, `debug`, `info`, `warn`, `error` or `fatal`. If you have issues with a service, and are requesting support, the higher levels of logging (those that appear earlier in the list, like `trace`) will generally be more helpful. +### Expose the bridge's API (for Mautrix Manager and similar tools) + +Each mautrix bridge runs an HTTP API which tools like [Mautrix Manager](https://github.com/mautrix/manager) can use to help you log into the bridge. This is especially handy for bridges where logging in manually is cumbersome (like [mautrix-gmessages](configuring-playbook-bridge-mautrix-gmessages.md)). + +By default, the playbook exposes this API publicly at `https://matrix.example.com/bridges/SERVICENAME` (for example, `https://matrix.example.com/bridges/gmessages`). Such tools authenticate to the bridge with your own Matrix access token, so you never need to share any bridge secret with them. + +To make discovery easier, the playbook also serves a `/.well-known/matrix/mautrix` file which advertises all your exposed bridges. Mautrix Manager reads this file and offers your bridges automatically, so you don't need to enter their URLs by hand. + +This is all enabled by default. To **disable exposing the API for all bridges**, add the following configuration to your `vars.yml` file: + +```yaml +matrix_bridges_exposure_enabled: false +``` + +**Alternatively**, to disable it for a specific bridge: + +```yaml +matrix_bridge_mautrix_SERVICENAME_exposure_enabled: false +``` + +If you run additional bridges on the same server which are not managed by this playbook and would like compatible tools to discover them as well, you can advertise their base URLs in the `/.well-known/matrix/mautrix` file: + +```yaml +matrix_static_files_file_matrix_mautrix_property_fi_mau_bridges_custom: + - https://matrix.example.com/bridges/SOME_OTHER_BRIDGE +``` + +Only list bridges hosted on (and connected to) this server here, as compatible tools will send your Matrix access token to them. For bridges on other servers, take a look at the `fi.mau.external_bridge_servers` property described in the [Mautrix Manager](https://github.com/mautrix/manager) documentation, which you can add via `matrix_static_files_file_matrix_mautrix_configuration_extension_json`. + ### Extending the configuration There are some additional things you may wish to configure about the bridge. @@ -145,7 +174,7 @@ There are some additional things you may wish to configure about the bridge. Take a look at: - `roles/custom/matrix-bridge-mautrix-SERVICENAME/defaults/main.yml` for some variables that you can customize via your `vars.yml` file -- `roles/custom/matrix-bridge-mautrix-SERVICENAME/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_mautrix_SERVICENAME_configuration_extension_yaml` variable +- `roles/custom/matrix-bridge-mautrix-SERVICENAME/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_mautrix_SERVICENAME_configuration_extension_yaml` variable ## Installing @@ -197,7 +226,7 @@ This is the recommended way of setting up Double Puppeting, as it's easier to ac - Previously there were multiple different automatic double puppeting methods like one with the help of the [Shared Secret Auth password provider module](./configuring-playbook-shared-secret-auth.md), but they have been superseded by this Appservice Double Puppet method. Double puppeting with the Shared Secret Auth works at the time of writing, but is deprecated and will stop working in the future as the older methods were completely removed in the megabridge rewrites on [the upstream project](https://docs.mau.fi/bridges/general/double-puppeting.html#automatically). -- Some bridges like [the deprecated Facebook mautrix bridge](configuring-playbook-bridge-mautrix-facebook.md) and [matrix-appservice-kakaotalk](configuring-playbook-bridge-appservice-kakaotalk.md), which is partially based on the Facebook bridge, are compatible with the Shared Secret Auth service only. These bridges automatically perform Double Puppeting if [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) service is configured and enabled on the server for this playbook. +- Some bridges like [the deprecated Facebook mautrix bridge](configuring-playbook-bridge-mautrix-facebook.md) are compatible with the Shared Secret Auth service only. These bridges automatically perform Double Puppeting if [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) service is configured and enabled on the server for this playbook. #### Method 2: manually, by asking each user to provide a working access token diff --git a/docs/configuring-playbook-bridge-mautrix-discord.md b/docs/configuring-playbook-bridge-mautrix-discord.md index cb903d953..74e597bb7 100644 --- a/docs/configuring-playbook-bridge-mautrix-discord.md +++ b/docs/configuring-playbook-bridge-mautrix-discord.md @@ -39,7 +39,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_discord_enabled: true +matrix_bridge_mautrix_discord_enabled: true ``` ### Extending the configuration @@ -96,7 +96,7 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_discord_logging_level: 'debug' +matrix_bridge_mautrix_discord_logging_level: 'debug' ``` ### Command requires room admin rights when user is creator diff --git a/docs/configuring-playbook-bridge-mautrix-gmessages.md b/docs/configuring-playbook-bridge-mautrix-gmessages.md index 98cf5a53c..aeed96ce9 100644 --- a/docs/configuring-playbook-bridge-mautrix-gmessages.md +++ b/docs/configuring-playbook-bridge-mautrix-gmessages.md @@ -27,7 +27,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_gmessages_enabled: true +matrix_bridge_mautrix_gmessages_enabled: true ``` ### Extending the configuration @@ -68,5 +68,5 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_gmessages_logging_level: 'debug' +matrix_bridge_mautrix_gmessages_logging_level: 'debug' ``` diff --git a/docs/configuring-playbook-bridge-mautrix-googlechat.md b/docs/configuring-playbook-bridge-mautrix-googlechat.md index cc0f58e22..00f192073 100644 --- a/docs/configuring-playbook-bridge-mautrix-googlechat.md +++ b/docs/configuring-playbook-bridge-mautrix-googlechat.md @@ -30,7 +30,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the [Google Chat](https://chat.google.com/) bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_googlechat_enabled: true +matrix_bridge_mautrix_googlechat_enabled: true ``` ### Extending the configuration @@ -70,5 +70,5 @@ As with all other services, you can find the logs in [systemd-journald](https:// The default logging level for this component is `WARNING`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: ```yaml -matrix_mautrix_googlechat_logging_level: DEBUG +matrix_bridge_mautrix_googlechat_logging_level: DEBUG ``` diff --git a/docs/configuring-playbook-bridge-mautrix-gvoice.md b/docs/configuring-playbook-bridge-mautrix-gvoice.md new file mode 100644 index 000000000..7855e8015 --- /dev/null +++ b/docs/configuring-playbook-bridge-mautrix-gvoice.md @@ -0,0 +1,73 @@ + + +# Setting up Mautrix Google Voice bridging (optional) + +Refer the common guide for configuring mautrix bridges: [Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md) + +The playbook can install and configure [mautrix-gvoice](https://github.com/mautrix/gvoice) for you, for bridging to [Google Voice](https://voice.google.com/). + +See the project's [documentation](https://docs.mau.fi/bridges/go/gvoice/index.html) to learn what it does and why it might be useful to you. + +## Prerequisite (optional) + +### Enable Appservice Double Puppet + +If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) for this playbook. + +See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting. + +## Adjusting the playbook configuration + +To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: + +```yaml +matrix_bridge_mautrix_gvoice_enabled: true +``` + +### Extending the configuration + +There are some additional things you may wish to configure about the bridge. + + +See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc. + +## Installing + +After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below: + + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + +The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` + +`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. + +## Usage + +To use the bridge, start a chat with `@gvoicebot:example.com` (where `example.com` is your base domain, not the `matrix.` domain). + +Google Voice has no phone to pair and no QR code to scan. It logs in with cookies, which you copy from a browser already signed in to [voice.google.com](https://voice.google.com/) and hand to the bot. It is fiddlier than scanning a code and feels more suspicious than it is, but Google leaves no cleaner door open. The bridge's [official Authentication guide](https://docs.mau.fi/bridges/go/gvoice/authentication.html) has the exact cookies to grab and the steps for grabbing them. + +Those cookies are a login session, and Google expires them on its own schedule. When they lapse the bridge goes quiet and you log in again. Nothing is broken, that is just how cookie auth ages. + +Once you log in, the bridge builds portal rooms for your recent conversations and carries text and media both ways. Don't reach for it to start a brand-new chat or to place a call, though. That ground still belongs to Google Voice, so keep the app around for those. + +## Troubleshooting + +As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-mautrix-gvoice`. + +### Increase logging verbosity + +The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: + +```yaml +# Valid values: fatal, error, warn, info, debug, trace +matrix_bridge_mautrix_gvoice_logging_level: 'debug' +``` diff --git a/docs/configuring-playbook-bridge-mautrix-linkedin.md b/docs/configuring-playbook-bridge-mautrix-linkedin.md new file mode 100644 index 000000000..d88fdd9bb --- /dev/null +++ b/docs/configuring-playbook-bridge-mautrix-linkedin.md @@ -0,0 +1,112 @@ + + +# Setting up Mautrix LinkedIn bridging (optional) + +Refer the common guide for configuring mautrix bridges: [Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md) + +The playbook can install and configure [mautrix-linkedin](https://github.com/mautrix/linkedin) for you, for bridging to [LinkedIn](https://www.linkedin.com/) messaging. + +See the project's [documentation](https://docs.mau.fi/bridges/go/linkedin/index.html) to learn what it does and why it might be useful to you. + +>[!NOTE] +> LinkedIn keeps its messaging function behind a login wall and does not provide a usable public API, so using this bridge requires you to manually copy cookies on a web browser for logging in. Refer to [this section](#usage) below for details. + +## Prerequisite + +### Uninstalling `beeper-linkedin` + +If `beeper-linkedin` bridge is enabled on your host, you need to uninstall it first, since it claims the `@linkedinbot` username and `@linkedin_*` user range as exclusive appservice namespaces, which will cause conflicts with `mautrix-linkedin`. + +To uninstall the bridge, set `matrix_bridge_beeper_linkedin_enabled: false` and re-run the playbook. The playbook refuses to install `mautrix-linkedin` until `beeper-linkedin` is uninstalled. + +### Enable Appservice Double Puppet (optional) + +If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) for this playbook. + +See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting. + +## Adjusting the playbook configuration + +To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: + +```yaml +matrix_bridge_mautrix_linkedin_enabled: true +``` + +### Extending the configuration + +There are some additional things you may wish to configure about the bridge. + + +See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc. + +## Installing + +After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below: + + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + +The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` + +`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. + +## Usage + +Start a chat with `@linkedinbot:example.com` (where `example.com` is your base domain, the bare one without the `matrix.` prefix) and send `login`. + +### Logging in + +To log in, you need to sign in to LinkedIn with a web browser and hand one of the requests it makes to the bot. Because the bridge presents itself as Chrome on Linux, the request needs to come from **Chrome or a Chrome-based browser**. + +>[!WARNING] +> LinkedIn ties the session to the browser that made the request and rejects it when it is replayed under a different user-agent. A request copied from Firefox therefore results in a session that stops working immediately, without an error message. + +You need to follow these steps to log in: + +1. Open [linkedin.com](https://www.linkedin.com/) in a private/incognito window on Chrome / a Chrome-based browser +2. Sign in to LinkedIn +3. Open your browser's devtools (F12) and go to the Network tab +4. Filter for `graphql` +5. Right-click any one of those requests, then "Copy" and "Copy as cURL" +6. Paste the output into the chat with the bot and send it + +The bridge's [official Authentication guide](https://docs.mau.fi/bridges/go/linkedin/authentication.html) walks the same steps with screenshots. + +Once you log in, the bridge builds portal rooms for your recent conversations and carries messages both ways. + +**💡 Notes:** + +- The request contains a login session, which LinkedIn may expire at any time. When the bridge goes quiet, log in again by following the steps above. +- If you would rather not retrieve the request yourself, you may wish to take a look at [mautrix-manager](https://github.com/mautrix/manager). + +## Troubleshooting + +### The bot does not respond after you send it the cURL output + +This most likely means that you have obtained the request with a browser other than Chrome or a Chrome-based one. LinkedIn silently discards a session replayed under a different user-agent. Follow the login steps above again, this time using Chrome or a Chrome-based browser. + +### The bridge worked before, but has gone quiet + +Your LinkedIn session has most likely expired. Send `login` to the bot and follow the login steps above again. + +### Other issues + +As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-mautrix-linkedin`. + +### Increase logging verbosity + +The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: + +```yaml +# Valid values: fatal, error, warn, info, debug, trace +matrix_bridge_mautrix_linkedin_logging_level: 'debug' +``` diff --git a/docs/configuring-playbook-bridge-mautrix-meta-instagram.md b/docs/configuring-playbook-bridge-mautrix-meta-instagram.md index a9a77fa44..6784fb2b9 100644 --- a/docs/configuring-playbook-bridge-mautrix-meta-instagram.md +++ b/docs/configuring-playbook-bridge-mautrix-meta-instagram.md @@ -13,7 +13,7 @@ The playbook can install and configure the [mautrix-meta](https://github.com/mau See the project's [documentation](https://docs.mau.fi/bridges/go/meta/index.html) to learn what it does and why it might be useful to you. -Since this bridge component can bridge to both [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/) and you may wish to do both at the same time, the playbook makes it available via 2 different Ansible roles (`matrix-bridge-mautrix-meta-messenger` and `matrix-bridge-mautrix-meta-instagram`). The latter is a reconfigured copy of the first one (created by `just rebuild-mautrix-meta-instagram` and `bin/rebuild-mautrix-meta-instagram.sh`). +The mautrix-meta project provides bridging to both [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/), each via a separate bridge (its own binary and container image) since mautrix-meta v26.07. The playbook makes them available via 2 different Ansible roles (`matrix-bridge-mautrix-meta-messenger` and `matrix-bridge-mautrix-meta-instagram`), which can both be enabled at the same time. This documentation page only deals with the bridge's ability to bridge to Instagram. For bridging to Facebook/Messenger, see [Setting up Messenger bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-messenger.md). @@ -23,7 +23,7 @@ This documentation page only deals with the bridge's ability to bridge to Instag If you've been using the [mautrix-instagram](./configuring-playbook-bridge-mautrix-instagram.md) bridge, **you'd better get rid of it first** or the 2 bridges will be in conflict: -- both trying to use `@instagrambot:example.com` as their username. This conflict may be resolved by adjusting `matrix_mautrix_instagram_appservice_bot_username` or `matrix_mautrix_meta_instagram_appservice_username` +- both trying to use `@instagrambot:example.com` as their username. This conflict may be resolved by adjusting `matrix_mautrix_instagram_appservice_bot_username` or `matrix_bridge_mautrix_meta_instagram_appservice_username` - both trying to bridge the same DMs To do so, send a `clean-rooms` command to the management room with the old bridge bot (`@instagrambot:example.com`). It gives you a list of portals and groups of portals you may purge. Proceed with sending commands like `clean recommended`, etc. @@ -41,7 +41,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_meta_instagram_enabled: true +matrix_bridge_mautrix_meta_instagram_enabled: true ``` Before proceeding to [re-running the playbook](./installing.md), you may wish to adjust the configuration further. See below. @@ -83,5 +83,5 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # This bridge uses zerolog, so valid levels are: panic, fatal, error, warn, info, debug, trace -matrix_mautrix_meta_instagram_logging_min_level: debug +matrix_bridge_mautrix_meta_instagram_logging_min_level: debug ``` diff --git a/docs/configuring-playbook-bridge-mautrix-meta-messenger.md b/docs/configuring-playbook-bridge-mautrix-meta-messenger.md index 9c0064cd1..8cb289778 100644 --- a/docs/configuring-playbook-bridge-mautrix-meta-messenger.md +++ b/docs/configuring-playbook-bridge-mautrix-meta-messenger.md @@ -14,7 +14,7 @@ The playbook can install and configure the [mautrix-meta](https://github.com/mau See the project's [documentation](https://docs.mau.fi/bridges/go/meta/index.html) to learn what it does and why it might be useful to you. -Since this bridge component can bridge to both [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/) and you may wish to do both at the same time, the playbook makes it available via 2 different Ansible roles (`matrix-bridge-mautrix-meta-messenger` and `matrix-bridge-mautrix-meta-instagram`). The latter is a reconfigured copy of the first one (created by `just rebuild-mautrix-meta-instagram` and `bin/rebuild-mautrix-meta-instagram.sh`). +The mautrix-meta project provides bridging to both [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/), each via a separate bridge (its own binary and container image) since mautrix-meta v26.07. The playbook makes them available via 2 different Ansible roles (`matrix-bridge-mautrix-meta-messenger` and `matrix-bridge-mautrix-meta-instagram`), which can both be enabled at the same time. This documentation page only deals with the bridge's ability to bridge to Facebook Messenger. For bridging to Instagram, see [Setting up Instagram bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-instagram.md). @@ -41,7 +41,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_meta_messenger_enabled: true +matrix_bridge_mautrix_meta_messenger_enabled: true ``` Before proceeding to [re-running the playbook](./installing.md), you may wish to adjust the configuration further. See below. @@ -56,7 +56,7 @@ The bridge can pull your Messenger messages via 3 different methods: - (`facebook-tor`) Facebook via `facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion` ([Tor](https://www.torproject.org/)) — does not currently proxy media downloads - (default) (`messenger`) Messenger via `messenger.com` — usable even without a Facebook account -You may switch the mode via the `matrix_mautrix_meta_messenger_meta_mode` variable. The playbook defaults to the `messenger` mode, because it's most universal (every Facebook user has a Messenger account, but the opposite is not true). +You may switch the mode via the `matrix_bridge_mautrix_meta_messenger_meta_mode` variable. The playbook defaults to the `messenger` mode, because it's most universal (every Facebook user has a Messenger account, but the opposite is not true). Note that switching the mode (especially between `facebook*` and `messenger`) will intentionally make the bridge use another database (`matrix_mautrix_meta_facebook` or `matrix_mautrix_meta_messenger`) to isolate the 2 instances. Switching between Tor and non-Tor may be possible without dataloss, but your mileage may vary. Before switching to a new mode, you may wish to de-configure the old one (send `help` to the bridge bot and unbridge your portals, etc.). @@ -99,5 +99,5 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # This bridge uses zerolog, so valid levels are: panic, fatal, error, warn, info, debug, trace -matrix_mautrix_meta_messenger_logging_min_level: debug +matrix_bridge_mautrix_meta_messenger_logging_min_level: debug ``` diff --git a/docs/configuring-playbook-bridge-mautrix-signal.md b/docs/configuring-playbook-bridge-mautrix-signal.md index 1fb0e2c6d..9d3bdfd20 100644 --- a/docs/configuring-playbook-bridge-mautrix-signal.md +++ b/docs/configuring-playbook-bridge-mautrix-signal.md @@ -28,7 +28,7 @@ See the project's [documentation](https://docs.mau.fi/bridges/go/signal/index.ht If you're running with the Postgres database server integrated by the playbook (which is the default), you don't need to do anything special and can easily proceed with installing. -However, if you're [using an external Postgres server](configuring-playbook-external-postgres.md), you'd need to manually prepare a Postgres database for this bridge and adjust the variables related to that (`matrix_mautrix_signal_database_*`). +However, if you're [using an external Postgres server](configuring-playbook-external-postgres.md), you'd need to manually prepare a Postgres database for this bridge and adjust the variables related to that (`matrix_bridge_mautrix_signal_database_*`). ### Enable Appservice Double Puppet @@ -41,7 +41,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_signal_enabled: true +matrix_bridge_mautrix_signal_enabled: true ``` ### Extending the configuration @@ -83,5 +83,5 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_signal_logging_level: 'debug' +matrix_bridge_mautrix_signal_logging_level: 'debug' ``` diff --git a/docs/configuring-playbook-bridge-mautrix-slack.md b/docs/configuring-playbook-bridge-mautrix-slack.md index 41197b542..ca91c7c7f 100644 --- a/docs/configuring-playbook-bridge-mautrix-slack.md +++ b/docs/configuring-playbook-bridge-mautrix-slack.md @@ -34,7 +34,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_slack_enabled: true +matrix_bridge_mautrix_slack_enabled: true ``` ### Extending the configuration @@ -74,5 +74,5 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_slack_logging_level: 'debug' +matrix_bridge_mautrix_slack_logging_level: 'debug' ``` diff --git a/docs/configuring-playbook-bridge-mautrix-telegram.md b/docs/configuring-playbook-bridge-mautrix-telegram.md index 5f089d3a4..f7c2eb925 100644 --- a/docs/configuring-playbook-bridge-mautrix-telegram.md +++ b/docs/configuring-playbook-bridge-mautrix-telegram.md @@ -1,5 +1,5 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc. ## Installing @@ -99,9 +72,9 @@ The shortcut commands with the [`just` program](just.md) are also available: `ju To use the bridge, you need to start a chat with `@telegrambot:example.com` (where `example.com` is your base domain, not the `matrix.` domain). -You can then follow instructions on the bridge's [official documentation on Authentication](https://docs.mau.fi/bridges/python/telegram/authentication.html). +You can then follow instructions on the bridge's [official documentation on Authentication](https://docs.mau.fi/bridges/go/telegram/authentication.html). -After logging in, the bridge will create portal rooms for all of your Telegram groups and invite you to them. Note that the bridge won't automatically create rooms for private chats. +After logging in, the bridge will create portal rooms for all of your Telegram groups and invite you to them. ## Troubleshooting @@ -109,8 +82,9 @@ As with all other services, you can find the logs in [systemd-journald](https:// ### Increase logging verbosity -The default logging level for this component is `WARNING`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: +The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: ```yaml -matrix_mautrix_telegram_logging_level: DEBUG +# Valid values: fatal, error, warn, info, debug, trace +matrix_bridge_mautrix_telegram_logging_level: debug ``` diff --git a/docs/configuring-playbook-bridge-mautrix-twitter.md b/docs/configuring-playbook-bridge-mautrix-twitter.md index 1a51dfbd6..25778ec39 100644 --- a/docs/configuring-playbook-bridge-mautrix-twitter.md +++ b/docs/configuring-playbook-bridge-mautrix-twitter.md @@ -28,7 +28,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_twitter_enabled: true +matrix_bridge_mautrix_twitter_enabled: true ``` ### Extending the configuration @@ -69,5 +69,5 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_twitter_logging_level: 'debug' +matrix_bridge_mautrix_twitter_logging_level: 'debug' ``` diff --git a/docs/configuring-playbook-bridge-mautrix-whatsapp.md b/docs/configuring-playbook-bridge-mautrix-whatsapp.md index 6e42c1d96..62549e9f7 100644 --- a/docs/configuring-playbook-bridge-mautrix-whatsapp.md +++ b/docs/configuring-playbook-bridge-mautrix-whatsapp.md @@ -34,7 +34,7 @@ See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double- To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_whatsapp_enabled: true +matrix_bridge_mautrix_whatsapp_enabled: true ``` ### Extending the configuration @@ -76,5 +76,5 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_whatsapp_logging_level: 'debug' +matrix_bridge_mautrix_whatsapp_logging_level: 'debug' ``` diff --git a/docs/configuring-playbook-bridge-mautrix-wsproxy.md b/docs/configuring-playbook-bridge-mautrix-wsproxy.md index a0d95d68b..1319aa934 100644 --- a/docs/configuring-playbook-bridge-mautrix-wsproxy.md +++ b/docs/configuring-playbook-bridge-mautrix-wsproxy.md @@ -25,26 +25,26 @@ When setting, replace `example.com` with your own. To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mautrix_wsproxy_enabled: true +matrix_bridge_mautrix_wsproxy_enabled: true -matrix_mautrix_androidsms_appservice_token: 'secret token from bridge' -matrix_mautrix_androidsms_homeserver_token: 'secret token from bridge' -matrix_mautrix_imessage_appservice_token: 'secret token from bridge' -matrix_mautrix_imessage_homeserver_token: 'secret token from bridge' -matrix_mautrix_wsproxy_syncproxy_shared_secret: 'secret token from bridge' +matrix_bridge_mautrix_wsproxy_androidsms_appservice_token: 'secret token from bridge' +matrix_bridge_mautrix_wsproxy_androidsms_homeserver_token: 'secret token from bridge' +matrix_bridge_mautrix_wsproxy_imessage_appservice_token: 'secret token from bridge' +matrix_bridge_mautrix_wsproxy_imessage_homeserver_token: 'secret token from bridge' +matrix_bridge_mautrix_wsproxy_syncproxy_shared_secret: 'secret token from bridge' ``` Note that the tokens must match what is compiled into the [mautrix-imessage](https://github.com/mautrix/imessage) bridge running on your Mac or Android device. ### Adjusting the wsproxy URL (optional) -By tweaking the `matrix_mautrix_wsproxy_hostname` variable, you can easily make the service available at a **different hostname** than the default one. +By tweaking the `matrix_bridge_mautrix_wsproxy_hostname` variable, you can easily make the service available at a **different hostname** than the default one. Example additional configuration for your `vars.yml` file: ```yaml # Change the default hostname -matrix_mautrix_wsproxy_hostname: ws.example.com +matrix_bridge_mautrix_wsproxy_hostname: ws.example.com ``` After changing the domain, **you may need to adjust your DNS** records to point the wsproxy domain to the Matrix server. diff --git a/docs/configuring-playbook-bridge-meshtastic-relay.md b/docs/configuring-playbook-bridge-meshtastic-relay.md new file mode 100644 index 000000000..7fa37376e --- /dev/null +++ b/docs/configuring-playbook-bridge-meshtastic-relay.md @@ -0,0 +1,95 @@ + + +# Setting up a Matrix <-> Meshtastic bridge (optional) + +The playbook can install and configure [meshtastic-matrix-relay](https://github.com/jeremiah-k/meshtastic-matrix-relay) (sometimes referred to as `mmrelay`) for you — a bridge between [Matrix](https://matrix.org/) and [Meshtastic](https://meshtastic.org/) mesh networks. + +See the [project's documentation](https://github.com/jeremiah-k/meshtastic-matrix-relay) to learn what it does and why it might be useful to you. + +## Prerequisites + +You need a Matrix account for the bot. You can either [register the bot account manually](registering-users.md) or let the playbook create it when running `ansible-playbook … --tags=ensure-matrix-users-created`. Either way, you'll need the account's **password** to configure the bridge — unlike most other bridges in this playbook, `mmrelay` authenticates with a password and creates its own session (optionally with End-to-End Encryption material). + +You also need access to a Meshtastic device, connected to the server via one of: + +- **TCP**: the device is reachable on the network (e.g. a Meshtastic node running the TCP API), +- **Serial**: the device is plugged in via USB and available on the host (e.g. `/dev/ttyUSB0`), +- **BLE**: the device is reachable via Bluetooth Low Energy from the host. + +## Adjusting the playbook configuration + +To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: + +```yaml +matrix_bridge_meshtastic_relay_enabled: true + +# Password for the bot's Matrix account. +# On first startup, the bridge uses this to log in and persist credentials +# (including End-to-End Encryption material) under its data directory. +# After that, the password can be removed from this variable. +matrix_bridge_meshtastic_relay_matrix_bot_password: "PASSWORD_FOR_THE_BOT" + +# How the bridge connects to your Meshtastic device. +# One of: tcp, serial, ble +matrix_bridge_meshtastic_relay_connection_type: tcp + +# For connection_type: tcp +matrix_bridge_meshtastic_relay_tcp_host: "meshtastic.local" + +# For connection_type: serial +# matrix_bridge_meshtastic_relay_serial_port: "/dev/ttyUSB0" + +# For connection_type: ble +# matrix_bridge_meshtastic_relay_ble_address: "AA:BB:CC:DD:EE:FF" + +# Matrix rooms to bridge to Meshtastic channels. +matrix_bridge_meshtastic_relay_matrix_rooms_list: + - id: "#meshtastic:{{ matrix_domain }}" + meshtastic_channel: "0" +``` + +By default, the bot's Matrix ID is `@meshtasticbot:{{ matrix_domain }}`. To change it, adjust `matrix_bridge_meshtastic_relay_matrix_bot_user_id`. + +### Bluetooth (BLE) connections + +When `matrix_bridge_meshtastic_relay_connection_type` is `ble`, the container runs with `--network=host` and bind-mounts the host's DBus socket — both are required for Bluetooth pairing/communication. Only use this connection type if you trust the playbook-managed host and are comfortable with these privileges. + +### Serial connections + +When `matrix_bridge_meshtastic_relay_connection_type` is `serial`, the host device referenced by `matrix_bridge_meshtastic_relay_serial_port` is passed through to the container. Make sure that `matrix_user_uid` / `matrix_user_gid` have read/write access to that device (e.g. by adding the matrix user to the `dialout` group, or adjusting udev rules). + +### Extending the configuration + +There are some additional things you may wish to configure about the bridge. + +Take a look at: + +- `roles/custom/matrix-bridge-meshtastic-relay/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override individual `matrix_bridge_meshtastic_relay_*` variables, or make finer-grained adjustments via `matrix_bridge_meshtastic_relay_configuration_extension_yaml`. + +## Installing + +After configuring the playbook, run the playbook with [playbook tags](playbook-tags.md) as below: + + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + +The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`. + +`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. + +## Usage + +Invite the bot to the Matrix rooms listed in `matrix_bridge_meshtastic_relay_matrix_rooms_list` and it will relay between Matrix and the corresponding Meshtastic channel. Messages sent on Meshtastic will appear in Matrix and vice versa. + +See the [project's wiki](https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki) for details about commands, plugins and advanced usage. + +## Troubleshooting + +As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-meshtastic-relay`. diff --git a/docs/configuring-playbook-bridge-mx-puppet-groupme.md b/docs/configuring-playbook-bridge-mx-puppet-groupme.md index 50b0f4437..3f358c343 100644 --- a/docs/configuring-playbook-bridge-mx-puppet-groupme.md +++ b/docs/configuring-playbook-bridge-mx-puppet-groupme.md @@ -18,7 +18,7 @@ See the project's [documentation](https://gitlab.com/xangelix-pub/matrix/mx-pupp To enable the [GroupMe](https://groupme.com/) bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mx_puppet_groupme_enabled: true +matrix_bridge_mx_puppet_groupme_enabled: true ``` ## Installing diff --git a/docs/configuring-playbook-bridge-mx-puppet-steam.md b/docs/configuring-playbook-bridge-mx-puppet-steam.md index 6c662561f..2779f51f7 100644 --- a/docs/configuring-playbook-bridge-mx-puppet-steam.md +++ b/docs/configuring-playbook-bridge-mx-puppet-steam.md @@ -20,7 +20,7 @@ See the project's [documentation](https://codeberg.org/icewind/mx-puppet-steam/b To enable the [Steam](https://steampowered.com/) bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_mx_puppet_steam_enabled: true +matrix_bridge_mx_puppet_steam_enabled: true ``` ## Installing diff --git a/docs/configuring-playbook-bridge-postmoogle.md b/docs/configuring-playbook-bridge-postmoogle.md index 6a21043a7..8e1e4c728 100644 --- a/docs/configuring-playbook-bridge-postmoogle.md +++ b/docs/configuring-playbook-bridge-postmoogle.md @@ -24,7 +24,7 @@ Open the following ports on your server to be able to receive incoming emails: If you don't open these ports, you will still be able to send emails, but not receive any. -These port numbers are configurable via the `matrix_postmoogle_smtp_host_bind_port` and `matrix_postmoogle_submission_host_bind_port` variables, but other email servers will try to deliver on these default (standard) ports, so changing them is of little use. +These port numbers are configurable via the `matrix_bridge_postmoogle_smtp_host_bind_port` and `matrix_bridge_postmoogle_submission_host_bind_port` variables, but other email servers will try to deliver on these default (standard) ports, so changing them is of little use. ## Adjusting DNS records @@ -44,17 +44,17 @@ To make Postmoogle enable its email sending features, you need to configure MX a Add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_postmoogle_enabled: true +matrix_bridge_postmoogle_enabled: true # Uncomment and adjust this part if you'd like to use a username different than the default -# matrix_postmoogle_login: postmoogle +# matrix_bridge_postmoogle_login: postmoogle # Generate a strong password for the bot. You can create one with a command like `pwgen -s 64 1`. -matrix_postmoogle_password: PASSWORD_FOR_THE_BOT +matrix_bridge_postmoogle_password: PASSWORD_FOR_THE_BOT # Uncomment to add one or more admins to this bridge: # -# matrix_postmoogle_admins: +# matrix_bridge_postmoogle_admins: # - '@yourAdminAccount:{{ matrix_domain }}' # # … unless you've made yourself an admin of all bots/bridges like this: @@ -87,7 +87,7 @@ ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-use `just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. -- If you change the bridge's bot password (`matrix_postmoogle_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_postmoogle_password` to let the bot know its new password. +- If you change the bridge's bot password (`matrix_bridge_postmoogle_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bridge_postmoogle_password` to let the bot know its new password. ## Usage @@ -108,5 +108,5 @@ As with all other services, you can find the logs in [systemd-journald](https:// The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: ```yaml -matrix_postmoogle_loglevel: 'DEBUG' +matrix_bridge_postmoogle_loglevel: 'DEBUG' ``` diff --git a/docs/configuring-playbook-bridge-rustpush.md b/docs/configuring-playbook-bridge-rustpush.md new file mode 100644 index 000000000..f59d48ded --- /dev/null +++ b/docs/configuring-playbook-bridge-rustpush.md @@ -0,0 +1,100 @@ + + +# Setting up RustPush (iMessage) bridging (optional) + +> **Note:** This bridge is in early development and may have stability issues. It may not be desirable to deploy this to a large number of users. Your testing and feedback is appreciated. + +Refer the common guide for configuring mautrix bridges: [Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md) + +The playbook can install and configure [RustPush bridge to iMessage](https://github.com/jasonlaguidice/imessage) for you using Apple's push notification service. + +See the project's [documentation](https://github.com/jasonlaguidice/imessage/blob/main/README.md) to learn what it does and why it might be useful to you. + +## Prerequisites + +### Hardware Key Extraction + +To use this bridge on Linux (Docker), each user needs a **hardware key** extracted from a real Mac. This key contains hardware identifiers needed for iMessage registration. Hardware keys can be shared by a number of users (approximately 20) before causing issues with Apple. + +The key is entered interactively through the bridge bot's login flow (not configured via Ansible variables). See the upstream [README](https://github.com/jasonlaguidice/imessage/blob/main/README.md) for instructions on extracting the key. + +If extracted from an Intel Mac, the Mac does not need to remain running after the key is extracted for this bridge to work. Apple Silicon Macs must run a NAC relay and thus must remain running. + +### Phone Number Registration (optional) + +This bridge can **not** do phone number registration (PNR). The only way to have your phone number registered and used (instead of an Apple ID e-mail address) is to have an iPhone connected to your Apple account. Reference the [BlueBubbles Phone Number Registration Guide](https://docs.bluebubbles.app/server/advanced/registering-a-phone-number-with-your-imessage-account) for information on how to set this up. + +### Enable Appservice Double Puppet (optional) + +If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) service for this playbook. + +See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting. + +## Adjusting the playbook configuration + +To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: + +```yaml +matrix_bridge_rustpush_enabled: true +``` + +### Disable Backfill (optional) + +Backfill can be disabled globally if desired via config. By default, the bridge will backfill from iCloud (CloudKit) and APNS if available. Backfill from `chat.db` is only possible when the bridge is running on MacOS. + +```yaml +matrix_bridge_rustpush_backfill_enabled: false +``` + +### Extending the Configuration + +There are some additional things you may wish to configure about the bridge. + +See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc. + +## Installing + +After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below: + + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + +**Notes**: + +- The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` + + `just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. + +## Usage + +To use the bridge, you need to start a chat with `@rustpushbot:example.com` (where `example.com` is your base domain, not the `matrix.` domain). + +After logging in, the bridge will start receiving iMessages and creating portal rooms. + +## Troubleshooting + +As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-rustpush-bridge`. + +### Increase logging verbosity + +The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook: + +```yaml +# Valid values: fatal, error, warn, info, debug, trace +matrix_bridge_rustpush_logging_level: 'debug' + +# Enable debug logging for RustPush +matrix_bridge_rustpush_rust_log: "warn,rustpushgo=info,openabsinthe=debug" +``` +## Notable Configuration Options +- `matrix_bridge_rustpush_statuskit_notifications` will display StatusKit information for conversation participants. In some clients, this update will cause the DM to be pushed to the top of the conversation list continuously, so this option is disabled by default. + - `matrix_bridge_rustpush_statuskit_notification_style` can be set to either `topic` or `notice` + - `topic` sets the status as a room topic. In supported clients (like Cinny and Sable), this will display `🔕 Focus` as a second line when the person has focus mode enabled. + - `notice` sends an `m.notice` event to the room which will display text in the room but should not generate a notification diff --git a/docs/configuring-playbook-bridge-steam.md b/docs/configuring-playbook-bridge-steam.md index 6cdf7353e..c879af74e 100644 --- a/docs/configuring-playbook-bridge-steam.md +++ b/docs/configuring-playbook-bridge-steam.md @@ -15,7 +15,7 @@ See the project's [documentation](https://github.com/jasonlaguidice/matrix-steam To enable the [Steam](https://steampowered.com/) bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_steam_bridge_enabled: true +matrix_bridge_steam_enabled: true ``` ## Installing @@ -46,3 +46,6 @@ Once logged in, send `search [name]` to search through recognized Steam friends. Chat rooms will automatically be opened as new messages are received. Send `help` to the bot to see the available commands. + +## Notable Configuration Options +- `matrix_bridge_steam_network_presence_topic_enabled` and `matrix_bridge_steam_network_presence_topic_rich_presence_enabled` mirror Steam's [Enhanced Rich Presence](https://partner.steamgames.com/doc/features/enhancedrichpresence) feature in Matrix. This will display the user's current game and rich presence if supported by the game. This sets the DM room's `m.topic` field to achieve this. Some games (like Deadlock) update the rich presence every minute with a match timer. In some clients, the topic update will cause the DM to be pushed to the top of the conversation list continuously, so this option is disabled by default. diff --git a/docs/configuring-playbook-bridge-wechat.md b/docs/configuring-playbook-bridge-wechat.md index 2c7590b40..f53c74b73 100644 --- a/docs/configuring-playbook-bridge-wechat.md +++ b/docs/configuring-playbook-bridge-wechat.md @@ -19,7 +19,7 @@ See the project's [documentation](https://github.com/duo/matrix-wechat/blob/mast To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: ```yaml -matrix_wechat_enabled: true +matrix_bridge_wechat_enabled: true ``` ### Extending the configuration @@ -29,7 +29,7 @@ There are some additional things you may wish to configure about the bridge. Take a look at: - `roles/custom/matrix-bridge-wechat/defaults/main.yml` for some variables that you can customize via your `vars.yml` file -- `roles/custom/matrix-bridge-wechat/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_wechat_configuration_extension_yaml` variable +- `roles/custom/matrix-bridge-wechat/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_wechat_configuration_extension_yaml` variable ## Installing @@ -62,5 +62,5 @@ The default logging level for this component is `warn`. If you want to increase ```yaml # Valid values: fatal, error, warn, info, debug -matrix_wechat_log_level: 'debug' +matrix_bridge_wechat_log_level: 'debug' ``` diff --git a/docs/configuring-playbook-client-commet.md b/docs/configuring-playbook-client-commet.md new file mode 100644 index 000000000..f5ba01a0c --- /dev/null +++ b/docs/configuring-playbook-client-commet.md @@ -0,0 +1,93 @@ + + +# Setting up Commet (optional) + +The playbook can install and configure the [Commet](https://github.com/commetchat/commet) Matrix web client for you. + +## Adjusting DNS records + +By default, this playbook installs Commet on the `commet.` subdomain (`commet.example.com`) and requires you to create a CNAME record for `commet`, which targets `matrix.example.com`. + +When setting, replace `example.com` with your own. + +## Adjusting the playbook configuration + +To enable Commet, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: + +```yaml +matrix_client_commet_enabled: true +``` + +### Adjusting the Commet URL (optional) + +By tweaking the `matrix_client_commet_hostname` and `matrix_client_commet_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one. + +Example additional configuration for your `vars.yml` file: + +```yaml +# Switch to the domain used for Matrix services (`matrix.example.com`), +# so we won't need to add additional DNS records for Commet. +matrix_client_commet_hostname: "{{ matrix_server_fqn_matrix }}" + +# Expose under the /commet subpath +matrix_client_commet_path_prefix: /commet +``` + +After changing the domain, **you may need to adjust your DNS** records to point the Commet domain to the Matrix server. + +If you've decided to reuse the `matrix.` domain, you won't need to do any extra DNS configuration. + +**Note**: `matrix_client_commet_path_prefix` must either be `/` or not end with a slash (e.g. `/commet`). + +### Adjusting the default homeserver (optional) + +Commet is configured with a `default_homeserver` value. By default, the playbook uses `matrix.org`. + +To change it, add the following configuration to your `vars.yml` file: + +```yaml +matrix_client_commet_default_homeserver: "{{ matrix_domain }}" +``` + +### Adjusting the Commet version/branch to build (optional) + +When self-building the container image (`matrix_client_commet_container_image_self_build: true`), the playbook checks out the Commet source repository and builds an image from it. + +To build from a different git branch/tag/SHA, set `matrix_client_commet_version` in your `vars.yml` file: + +```yaml +# Examples: "main", "v1.2.3", "feature-branch", "a1b2c3d4" +matrix_client_commet_version: "main" +``` + +**Note**: by default, the image tag is derived from `matrix_client_commet_version` (`localhost/matrix-client-commet:{{ matrix_client_commet_version }}`). If your branch name contains `/` (e.g. `feature/foo`), override `matrix_client_commet_container_image` (and optionally `matrix_client_commet_container_image_self_build_version_tag`) to a Docker-tag-safe value. + +### Extending the configuration + +There are some additional things you may wish to configure about the component. + +Take a look at: + +- `roles/custom/matrix-client-commet/defaults/main.yml` for some variables that you can customize via your `vars.yml` file +- `roles/custom/matrix-client-commet/templates/global_config.json.j2` for the component's default runtime configuration + +## Installing + +After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below: + + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + +The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` + +`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. + +## Troubleshooting + +As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-client-commet`. diff --git a/docs/configuring-playbook-client-sable.md b/docs/configuring-playbook-client-sable.md index 1ca4a8857..72dd3c79a 100644 --- a/docs/configuring-playbook-client-sable.md +++ b/docs/configuring-playbook-client-sable.md @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later # Setting up Sable (optional) -The playbook can install and configure the [Sable](https://github.com/7w1/sable) Matrix web client for you. +The playbook can install and configure the [Sable](https://github.com/SableClient/Sable) Matrix web client for you. Sable is a web client focusing primarily on simple, elegant and secure interface. It can be installed alongside or instead of [Element Web](./configuring-playbook-client-element-web.md), [Cinny](./configuring-playbook-client-cinny.md) and others. diff --git a/docs/configuring-playbook-conduwuit.md b/docs/configuring-playbook-conduwuit.md index f35dfcac9..92fcce0e5 100644 --- a/docs/configuring-playbook-conduwuit.md +++ b/docs/configuring-playbook-conduwuit.md @@ -1,6 +1,6 @@ - -# Setting up JWT Service (optional) - -The playbook can install and configure [LiveKit JWT Service](https://github.com/element-hq/lk-jwt-service) for you. - -LK-JWT-Service is currently used for a single reason: generate JWT tokens with a given identity for a given room, so that users can use them to authenticate against LiveKit SFU. - -See the project's [documentation](https://github.com/element-hq/lk-jwt-service/) to learn more. - -## Decide on a domain and path - -By default, JWT Service is configured to be served: - -- on the Matrix domain (`matrix.example.com`), configurable via `matrix_livekit_jwt_service_hostname` -- under a `/livekit-jwt-service` path prefix, configurable via `matrix_livekit_jwt_service_path_prefix` - -This makes it easy to set it up, **without** having to adjust your DNS records manually. - -## Adjusting DNS records - -If you've changed the default hostname, **you may need to adjust your DNS** records accordingly to point to the correct server. - -## Adjusting the playbook configuration - -Add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: - -```yaml -matrix_livekit_jwt_service_enabled: true -``` - -## Installing - -After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the [installation](installing.md) command: `just install-all` or `just setup-all` - -## Usage - -Once installed, a new `org.matrix.msc4143.rtc_foci` section is added to the Element Web client to point to your JWT service URL (e.g., `https://matrix.example.com/livekit-jwt-service`). - -## Additional Information - -Refer to the LiveKit JWT-Service documentation for more details on configuring and using JWT Service. diff --git a/docs/configuring-playbook-ketesa.md b/docs/configuring-playbook-ketesa.md new file mode 100644 index 000000000..f056a6966 --- /dev/null +++ b/docs/configuring-playbook-ketesa.md @@ -0,0 +1,101 @@ + + +# Setting up Ketesa (optional) + +The playbook can install and configure [Ketesa](https://ketesa.app) ([source code](https://github.com/etkecc/ketesa)) for you. + +Ketesa is a fully-featured admin interface for Matrix homeservers — manage users, rooms, media, sessions, and more from one clean, responsive web UI. It is the evolution of [Awesome-Technologies/synapse-admin](https://github.com/Awesome-Technologies/synapse-admin): what began as a fork has grown into its own independent project with a redesigned interface, comprehensive Synapse and MAS API coverage, and multi-language support. See the [Ketesa v1.0.0 announcement](https://etke.cc/blog/introducing-ketesa/) for a full overview of what's new. + +>[!NOTE] +> +> - Ketesa does not work with other homeserver implementations than Synapse due to API's incompatibility. +> - The latest version of Ketesa is hosted by [etke.cc](https://etke.cc/) at [cloud.ketesa.app](https://cloud.ketesa.app/). If you only need this service occasionally and trust giving your admin credentials to a 3rd party Single Page Application, you can consider using it from there and avoiding the (small) overhead of self-hosting. +> - This playbook also supports an alternative management UI in the shape of [Element Admin](./configuring-playbook-element-admin.md). Please note that it's currently less feature-rich than Ketesa and requires [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md). + +## Adjusting DNS records (optional) + +By default, this playbook installs Ketesa on the `matrix.` subdomain, at the `/synapse-admin` path (https://matrix.example.com/synapse-admin) — the legacy path is kept for backward compatibility. This makes it easy to install it, because it **doesn't require additional DNS records to be set up**. If that's okay, you can skip this section. + +If you wish to adjust it, see the section [below](#adjusting-the-ketesa-url-optional) for details about DNS configuration. + +## Adjusting the playbook configuration + +To enable Ketesa, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: + +```yaml +matrix_ketesa_enabled: true +``` + +**Note**: Ketesa requires Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/usage/administration/admin_api/index.html) to function. Access to them is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, for additional security, we normally leave them unexposed, following [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints). Because Ketesa needs these APIs to function, when installing Ketesa, the playbook **automatically** exposes the Synapse Admin API publicly for you. Depending on the homeserver implementation you're using (Synapse, Dendrite), this is equivalent to: + +- for [Synapse](./configuring-playbook-synapse.md) (our default homeserver implementation): `matrix_synapse_container_labels_public_client_synapse_admin_api_enabled: true` +- for [Dendrite](./configuring-playbook-dendrite.md): `matrix_dendrite_container_labels_public_client_synapse_admin_api_enabled: true` +- for [Tuwunel](./configuring-playbook-tuwunel.md): `matrix_tuwunel_container_labels_public_client_synapse_admin_api_enabled: true` + +By default, Ketesa installation will be [restricted to only work with one homeserver](https://github.com/etkecc/ketesa/blob/main/README.md#restricting-available-homeserver) — the one managed by the playbook. To adjust these restrictions, tweak the `matrix_ketesa_config_restrictBaseUrl` variable. + +### Adjusting the Ketesa URL (optional) + +By tweaking the `matrix_ketesa_hostname` and `matrix_ketesa_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one. + +We recommend updating the path prefix to `/ketesa` to align with the new branding, while the default `/synapse-admin` is kept for backward compatibility: + +```yaml +matrix_ketesa_path_prefix: /ketesa +``` + +Or to change the hostname entirely: + +```yaml +# Change the default hostname and path prefix +matrix_ketesa_hostname: admin.example.com +matrix_ketesa_path_prefix: / +``` + +If you've changed the default hostname, you may need to create a CNAME record for the Ketesa domain (`admin.example.com`), which targets `matrix.example.com`. + +When setting, replace `example.com` with your own. + +### Extending the configuration + +There are some additional things you may wish to configure about the component. + +Take a look at: + +- `roles/custom/matrix-ketesa/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_ketesa_configuration_extension_json` variable + +## Installing + +After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below: + + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + +The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` + +`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. + +## Usage + +After installation, Ketesa will be accessible at: `https://matrix.example.com/synapse-admin/` (or `/ketesa/` if you updated the path prefix as recommended) + +To use Ketesa, you need to have [registered at least one administrator account](registering-users.md) on your server. + +## Troubleshooting + +As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-ketesa`. + +If you have questions, you can join this community room and feel free to ask: [#ketesa:etke.cc](https://matrix.to/#/#ketesa:etke.cc) diff --git a/docs/configuring-playbook-ldap-auth.md b/docs/configuring-playbook-ldap-auth.md index f6736a735..69fb49a4d 100644 --- a/docs/configuring-playbook-ldap-auth.md +++ b/docs/configuring-playbook-ldap-auth.md @@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later The playbook can install and configure the [matrix-synapse-ldap3](https://github.com/matrix-org/matrix-synapse-ldap3) LDAP Auth password provider for you. -See the project's [documentation](https://github.com/matrix-org/matrix-synapse-ldap3/blob/main/README.rst) to learn what it does and why it might be useful to you. +See the project's [documentation](https://github.com/matrix-org/matrix-synapse-ldap3/blob/main/README.md) to learn what it does and why it might be useful to you. ## Adjusting the playbook configuration @@ -52,9 +52,3 @@ ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` `just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. - -## Usage - -### Handling user registration - -If you wish for users to also be able to make new registrations against LDAP, you may **also** wish to [set up the ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md). diff --git a/docs/configuring-playbook-livekit-server.md b/docs/configuring-playbook-livekit-server.md index 3cd9c5dcc..a06ccb3f8 100644 --- a/docs/configuring-playbook-livekit-server.md +++ b/docs/configuring-playbook-livekit-server.md @@ -61,6 +61,12 @@ livekit_server_container_labels_turn_traefik_entrypoints: " -# Setting up matrix-ldap-registration-proxy (optional) +# Setting up matrix-ldap-registration-proxy (optional, removed) -The playbook can install and configure [matrix-ldap-registration-proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy) for you. +🪦 The playbook used to be able to install and configure [matrix-ldap-registration-proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy), but no longer includes this component, as it has become unavailable. -This proxy handles Matrix registration requests and forwards them to LDAP. +## Uninstalling the component manually -See the project's [documentation](https://gitlab.com/activism.international/matrix_ldap_registration_proxy/-/blob/main/README.md) to learn what it does and why it might be useful to you. +If you still have matrix-ldap-registration-proxy installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server: -**Note**: This does support the full Matrix specification for registrations. It only provide a very coarse implementation of a basic password registration. - -## Adjusting the playbook configuration - -To enable the component, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file (adapt to your needs): - -```yaml -matrix_ldap_registration_proxy_enabled: true - -# LDAP credentials -matrix_ldap_registration_proxy_ldap_uri: YOUR_URI_HERE -matrix_ldap_registration_proxy_ldap_base_dn: YOUR_DN_HERE -matrix_ldap_registration_proxy_ldap_user: YOUR_USER_HERE -matrix_ldap_registration_proxy_ldap_password: YOUR_PASSWORD_HERE -``` - -If you already use the [synapse external password provider via LDAP](configuring-playbook-ldap-auth.md) (that is, you have `matrix_synapse_ext_password_provider_ldap_enabled: true` and other options in your configuration) you can use the following values as configuration: - -```yaml -# Use the LDAP values specified for the synapse role to setup LDAP proxy -matrix_ldap_registration_proxy_ldap_uri: "{{ matrix_synapse_ext_password_provider_ldap_uri }}" -matrix_ldap_registration_proxy_ldap_base_dn: "{{ matrix_synapse_ext_password_provider_ldap_base }}" -matrix_ldap_registration_proxy_ldap_user: "{{ matrix_synapse_ext_password_provider_ldap_bind_dn }}" -matrix_ldap_registration_proxy_ldap_password: "{{ matrix_synapse_ext_password_provider_ldap_bind_password }}" - -matrix_ldap_registration_proxy_systemd_wanted_services_list_custom: - - matrix-synapse.service -``` - -### Extending the configuration - -There are some additional things you may wish to configure about the component. - -Take a look at: - -- `roles/custom/matrix-ldap-registration-proxy/defaults/main.yml` for some variables that you can customize via your `vars.yml` file - -## Installing - -After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below: - - ```sh -ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start -``` - -The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` - -`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. +systemctl disable --now matrix-ldap-registration-proxy.service -## Troubleshooting - -As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-ldap-registration-proxy`. +rm -rf /matrix/matrix_ldap_registration_proxy +``` diff --git a/docs/configuring-playbook-matrix-registration.md b/docs/configuring-playbook-matrix-registration.md index 441c85973..bb22ec35e 100644 --- a/docs/configuring-playbook-matrix-registration.md +++ b/docs/configuring-playbook-matrix-registration.md @@ -1,115 +1,36 @@ -# Setting up matrix-registration (optional) +# Setting up matrix-registration (optional, removed) -> [!WARNING] -> - This is a poorly maintained and buggy project. It's better to avoid using it. -> - This is not related to [matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md) +> [!NOTE] +> This is not related to [matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md). -The playbook can install and configure [matrix-registration](https://github.com/ZerataX/matrix-registration) for you. It is a simple python application to have a token based Matrix registration. +🪦 The playbook used to be able to install and configure [matrix-registration](https://github.com/ZerataX/matrix-registration), but no longer includes this component, as it has been unmaintained since November, 2025. -Use matrix-registration to **create unique registration links**, which people can use to register on your Matrix server. It allows certain people (these having a special link) to register a user account, **keeping your server's registration closed (private)**. +## Uninstalling the component manually -**matrix-registration** provides 2 things: +If you still have matrix-registration installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server: -- **an API for creating registration tokens** (unique registration links). This API can be used via `curl` or via the playbook (see [Usage](#usage) below) - -- **a user registration page**, where people can use these registration tokens. By default, exposed at `https://matrix.example.com/matrix-registration` - -## Adjusting DNS records (optional) - -By default, this playbook installs the matrix-registration on the `matrix.` subdomain, at the `/matrix-registration` path (https://matrix.example.com/matrix-registration). This makes it easy to install it, because it **doesn't require additional DNS records to be set up**. If that's okay, you can skip this section. - -If you wish to adjust it, see the section [below](#adjusting-the-matrix-registration-url-optional) for details about DNS configuration. - -## Adjusting the playbook configuration - -To enable matrix-registration, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: - -```yaml -matrix_registration_enabled: true - -# Generate a strong secret here. You can create one with a command like `pwgen -s 64 1`. -matrix_registration_admin_secret: "ENTER_SOME_SECRET_HERE" -``` - -### Adjusting the matrix-registration URL (optional) - -By tweaking the `matrix_registration_hostname` and `matrix_registration_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one. - -Example additional configuration for your `vars.yml` file: - -```yaml -# Change the default hostname and path prefix -matrix_registration_hostname: registration.example.com -matrix_registration_path_prefix: / -``` - -If you've changed the default hostname, you may need to create a CNAME record for the matrix-registration domain (`registration.example.com`), which targets `matrix.example.com`. - -When setting, replace `example.com` with your own. - -### Extending the configuration - -There are some additional things you may wish to configure about the component. - -Take a look at: - -- `roles/custom/matrix-registration/defaults/main.yml` for some variables that you can customize via your `vars.yml` file -- `roles/custom/matrix-registration/templates/config.yaml.j2` for the component's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_registration_configuration_extension_yaml` variable - -## Installing - -After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below: - - ```sh -ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start -``` - -The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` - -`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. - -## Usage +systemctl disable --now matrix-registration.service -**matrix-registration** gets exposed at `https://matrix.example.com/matrix-registration` +rm -rf /matrix/matrix-registration -It provides various [APIs](https://github.com/ZerataX/matrix-registration/wiki/api) — for creating registration tokens, listing tokens, disabling tokens, etc. To make use of all of its capabilities, consider using `curl`. - -We make the most common APIs easy to use via the playbook (see below). - -### Creating registration tokens - -To **create a new user registration token (link)**, use this command: - -```sh -ansible-playbook -i inventory/hosts setup.yml \ ---tags=generate-matrix-registration-token \ ---extra-vars="one_time=yes ex_date=2021-12-31" +/matrix/postgres/bin/cli-non-interactive -c 'DROP DATABASE matrix_registration;' ``` - -The above command creates and returns a **one-time use** token, which **expires** on the 31st of December 2021. Adjust the `one_time` and `ex_date` variables as you see fit. - -Share the unique registration link (generated by the command above) with users to let them register on your Matrix server. - -### Listing registration tokens - -To **list the existing user registration tokens**, use this command: - -```sh -ansible-playbook -i inventory/hosts setup.yml \ ---tags=list-matrix-registration-tokens -``` - -The shortcut command with `just` program is also available: `just run-tags list-matrix-registration-tokens` - -## Troubleshooting - -As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-registration`. diff --git a/docs/configuring-playbook-matrix-rtc.md b/docs/configuring-playbook-matrix-rtc.md index 9360202ad..fa9c29ee0 100644 --- a/docs/configuring-playbook-matrix-rtc.md +++ b/docs/configuring-playbook-matrix-rtc.md @@ -38,6 +38,12 @@ matrix_rtc_enabled: true In addition to the HTTP/HTTPS ports (which you've already exposed as per the [prerequisites](prerequisites.md) document), you'll also need to open ports required by [LiveKit Server](configuring-playbook-livekit-server.md) as described in its own [Adjusting firewall rules](configuring-playbook-livekit-server.md#adjusting-firewall-rules) section. +## Fronting the integrated reverse-proxy with another reverse-proxy + +If you're [fronting the integrated reverse-proxy webserver with another reverse-proxy](configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy) (e.g. nginx), it needs to forward WebSocket traffic for [LiveKit Server](configuring-playbook-livekit-server.md) at the `/livekit-server/` path. Without that, Matrix RTC calls will not work. + +See [`examples/reverse-proxies/nginx/matrix.conf`](../examples/reverse-proxies/nginx/matrix.conf) for an nginx example. + ## Installing After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records) and [adjusting firewall rules](#adjusting-firewall-rules), run the playbook with [playbook tags](playbook-tags.md) as below: diff --git a/docs/configuring-playbook-prometheus-grafana.md b/docs/configuring-playbook-prometheus-grafana.md index 41f14cb98..16e41f958 100644 --- a/docs/configuring-playbook-prometheus-grafana.md +++ b/docs/configuring-playbook-prometheus-grafana.md @@ -183,6 +183,9 @@ Name | Description `prometheus_postgres_exporter_container_labels_metrics_enabled`|Set this to `true` to expose the [Postgres exporter](#enable-metrics-and-graphs-for-postgres-optional) metrics on `https://matrix.example.com/metrics/postgres-exporter`. `prometheus_nginxlog_exporter_enabled`|Set this to `true` to enable the [prometheus-nginxlog-exporter](#enable-metrics-and-graphs-for-nginx-logs-optional) (locally, on the container network). `prometheus_nginxlog_exporter_container_labels_metrics_enabled`|Set this to `true` to expose the [prometheus-nginxlog-exporter](#enable-metrics-and-graphs-for-nginx-logs-optional) metrics on `https://matrix.example.com/metrics/nginxlog`. +`ntfy_metrics_listen_http_port`|Set this to a port number (e.g. `9090`) to make [ntfy](configuring-playbook-ntfy.md) serve its metrics (locally, on the container network) on that port. +`ntfy_container_labels_traefik_metrics_enabled`|Set this to `true` to expose the [ntfy](configuring-playbook-ntfy.md) metrics on `https://matrix.example.com/metrics/ntfy`. +`matrix_synapse_usage_exporter_metrics_proxying_enabled`|Set this to `true` to expose the [synapse-usage-exporter](configuring-playbook-synapse-usage-exporter.md) metrics on `https://matrix.example.com/metrics/synapse-usage-exporter`. ### Expose metrics of other services/roles diff --git a/docs/configuring-playbook-synapse-admin.md b/docs/configuring-playbook-synapse-admin.md deleted file mode 100644 index 475bce71d..000000000 --- a/docs/configuring-playbook-synapse-admin.md +++ /dev/null @@ -1,93 +0,0 @@ - - -# Setting up Synapse Admin (optional) - -The playbook can install and configure Synapse Admin for you. - -Synapse Admin is a web UI tool you can use to **administrate users, rooms, media, etc. on your Matrix homeserver**. This playbook is configured to install [etkecc/synapse-admin](https://github.com/etkecc/synapse-admin), which is a [feature-rich](https://github.com/etkecc/synapse-admin#fork-differences) fork of [Awesome-Technologies/synapse-admin](https://github.com/Awesome-Technologies/synapse-admin). - ->[!NOTE] -> -> - Synapse Admin does not work with other homeserver implementations than Synapse due to API's incompatibility. -> - The latest version of Synapse Admin is hosted by [etke.cc](https://etke.cc/) at [admin.etke.cc](https://admin.etke.cc/). If you only need this service occasionally and trust giving your admin credentials to a 3rd party Single Page Application, you can consider using it from there and avoiding the (small) overhead of self-hosting. -> - This playbook also supports an alternative management UI in the shape of [Element Admin](./configuring-playbook-element-admin.md). Please note that it's currently less feature-rich than Synapse Admin and requires [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md). - -## Adjusting DNS records (optional) - -By default, this playbook installs Synapse Admin on the `matrix.` subdomain, at the `/synapse-admin` path (https://matrix.example.com/synapse-admin). This makes it easy to install it, because it **doesn't require additional DNS records to be set up**. If that's okay, you can skip this section. - -If you wish to adjust it, see the section [below](#adjusting-the-synapse-admin-url-optional) for details about DNS configuration. - -## Adjusting the playbook configuration - -To enable Synapse Admin, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file: - -```yaml -matrix_synapse_admin_enabled: true -``` - -**Note**: Synapse Admin requires Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/usage/administration/admin_api/index.html) to function. Access to them is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, for additional security, we normally leave them unexposed, following [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints). Because Synapse Admin needs these APIs to function, when installing Synapse Admin, the playbook **automatically** exposes the Synapse Admin API publicly for you. Depending on the homeserver implementation you're using (Synapse, Dendrite), this is equivalent to: - -- for [Synapse](./configuring-playbook-synapse.md) (our default homeserver implementation): `matrix_synapse_container_labels_public_client_synapse_admin_api_enabled: true` -- for [Dendrite](./configuring-playbook-dendrite.md): `matrix_dendrite_container_labels_public_client_synapse_admin_api_enabled: true` - -By default, synapse-admin installation will be [restricted to only work with one homeserver](https://github.com/etkecc/synapse-admin/blob/e21e44362c879ac41f47c580b04210842b6ff3d7/README.md#restricting-available-homeserver) — the one managed by the playbook. To adjust these restrictions, tweak the `matrix_synapse_admin_config_restrictBaseUrl` variable. - -### Adjusting the Synapse Admin URL (optional) - -By tweaking the `matrix_synapse_admin_hostname` and `matrix_synapse_admin_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one. - -Example additional configuration for your `vars.yml` file: - -```yaml -# Change the default hostname and path prefix -matrix_synapse_admin_hostname: admin.example.com -matrix_synapse_admin_path_prefix: / -``` - -If you've changed the default hostname, you may need to create a CNAME record for the Synapse Admin domain (`admin.example.com`), which targets `matrix.example.com`. - -When setting, replace `example.com` with your own. - -### Extending the configuration - -There are some additional things you may wish to configure about the component. - -Take a look at: - -- `roles/custom/matrix-synapse-admin/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_synapse_admin_configuration_extension_json` variable - -## Installing - -After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below: - - -```sh -ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start -``` - -The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all` - -`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too. - -## Usage - -After installation, Synapse Admin will be accessible at: `https://matrix.example.com/synapse-admin/` - -To use Synapse Admin, you need to have [registered at least one administrator account](registering-users.md) on your server. - -## Troubleshooting - -As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-synapse-admin`. - -If you have questions, you can join this community room and feel free to ask: [#synapse-admin:etke.cc](https://matrix.to/#/#synapse-admin:etke.cc) diff --git a/docs/configuring-playbook-synapse-usage-exporter.md b/docs/configuring-playbook-synapse-usage-exporter.md index cb66cdffe..8be14c11e 100644 --- a/docs/configuring-playbook-synapse-usage-exporter.md +++ b/docs/configuring-playbook-synapse-usage-exporter.md @@ -1,7 +1,7 @@ @@ -38,13 +38,35 @@ To enable synapse-usage-exporter, add the following configuration to your `inven ```yaml matrix_synapse_usage_exporter_enabled: true -# (Optional) Expose endpoint if you want to collect statistics from outside (from other homeservers). +# (Optional) Expose the usage-stats ingestion endpoint if you want to collect statistics from outside (from other homeservers). # If enabled, synapse-usage-exporter will be exposed publicly at `matrix.example.com/report-usage-stats/push`. # When collecting usage statistics for Synapse running on the same host, you don't need to enable this. # You can adjust the hostname and path via `matrix_synapse_usage_exporter_hostname` and `matrix_synapse_usage_exporter_path_prefix`. # matrix_synapse_usage_exporter_proxying_enabled: true ``` +**Note**: `matrix_synapse_usage_exporter_proxying_enabled` only exposes the endpoint that Synapse pushes usage statistics **to** (`/report-usage-stats/push`). Despite its generic name, it has nothing to do with the metrics endpoint that Prometheus reads **from**. See [below](#collecting-metrics-to-an-external-prometheus-server) for exposing metrics. + +### Collecting metrics to an external Prometheus server + +Metrics are always served on the container network, so the [integrated Prometheus](./configuring-playbook-prometheus-grafana.md) (`prometheus_enabled: true`) scrapes them without any additional configuration. + +To collect them with an **external Prometheus server**, you need to expose them publicly. You can do so by enabling metrics exposure for all services (`matrix_metrics_exposure_enabled: true`), or just for this service: + +```yaml +# Expose the metrics on https://matrix.example.com/metrics/synapse-usage-exporter +matrix_synapse_usage_exporter_metrics_proxying_enabled: true + +# Uncomment to password-protect the metrics for synapse-usage-exporter. +# matrix_synapse_usage_exporter_container_labels_traefik_metrics_middleware_basic_auth_enabled: true + +# Uncomment and set this part to the Basic Authentication credentials (raw `htpasswd` file content) used to protect the endpoint. +# See https://doc.traefik.io/traefik/middlewares/http/basicauth/#users +# matrix_synapse_usage_exporter_container_labels_traefik_metrics_middleware_basic_auth_users: '' +``` + +Refer to [this section](./configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) of the Prometheus and Grafana documentation for more details. + ### Adjusting the synapse-usage-exporter URL (optional) By tweaking the `matrix_synapse_usage_exporter_hostname` and `matrix_synapse_usage_exporter_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one. diff --git a/docs/configuring-playbook-synapse.md b/docs/configuring-playbook-synapse.md index f56ec4aea..c5a9e7533 100644 --- a/docs/configuring-playbook-synapse.md +++ b/docs/configuring-playbook-synapse.md @@ -196,11 +196,11 @@ The shortcut commands with the [`just` program](just.md) are also available: `ju ## Usage -### Synapse Admin +### Ketesa -With [Synapse Admin](configuring-playbook-synapse-admin.md), certain Synapse administration tasks (managing users and rooms, etc.) can be performed via a web user-interace. +[Ketesa](configuring-playbook-ketesa.md) is a fully-featured web UI for administrating your homeserver — managing users, rooms, media, sessions, and more. -The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md). +The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md). ### Monitoring Synapse Metrics with Prometheus and Grafana diff --git a/docs/configuring-playbook-synology.md b/docs/configuring-playbook-synology.md new file mode 100644 index 000000000..969831c2b --- /dev/null +++ b/docs/configuring-playbook-synology.md @@ -0,0 +1,179 @@ + + +# Configuring Synology DSM + +This document is a guide for preparing Synology DSM for the installation of the [Matrix Docker Ansible Deploy](https://github.com/spantaleev/matrix-docker-ansible-deploy) project. + +> **Note:** Synology DSM is a community-supported platform. It is not officially tested or maintained by the project maintainers. Use at your own discretion. + +**Intended audience:** Users already familiar with DSM, SSH, and this Ansible project. + +## Assumptions + +- DSM version 7 or higher +- `Volume1` is used as the default Docker storage location +- You are using DSM's built-in reverse proxy for handling HTTPS + +## How Synology Support Works + +The playbook automatically detects Synology DSM by checking for `/etc/synoinfo.conf`. When detected, it: + +- Uses `synouser` and `synogroup` (DSM-native tools) instead of standard Linux user management +- Constrains the Python `requests` package to a version compatible with the Docker SDK +- Ensures `/volume1` has shared mount propagation so container bind mounts work correctly +- Deploys a `matrix-synology-boot-fix` service that runs on every boot after Docker is ready + +You can override auto-detection by setting `matrix_base_host_is_synology: true` or `false` in your `vars.yml`. + +### Matrix Service Account + +The playbook creates a `matrix` system account using Synology's `synouser` tool. The account is secured as follows: + +- **Expired** (`expired=1`) — the account cannot be used to log in to DSM or any application + +You must set a password for this account via `matrix_synology_user_password` in your `vars.yml` (see [vars.yml Configuration](#varsyml-configuration)). The password cannot be used to log in because the account is expired, but a non-empty password is required as an additional security layer. + +> If you pre-create the `matrix` user manually before running the playbook, the playbook will not modify the existing account's settings — you are responsible for securing it. + +### Boot-fix Service + +Synology DSM has two boot-time quirks that the boot-fix service addresses automatically: + +1. **`/volume1` shared mount propagation** + + Docker requires `/volume1` to be mounted as shared (`mount --make-shared /volume1`) for container bind mounts with `bind-propagation=slave` to work correctly (used by matrix-synapse for its media store). On Synology, this cannot be inserted into the systemd chain before Container Manager starts — doing so causes Container Manager to detect a broken dependency and prompt for repair on every boot. The playbook applies this during setup, and the boot-fix service re-applies it on every subsequent reboot, safely outside Container Manager's dependency chain. + +2. **Skipped services at boot** + + Synology's systemd drops services with multi-level dependency chains from the boot activation queue (e.g. `matrix-traefik → matrix-container-socket-proxy → docker`). These services show as `inactive` or `failed` after reboot even though they are enabled. The boot-fix service scans for any enabled `matrix-*.service` in either state and starts them automatically. + + > **If you previously configured a Task Scheduler entry** (`Control Panel > Task Scheduler`) to run `mount --make-shared /volume1` at boot-up, you can remove it — the boot-fix service now handles this. + +## Synology GUI Preparation + +1. **Enable SSH** + - `Control Panel` > `Terminal & SNMP` > `Enable SSH service` + +2. **Enable SFTP** + - `Control Panel` > `File Service` > `FTP` > `Enable SFTP service` with default port + +3. **Enable User Home Directory** + - `Control Panel` > `User & Group` > `Advanced` > `Enable user home service` + +4. **Install Container Manager** + - Install from `Package Center` + +5. **Configure Reverse Proxy** + - `Control Panel` > `Login Portal` > `Advanced` > `Reverse Proxy` + - Create entries for each service you enable (e.g. Matrix, Element, admin page) + - Example entry: + - Source: `HTTPS` / `matrix.example.com` / port `443` + - Destination: `HTTP` / `localhost` / port `81` + +## SSH Preparation + +### (Optional but Recommended) Enable SSH Key Authentication + +Configure key-based SSH login to avoid password prompts during Ansible runs. + +### Set Up the Ansible Environment + +Create a project folder and Python virtual environment on the DSM host: + +```shell +mkdir ~/path/to/your/project/folder +cd ~/path/to/your/project/folder + +python3 -m venv ./myenv +# (optional) activate python virtual environment +# source ./myenv/bin/activate +``` + +## Inventory Configuration + +In your `inventory/hosts` file, set the Python interpreter to your virtual environment: + +```ini +# SSH key authentication with empty passphrase example +matrix.example.com ansible_host= ansible_ssh_user= become=true become_user=root ansible_python_interpreter=/volume1/homes/path/to/your/project/folder/myenv/bin/python ansible_sudo_pass='your-password' +``` + +## vars.yml Configuration + +Add the following Synology-specific variables to your `vars.yml`: + +```yaml +# Synology-specific settings + +# Controls Synology DSM-specific handling. `null` means autodetect (via /etc/synoinfo.conf). +# Set to `true`/`false` to force. +# matrix_base_host_is_synology: true + +# Password for the Matrix service account created by the playbook. +# The account is created as expired so this password cannot be used to log in. +matrix_synology_user_password: "your-strong-password" + +# User and group that will be created automatically by the playbook +matrix_user_name: "matrix" +matrix_group_name: "matrix" + +# Data path on your Synology volume +matrix_base_data_path: "/volume1/docker/matrix" + +# Use Synology Container Manager's Docker daemon instead of installing Docker +matrix_playbook_docker_installation_enabled: false +devture_systemd_docker_base_host_command_docker: "/var/packages/ContainerManager/target/usr/bin/docker" +devture_systemd_docker_base_docker_service_name: "pkg-ContainerManager-dockerd.service" + +# Use Synology's NTP service +devture_timesync_ntpd_service: "chronyd" + +# Reverse proxy settings — use HTTPS at the DSM reverse proxy level +matrix_playbook_ssl_enabled: true +traefik_config_entrypoint_web_secure_enabled: false + +# Bind to localhost only — DSM reverse proxy handles public traffic +traefik_container_web_host_bind_port: '127.0.0.1:81' +matrix_playbook_public_matrix_federation_api_traefik_entrypoint_host_bind_port: '127.0.0.1:8449' + +# Trust X-Forwarded-* headers from the local reverse proxy +traefik_config_entrypoint_web_forwardedHeaders_insecure: true + +matrix_playbook_public_matrix_federation_api_traefik_entrypoint_config_custom: + forwardedHeaders: + insecure: true +``` + +## Running the Playbook + +```shell +# Full setup +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all + +# start +ansible-playbook -i inventory/hosts setup.yml --tags=install-all,start + +# Stop all services +ansible-playbook -i inventory/hosts setup.yml --tags=stop + +# Apply config changes (always include start to restart running containers) +ansible-playbook -i inventory/hosts setup.yml --tags=stop,setup-all,start +``` + +> **Important:** Always include `stop` before `setup-all,start` when changing configuration. Running `setup-all` alone does not restart already-running containers. + +## Creating Matrix Users + +After the services are running, create your first Matrix user: + +```shell +# option 1: +sudo docker exec -it matrix-synapse register_new_matrix_user http://localhost:8008 -c /data/homeserver.yaml -u your_username -p your_password + +# option 2: +ansible-playbook -i inventory/hosts setup.yml --extra-vars='username=your_username password=your_password admin=yes|no' --tags=register-user +``` diff --git a/docs/configuring-playbook-traefik.md b/docs/configuring-playbook-traefik.md index 46b236580..0b68dd205 100644 --- a/docs/configuring-playbook-traefik.md +++ b/docs/configuring-playbook-traefik.md @@ -25,16 +25,31 @@ traefik_config_accessLog_enabled: false ### Enable Traefik Dashboard -To enable a Traefik [Dashboard](https://doc.traefik.io/traefik/operations/dashboard/) UI at `https://matrix.example.com/dashboard/` (note the trailing `/`), add the following configuration to your `vars.yml` file: +To enable the Traefik [Dashboard](https://doc.traefik.io/traefik/operations/dashboard/) UI at `https://matrix.example.com/dashboard/` (note the trailing `/`), add the following configuration to your `vars.yml` file: ```yaml traefik_dashboard_enabled: true traefik_dashboard_hostname: "{{ matrix_server_fqn_matrix }}" traefik_dashboard_basicauth_enabled: true -traefik_dashboard_basicauth_user: YOUR_USERNAME_HERE -traefik_dashboard_basicauth_password: YOUR_PASSWORD_HERE +traefik_dashboard_basicauth_htpasswd: "YOUR_USERNAME_HERE:$apr1$..." ``` +Choose a username and password for the dashboard, then generate the corresponding `htpasswd` entry with: + +```sh +htpasswd -nb YOUR_USERNAME_HERE YOUR_PASSWORD_HERE +``` + +The command outputs the exact value to use for `traefik_dashboard_basicauth_htpasswd` — your username, a colon, and a hash of your chosen password: + +```text +YOUR_USERNAME_HERE:$apr1$... +``` + +Copy the full output line into `traefik_dashboard_basicauth_htpasswd`. After deploying, log in to the dashboard using the same username and password that you chose earlier. + +The role also supports the legacy `traefik_dashboard_basicauth_user` / `traefik_dashboard_basicauth_password` convenience variables, but that path depends on the `passlib` Python library on the Ansible controller, may be affected by passlib/bcrypt compatibility issues, and generates non-deterministic hashes which can lead to unnecessary changes. + > [!WARNING] > Enabling the dashboard on a hostname you use for something else (like `matrix_server_fqn_matrix` in the configuration above) may cause conflicts. Enabling the Traefik Dashboard makes Traefik capture all `/dashboard` and `/api` requests and forward them to itself. If any of the services hosted on the same hostname requires any of these 2 URL prefixes, you will experience problems. So far, we're not aware of any playbook services which occupy these endpoints and are likely to cause conflicts. diff --git a/docs/configuring-playbook-tuwunel.md b/docs/configuring-playbook-tuwunel.md new file mode 100644 index 000000000..33ac097a7 --- /dev/null +++ b/docs/configuring-playbook-tuwunel.md @@ -0,0 +1,269 @@ + + +# Configuring Tuwunel (optional) + +The playbook can install and configure the [Tuwunel](https://matrix-construct.github.io/tuwunel/) Matrix homeserver for you. + +Tuwunel is a featureful homeserver written entirely in Rust, intended as a scalable, low-cost, enterprise-ready alternative to Synapse that fully implements the [Matrix specification](https://spec.matrix.org/latest/) for all but the most niche uses. It is the official successor to [conduwuit](configuring-playbook-conduwuit.md), is now sponsored by the government of Switzerland 🇨🇭 (where it is currently deployed for citizens), and is used by a number of organisations with a vested interest in its continued development. See the project's [documentation](https://matrix-construct.github.io/tuwunel/) for further background. + +By default, the playbook installs [Synapse](https://github.com/element-hq/synapse) as it's the only full-featured Matrix server at the moment. If that's okay, you can skip this document. + +> [!WARNING] +> - **You can't switch an existing Matrix server's implementation** (e.g. Synapse → Tuwunel). Proceed below only if you're OK with starting over, or you're dealing with a server on a new domain name which hasn't participated in the Matrix federation yet. The one exception is migrating from conduwuit; see [Migrating from conduwuit](#migrating-from-conduwuit). +> - **Homeserver implementations other than Synapse may not be fully functional** with every part of this playbook. Make yourself familiar with the trade-offs before proceeding. + +## Adjusting the playbook configuration + +To use Tuwunel, set the following on `inventory/host_vars/matrix.example.com/vars.yml`: + +```yaml +matrix_homeserver_implementation: tuwunel + +# Open the registration endpoint long enough to create your first user. +# After signing up, set this back to false. +matrix_tuwunel_config_allow_registration: true + +# A registration token to protect the endpoint from abuse. +# Generate one with `pwgen -s 64 1` or similar. +matrix_tuwunel_config_registration_token: '' +``` + +The first user account that registers becomes a server admin and is automatically invited to the admin room. See [Creating the first user account](#creating-the-first-user-account) below for the bootstrap procedure. + +## Wiring done for you + +When `matrix_homeserver_implementation: tuwunel` is set, the playbook automatically integrates Tuwunel with the rest of your stack: + +- **Federation.** Toggled by `matrix_homeserver_federation_enabled`. The federation virtual host (port 8448 in the default setup) is wired up via Traefik labels. +- **Well-known.** `matrix_tuwunel_config_well_known_client` is set to your public homeserver URL whenever SSL is enabled. Matrix clients use this for delegated-domain server discovery; identity-provider entries below can also omit their `callback_url`, since Tuwunel derives `/_matrix/client/unstable/login/sso/callback/` automatically. +- **Element Call / MatrixRTC.** When the [LiveKit JWT service](configuring-playbook-matrix-rtc.md) is enabled, Tuwunel publishes its public URL through `.well-known/matrix/client` per [MSC4143](https://github.com/matrix-org/matrix-spec-proposals/pull/4143). +- **Legacy calls (TURN).** When [Coturn](configuring-playbook-turn.md) is enabled, its URIs and shared secret (or username/password, depending on `coturn_authentication_method`) are wired automatically. + +## Extending the configuration + +Tuwunel exposes a large configuration surface. The role surfaces commonly used options as Ansible variables under `matrix_tuwunel_config_*`. See [`roles/custom/matrix-tuwunel/defaults/main.yml`](../roles/custom/matrix-tuwunel/defaults/main.yml) for the complete list, and [`roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2`](../roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2) for the rendered configuration. + +For options that aren't surfaced as a dedicated variable, [environment variables](https://matrix-construct.github.io/tuwunel/configuration.html#environment-variables) are the recommended override mechanism. They take priority over the rendered TOML, are scoped to the running container, and require no template patching: + +```yaml +matrix_tuwunel_environment_variables_extension: | + TUWUNEL_REQUEST_TIMEOUT=60 + TUWUNEL_DNS_CACHE_SIZE=131072 +``` + +Keys nested under a TOML section use `__` (double underscore) to descend, e.g. `TUWUNEL_WELL_KNOWN__SERVER`. User-named sections become path segments too: `TUWUNEL_STORAGE_PROVIDER__ARCHIVE__S3__URL` overrides the `url` field of the `archive` storage provider in the example below. + +If you need wholesale control of the configuration file, copy [`roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2`](../roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2) into your inventory and point `matrix_tuwunel_template_tuwunel_config` at your copy. + +The container image published as `:latest` is built with `io_uring`, `jemalloc`, LDAP, blurhashing, URL preview, sentry telemetry, and zstd compression all enabled, so most opt-in features are simply a configuration toggle away. + +### Identity providers (OAuth2 / OIDC) + +Configure one or more `[[global.identity_provider]]` entries via a list. Each entry maps directly to Tuwunel's [identity-provider fields](https://matrix-construct.github.io/tuwunel/authentication/providers.html); only the fields you set are emitted. GitHub, GitLab, and Google have built-in `issuer_url` defaults so a `client_id` plus `client_secret` is enough; for any other `brand` (Apple, Facebook, Keycloak, MAS, Twitter, etc.) you must supply `issuer_url` explicitly: + +```yaml +matrix_tuwunel_config_identity_providers: + - brand: keycloak + client_id: matrix + client_secret: '' + issuer_url: https://sso.example.com/realms/matrix + callback_url: https://matrix.example.com/_matrix/client/unstable/login/sso/callback/matrix + trusted: true + - brand: github + client_id: '' + client_secret: '' +``` + +Self-hosted providers must supply both `client_id` and `issuer_url`. Set `trusted: true` only on providers you operate yourself; trusting a public provider (GitHub, Google, etc.) is an account-takeover risk. + +### LDAP + +Tuwunel can authenticate `m.login.password` requests against an LDAP directory and, in search-then-bind mode, keep admin status in sync with directory membership. The shipped image already includes the `ldap` build feature. + +```yaml +matrix_tuwunel_config_ldap_enabled: true +matrix_tuwunel_config_ldap_uri: ldaps://ldap.example.com:636 +matrix_tuwunel_config_ldap_base_dn: ou=users,dc=example,dc=org +matrix_tuwunel_config_ldap_bind_dn: cn=ldap-reader,dc=example,dc=org +matrix_tuwunel_config_ldap_bind_password_file: /etc/tuwunel/ldap.pw +matrix_tuwunel_config_ldap_filter: '(&(objectClass=person)(memberOf=cn=matrix,ou=groups,dc=example,dc=org))' +``` + +> [!NOTE] +> `bind_password_file` is read **inside the container**. The role bind-mounts `/matrix/tuwunel/config` to `/etc/tuwunel` (read-only) and `/matrix/tuwunel/data` to `/var/lib/tuwunel`. To make the file available at the path above, drop it on the host at `/matrix/tuwunel/config/ldap.pw` (owned by `matrix:matrix`) before running the playbook; the role does not template secret files for you. + +For direct-bind, anonymous-search, and admin-sync details, see [LDAP authentication](https://matrix-construct.github.io/tuwunel/authentication/ldap.html). + +### JWT login + +Tuwunel can accept signed JSON Web Tokens both as a login flow and as a User-Interactive Authentication step: + +```yaml +matrix_tuwunel_config_jwt_enabled: true +matrix_tuwunel_config_jwt_key: '' +matrix_tuwunel_config_jwt_format: HMAC # one of HMAC, B64HMAC, ECDSA, EDDSA +matrix_tuwunel_config_jwt_algorithm: HS256 +matrix_tuwunel_config_jwt_audience: ['matrix'] +matrix_tuwunel_config_jwt_issuer: ['https://issuer.example.com'] +``` + +The defaults match Synapse's `experimental_features.jwt_config` semantics, so a key + algorithm port should authenticate the same set of tokens. See [Enterprise JWT](https://matrix-construct.github.io/tuwunel/authentication/jwt.html) for the full reference, including the asymmetric (ECDSA / EdDSA) formats and the operator-controlled UIAA override flow. + +### Media storage providers + +Each entry becomes a `[global.storage_provider..]` block. `kind` is `local` or `s3`; the remaining keys map directly to the fields documented in [Storage providers](https://matrix-construct.github.io/tuwunel/media/storage.html): + +```yaml +matrix_tuwunel_config_storage_providers: + - id: primary + kind: local + base_path: /var/lib/tuwunel/media + + - id: archive + kind: s3 + url: s3://my-bucket/media + region: us-east-1 + key: AKIA... + secret: '' + multipart_threshold: 100 MiB +``` + +The S3 backend ships with native multipart upload, so no goofys/rclone sidecar is required. MinIO, Cloudflare R2, and DigitalOcean Spaces all work; set `endpoint` and `use_vhost_request: false` as appropriate. + +> [!NOTE] +> Local provider paths must live under `/var/lib/tuwunel` (the container's data mount, persisted on the host at `/matrix/tuwunel/data`), or you must mount the target directory into the container yourself via `matrix_tuwunel_container_extra_arguments`. The container otherwise runs read-only. + +### RocksDB and cache tuning + +Tuwunel embeds RocksDB. The defaults (`rocksdb_compression_algo: zstd`) suit most deployments. For high-throughput servers you may want to enable direct I/O, raise parallelism, and configure a backup path: + +```yaml +matrix_tuwunel_config_rocksdb_direct_io: true +matrix_tuwunel_config_rocksdb_parallelism_threads: 8 +matrix_tuwunel_config_database_backup_path: /var/lib/tuwunel/backups +``` + +`matrix_tuwunel_config_cache_capacity_modifier` is left empty by default, so Tuwunel picks a value (`1.0` since v1.7.0, with rebalanced per-cache sizes that already raise memory use). Set it to `2.0` only on small hosts with four or fewer cores; on larger machines the default is recommended. + +If you run on ZFS, the [Tuwunel maintenance guide](https://matrix-construct.github.io/tuwunel/maintenance.html#zfs) lists the dataset properties (`recordsize`, `primarycache`, `compression`, `atime`, `logbias`) and config flags (`rocksdb_direct_io`, `rocksdb_allow_fallocate`) you need to adjust to avoid severe write amplification. + +To enable Sentry crash reporting, set `matrix_tuwunel_config_sentry_enabled: true`. + +### Federation gating + +Tuwunel accepts regular-expression patterns at every level of remote-server filtering: + +```yaml +matrix_tuwunel_config_forbidden_remote_server_names: + - 'bad\.example\.com$' +matrix_tuwunel_config_forbidden_remote_room_directory_server_names: + - 'spam\.example\.com$' +matrix_tuwunel_config_prevent_media_downloads_from: + - 'heavy\.example\.com$' +``` + +Tuwunel additionally implements [MSC4284 policy servers](https://github.com/matrix-org/matrix-spec-proposals/pull/4284) for room-level federation gating. The policy itself lives in room state, but enforcement is opt-in at the server level: + +```yaml +matrix_tuwunel_config_enable_policy_servers: true +matrix_tuwunel_config_policy_server_request_timeout: 5 +``` + +When enabled, rooms with a valid `m.room.policy` state event have outgoing events signed by the configured policy server before federation. Transient network or timeout failures fail open (with a warn log), so a policy-server outage will not silently take the room offline. + +### Default room version + +The role sets `default_room_version: '12'`, so newly created rooms default to Matrix [room version 12](https://github.com/matrix-org/matrix-spec-proposals/pull/4289) ("Hydra"). Override `matrix_tuwunel_config_default_room_version` if you need an earlier version for client compatibility. + +### The `/_tuwunel` API path + +Besides `/_matrix`, Tuwunel serves its own first-party routes under `/_tuwunel`. This namespace carries ad-hoc endpoints such as `/_tuwunel/server_version` and `/_tuwunel/local_user_count`, and the [native OpenID Connect provider](https://matrix-construct.github.io/tuwunel/authentication/oidc-server.html) endpoints (`/_tuwunel/oidc/...`) that clients use when Tuwunel handles OIDC login itself, rather than delegating to an upstream provider as described above. The role routes `/_tuwunel` on the public entrypoint by default so these features work out of the box. + +To keep this namespace off the public entrypoint and expose it only on the internal one, set: + +```yaml +matrix_tuwunel_container_labels_public_tuwunel_api_enabled: false +matrix_tuwunel_container_labels_internal_tuwunel_api_enabled: true +``` + +### Exposing the Administration API + +Tuwunel serves a Synapse-compatible Administration API under the `/_synapse/admin` path, so administration dashboards (such as synapse-admin and ketesa) and moderation bots (such as Draupnir and Meowlnir) work against it. The served endpoints are listed on the [Tuwunel Synapse Admin API page](https://matrix-construct.github.io/tuwunel/development/compliance/synapse-admin.html). + +The API is not routed through the reverse proxy by default. Every endpoint requires an administrator access token, but you may still prefer to keep it off the public entrypoint. To reach it only from trusted networks, expose it on the internal Traefik entrypoint: + +```yaml +matrix_tuwunel_container_labels_internal_client_synapse_admin_api_enabled: true +``` + +To expose it publicly instead (for example, when a dashboard runs in the browser), set: + +```yaml +matrix_tuwunel_container_labels_public_client_synapse_admin_api_enabled: true +``` + +## Creating the first user account + +Unlike Synapse and Dendrite, Tuwunel does not register users from the command line or via the playbook. On first startup it logs a one-time-use registration token to its journal: + +```sh +# Adjust the duration if necessary or remove the --since argument. +journalctl -u matrix-tuwunel.service --since="10 minutes ago" +``` + +Use the token to create your first account from any client that supports token-gated registration (e.g. [Element Web](configuring-playbook-client-element-web.md)). The account is auto-promoted to admin and invited to the admin room together with the `@conduit:` server bot. The bot keeps the legacy `conduit` localpart due to the project's lineage from Conduit. + +## Configuring bridges and appservices + +The playbook does not auto-register appservices for Tuwunel. After your bridge has produced its `registration.yaml` (e.g. `/matrix/mautrix-signal/bridge/registration.yaml`), register it manually by sending the contents to the admin room, prefixed with `!admin appservices register` and wrapped in a fenced code block: + + !admin appservices register + ``` + id: signal + url: http://matrix-mautrix-signal:29328 + as_token: + hs_token: + sender_localpart: _bot_signalbot + rate_limited: false + namespaces: + users: + - exclusive: true + regex: '^@signal_.+:example\.org$' + - exclusive: true + regex: '^@signalbot:example\.org$' + aliases: + - exclusive: true + regex: '^#signal_.+:example\.org$' + ``` + +Registrations stored this way are persisted in the database and survive restarts. Re-running the command with the same `id` replaces the existing entry. See [Application services](https://matrix-construct.github.io/tuwunel/appservices.html) for the full reference and admin commands. + +## Migrating from conduwuit + +Tuwunel is a "binary swap" for conduwuit; it reads conduwuit's RocksDB layout directly, so migration is a data move, not an export/import. + +1. Set `matrix_homeserver_implementation: tuwunel` on `vars.yml` and remove any `matrix_conduwuit_*` overrides. +2. Run a full installation so that the new service is created and the old one removed (e.g. `just setup-all`). +3. Run `just run-tags tuwunel-migrate-from-conduwuit`. + +The migration stops `matrix-conduwuit.service`, copies `/matrix/conduwuit` into `/matrix/tuwunel`, renames the config file, and starts `matrix-tuwunel.service`. The freshly generated tuwunel data directory is preserved alongside as `/matrix/tuwunel_old` until you remove it manually. + +> [!CAUTION] +> Migrating from any other Conduit derivative (Conduit itself, Continuwuity, or any other fork) is **not supported** and will corrupt your database. All Conduit forks share the same linear database version with no awareness of each other; switching between them produces unrecoverable damage. See the [upstream migration table](https://matrix-construct.github.io/tuwunel/#migrating-to-tuwunel). + +## Troubleshooting + +As with all other services, the logs are available via [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html): + +```sh +journalctl -fu matrix-tuwunel +``` + +Logging verbosity is controlled by `matrix_tuwunel_config_log` in [`tracing-subscriber` env-filter syntax](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html). The default (`info,state_res=warn`) is reasonable for production; for debugging, try `debug` or scope it tighter, e.g. `info,tuwunel_service::sending=debug`. + +For RocksDB-level issues, online backups, and offline backup procedures, see the [Tuwunel maintenance guide](https://matrix-construct.github.io/tuwunel/maintenance.html). For protocol-compliance state across MSCs, the spec, and Complement, the project's [compliance dashboard](https://matrix-construct.github.io/tuwunel/development/compliance.html) is the authoritative tracker. diff --git a/docs/configuring-playbook.md b/docs/configuring-playbook.md index 963af9c54..859f4fd5d 100644 --- a/docs/configuring-playbook.md +++ b/docs/configuring-playbook.md @@ -53,6 +53,8 @@ For a more custom setup, see the [Other configuration options](#other-configurat - [Configuring continuwuity](configuring-playbook-continuwuity.md), if you've switched to the [continuwuity](https://continuwuity.org) homeserver implementation + - [Configuring Tuwunel](configuring-playbook-tuwunel.md), if you've switched to the [Tuwunel](https://matrix-construct.github.io/tuwunel/) homeserver implementation + - [Configuring Dendrite](configuring-playbook-dendrite.md), if you've switched to the [Dendrite](https://matrix-org.github.io/dendrite) homeserver implementation - Server components: @@ -87,12 +89,14 @@ Web clients for Matrix that you can host on your own domains. - [Setting up Cinny](configuring-playbook-client-cinny.md), if you've enabled [Cinny](https://github.com/ajbura/cinny), a web client focusing primarily on simple, elegant and secure interface -- [Setting up Sable](configuring-playbook-client-sable.md), if you've enabled [Sable](https://github.com/7w1/sable), a web client focusing primarily on simple, elegant and secure interface +- [Setting up Sable](configuring-playbook-client-sable.md), if you've enabled [Sable](https://github.com/SableClient/Sable), a web client focusing primarily on simple, elegant and secure interface - [Setting up SchildiChat Web](configuring-playbook-client-schildichat-web.md), if you've enabled [SchildiChat Web](https://schildi.chat/), a web client based on [Element Web](https://element.io/) with some extras and tweaks - [Setting up FluffyChat Web](configuring-playbook-client-fluffychat-web.md), if you've enabled [FluffyChat Web](https://github.com/krille-chan/fluffychat), a cute cross-platform messenger (web, iOS, Android) for Matrix written in [Flutter](https://flutter.dev/) +- [Setting up Commet](configuring-playbook-client-commet.md), if you've enabled [Commet](https://github.com/commetchat/commet), a Matrix web client + ### Authentication and user-related @@ -102,9 +106,7 @@ Extend and modify how users are authenticated on your homeserver. - [Setting up Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) -- [Setting up Synapse Admin](configuring-playbook-synapse-admin.md) - -- [Setting up matrix-registration](configuring-playbook-matrix-registration.md) +- [Setting up Ketesa](configuring-playbook-ketesa.md) - [Setting up the REST authentication password provider module](configuring-playbook-rest-auth.md) (advanced) @@ -112,8 +114,6 @@ Extend and modify how users are authenticated on your homeserver. - [Setting up the LDAP authentication password provider module](configuring-playbook-ldap-auth.md) (advanced) -- [Setting up matrix-ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md) (advanced) - - [Setting up Synapse Simple Antispam](configuring-playbook-synapse-simple-antispam.md) (advanced) - [Setting up Matrix User Verification Service](configuring-playbook-user-verification-service.md) (advanced) @@ -146,6 +146,10 @@ Bridges can be used to connect your Matrix installation with third-party communi - [Setting up Mautrix Google Messages bridging](configuring-playbook-bridge-mautrix-gmessages.md) +- [Setting up Mautrix Google Voice bridging](configuring-playbook-bridge-mautrix-gvoice.md) + +- [Setting up Mautrix LinkedIn bridging](configuring-playbook-bridge-mautrix-linkedin.md) + - [Setting up Mautrix Whatsapp bridging](configuring-playbook-bridge-mautrix-whatsapp.md) - [Setting up Instagram bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-instagram.md) @@ -160,13 +164,13 @@ Bridges can be used to connect your Matrix installation with third-party communi - [Setting up Mautrix wsproxy for bridging Android SMS or Apple iMessage](configuring-playbook-bridge-mautrix-wsproxy.md) +- [Setting up RustPush (iMessage) bridging](configuring-playbook-bridge-rustpush.md) + - [Setting up Appservice IRC bridging](configuring-playbook-bridge-appservice-irc.md) - [Setting up Appservice Discord bridging](configuring-playbook-bridge-appservice-discord.md) -- [Setting up Appservice Kakaotalk bridging](configuring-playbook-bridge-appservice-kakaotalk.md) - -- [Setting up Beeper LinkedIn bridging](configuring-playbook-bridge-beeper-linkedin.md) +- [Setting up Beeper LINE bridging](configuring-playbook-bridge-beeper-line.md) - [Setting up matrix-hookshot](configuring-playbook-bridge-hookshot.md) — a bridge between Matrix and multiple project management services, such as [GitHub](https://github.com), [GitLab](https://about.gitlab.com) and [JIRA](https://www.atlassian.com/software/jira). @@ -182,18 +186,18 @@ Bridges can be used to connect your Matrix installation with third-party communi - [Setting up Heisenbridge bouncer-style IRC bridging](configuring-playbook-bridge-heisenbridge.md) +- [Setting up a Matrix <-> Meshtastic bridge](configuring-playbook-bridge-meshtastic-relay.md) + - [Setting up WeChat bridging](configuring-playbook-bridge-wechat.md) ### Bots Bots provide various additional functionality to your installation. -- [Setting up baibot](configuring-playbook-bot-baibot.md) — a bot through which you can talk to various [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) services ([OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/) and [others](https://github.com/etkecc/baibot/blob/main/docs/providers.md)) +- [Setting up baibot](configuring-playbook-bot-baibot.md) — a bot through which you can talk to various [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) services (the privacy-first [Venice](configuring-playbook-bot-baibot.md#venice) we recommend, [OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/), and [others](https://github.com/etkecc/baibot/blob/main/docs/providers.md)) - [Setting up matrix-reminder-bot](configuring-playbook-bot-matrix-reminder-bot.md) — a bot to remind you about stuff -- [Setting up matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md) — a bot to create and manage registration tokens to invite users - - [Setting up maubot](configuring-playbook-bot-maubot.md) — a plugin-based Matrix bot system - [Setting up Honoroit](configuring-playbook-bot-honoroit.md) — a helpdesk bot @@ -204,6 +208,8 @@ Bots provide various additional functionality to your installation. - [Setting up Draupnir for all/D4A](configuring-playbook-appservice-draupnir-for-all.md) — like the [Draupnir bot](configuring-playbook-bot-draupnir.md) mentioned above, but running in appservice mode and supporting multiple instances +- [Setting up Meowlnir](configuring-playbook-bot-meowlnir.md) — a moderation tool/bot which speaks the same policy list protocol as Draupnir and Mjolnir, but runs in appservice mode and can override policies coming from lists you do not control + - [Setting up Buscarron](configuring-playbook-bot-buscarron.md) — a bot you can use to send any form (HTTP POST, HTML) to a (encrypted) Matrix room ### Administration @@ -261,10 +267,14 @@ Various services that don't fit any other categories. - [Setting up the Sliding Sync proxy](configuring-playbook-sliding-sync-proxy.md) for clients which require Sliding Sync support (like old Element X versions, before it got switched to Simplified Sliding Sync) +- [Setting up Appservice Kakaotalk bridging](configuring-playbook-bridge-appservice-kakaotalk.md) (removed; the upstream repository has become unreachable and the component could only be installed by self-building it) + - [Setting up Appservice Slack bridging](configuring-playbook-bridge-appservice-slack.md) (removed; this component has been discontinued) - [Setting up Appservice Webhooks bridging](configuring-playbook-bridge-appservice-webhooks.md) (deprecated; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md)) +- [Setting up Beeper LinkedIn bridging](configuring-playbook-bridge-beeper-linkedin.md) (unmaintained; the [upstream repository](https://github.com/beeper/linkedin) has been archived. Consider [setting up Mautrix LinkedIn bridging](configuring-playbook-bridge-mautrix-linkedin.md)) + - [Setting up the Dimension integration manager](configuring-playbook-dimension.md) ([unmaintained](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2806#issuecomment-1673559299); after [installing](installing.md)) - [Setting up Email2Matrix](configuring-playbook-email2matrix.md) (removed; the author suggests taking a look at [Postmoogle](https://github.com/etkecc/postmoogle) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-postmoogle.md)) @@ -277,6 +287,12 @@ Various services that don't fit any other categories. - [Setting up matrix-bot-chatgpt](configuring-playbook-bot-chatgpt.md) (unmaintained; the bridge's author suggests taking a look at [baibot](https://github.com/etkecc/baibot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bot-baibot.md)) +- [Setting up matrix-ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md) (removed; the repository of the source code has been removed) + +- [Setting up matrix-registration](configuring-playbook-matrix-registration.md) (removed; this component has been unmaintained) + +- [Setting up matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md) (removed; this component has been unmaintained) + - [Setting up Mautrix Facebook bridging](configuring-playbook-bridge-mautrix-facebook.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-messenger](configuring-playbook-bridge-mautrix-meta-messenger.md)) - [Setting up Mautrix Instagram bridging](configuring-playbook-bridge-mautrix-instagram.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-instagram](configuring-playbook-bridge-mautrix-meta-instagram.md)) diff --git a/docs/configuring-well-known.md b/docs/configuring-well-known.md index ec5ad90ce..3dabd2e28 100644 --- a/docs/configuring-well-known.md +++ b/docs/configuring-well-known.md @@ -104,6 +104,14 @@ All you need to do is: - set up the server at your base domain (e.g. `example.com`) so that it adds an extra HTTP header when serving the `/.well-known/matrix/client` file. [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), the `Access-Control-Allow-Origin` header should be set with a value of `*`. If you don't do this step, web-based Matrix clients (like Element Web) may fail to work. Setting up headers for the `/.well-known/matrix/server` file is not necessary, as this file is only consumed by non-browsers, which don't care about CORS. +- make sure the files are served with a `Content-Type: application/json` HTTP header. You can verify this by running `curl -i https://example.com/.well-known/matrix/client`. Some web servers serve extensionless files as plain text or even offer them as downloads, which breaks stricter clients such as Element X ([manifesting as errors like `MISSING_MATRIX_RTC_FOCUS`](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/4763)). On Apache-based hosting, you can force the correct content type by placing an `.htaccess` file next to the files: + + ```apache + + ForceType application/json + + ``` + This is relatively easy to do and possibly your only choice if you can only host static files from the base domain's server. It is, however, **a little fragile**, as future updates performed by this playbook may regenerate the well-known files and you may need to notice that and copy them over again. #### (Option 2): **Setting up reverse-proxying** of the well-known files from the base domain's server to the Matrix server @@ -112,7 +120,9 @@ This option is less fragile and generally better. On the base domain's server (e.g. `example.com`), you can set up reverse-proxying (or simply a 302 redirect), so that any access for the `/.well-known/matrix` location prefix is forwarded to the Matrix domain's server (e.g. `matrix.example.com`). -With this method, you **don't need** to add special HTTP headers for [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) reasons (like `Access-Control-Allow-Origin`), because your Matrix server (where requests ultimately go) will be configured by this playbook correctly. +With reverse-proxying, you **don't need** to add special HTTP headers for [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) reasons (like `Access-Control-Allow-Origin`), because your Matrix server (where requests ultimately go) will be configured by this playbook correctly. + +If you use a 302 redirect instead, be aware that browsers apply CORS checks to every response in the redirect chain, so the redirect response itself must also carry an `Access-Control-Allow-Origin: *` header. Otherwise, web-based Matrix clients (like Element Web) may fail to work even though the final destination sets the header correctly. **For nginx**, it would be something like this: @@ -155,6 +165,23 @@ example.com { } ``` +**Note**: Caddy does not process directives in the order they appear in the Caddyfile, but according to its own [directive order](https://caddyserver.com/docs/caddyfile/directives#directive-order). Notably, `redir` is evaluated before `reverse_proxy`, so a `redir` elsewhere in the same site block (a common way to send the base domain to `www.example.com` or to another site) takes precedence and breaks the well-known reverse-proxying. In such cases, wrap the directives in [`handle`](https://caddyserver.com/docs/caddyfile/directives/handle) blocks to enforce the intended priority: + +```caddy +example.com { + handle /.well-known/matrix/* { + reverse_proxy https://matrix.example.com { + header_up Host {upstream_hostport} + } + } + + handle { + # Everything else, e.g. a redirect to some other site + redir https://www.example.com{uri} + } +} +``` + **For HAProxy**, it would be something like this: ```haproxy diff --git a/docs/container-images.md b/docs/container-images.md index f4fd9b62f..d94ae7deb 100644 --- a/docs/container-images.md +++ b/docs/container-images.md @@ -28,6 +28,7 @@ We try to stick to official images (provided by their respective projects) as mu | [Synapse](configuring-playbook-synapse.md) | [element-hq/synapse](https://ghcr.io/element-hq/synapse) | ✅ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network | | [Conduit](configuring-playbook-conduit.md) | [matrixconduit/matrix-conduit](https://hub.docker.com/r/matrixconduit/matrix-conduit) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Conduit is a lightweight open-source server implementation of the Matrix Specification with a focus on easy setup and low system requirements | | [continuwuity](configuring-playbook-continuwuity.md) | [continuwuation/continuwuity](https://forgejo.ellis.link/continuwuation/continuwuity) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. continuwuity is a continuation of conduwuit. | +| [Tuwunel](configuring-playbook-tuwunel.md) | [matrix-construct/tuwunel](https://ghcr.io/matrix-construct/tuwunel) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Tuwunel is the official successor to conduwuit. | | [Dendrite](configuring-playbook-dendrite.md) | [matrixdotorg/dendrite-monolith](https://hub.docker.com/r/matrixdotorg/dendrite-monolith/) | ❌ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Dendrite is a second-generation Matrix homeserver written in Go, an alternative to Synapse. | ## Clients @@ -66,8 +67,6 @@ Extend and modify how users are authenticated on your homeserver. | [matrix-synapse-rest-auth](configuring-playbook-rest-auth.md) | (N/A) | ❌ | REST authentication password provider module | | [matrix-synapse-shared-secret-auth](configuring-playbook-shared-secret-auth.md) | (N/A) | ❌ | Password provider module | | [matrix-synapse-ldap3](configuring-playbook-ldap-auth.md) (advanced) | (N/A) | ❌ | LDAP Auth password provider module | -| [matrix-ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md) | [activism.international/matrix_ldap_registration_proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy/container_registry) | ❌ | Proxy that handles Matrix registration requests and forwards them to LDAP | -| [matrix-registration](configuring-playbook-matrix-registration.md) | [zeratax/matrix-registration](https://hub.docker.com/r/devture/zeratax-matrix-registration/) | ❌ | Simple python application to have a token based Matrix registration | | [Matrix User Verification Service](configuring-playbook-user-verification-service.md) | [matrixdotorg/matrix-user-verification-service](https://hub.docker.com/r/atrixdotorg/matrix-user-verification-service) | ❌ | Service to verify details of a user based on an Open ID token | | [synapse-simple-antispam](configuring-playbook-synapse-simple-antispam.md) (advanced) | (N/A) | ❌ | Spam checker module | @@ -92,6 +91,8 @@ Bridges can be used to connect your Matrix installation with third-party communi | [mautrix-slack](configuring-playbook-bridge-mautrix-slack.md) | [mautrix/slack](https://mau.dev/mautrix/slack/container_registry) | ❌ | Bridge to [Slack](https://slack.com/) | | [mautrix-telegram](configuring-playbook-bridge-mautrix-telegram.md) | [mautrix/telegram](https://mau.dev/mautrix/telegram/container_registry) | ❌ | Bridge to [Telegram](https://telegram.org/) | | [mautrix-gmessages](configuring-playbook-bridge-mautrix-gmessages.md) | [mautrix/gmessages](https://mau.dev/mautrix/gmessages/container_registry) | ❌ | Bridge to [Google Messages](https://messages.google.com/) | +| [mautrix-gvoice](configuring-playbook-bridge-mautrix-gvoice.md) | [mautrix/gvoice](https://mau.dev/mautrix/gvoice/container_registry) | ❌ | Bridge to [Google Voice](https://voice.google.com/) | +| [mautrix-linkedin](configuring-playbook-bridge-mautrix-linkedin.md) | [mautrix/linkedin](https://mau.dev/mautrix/linkedin/container_registry) | ❌ | Bridge to [LinkedIn](https://www.linkedin.com/) | | [mautrix-whatsapp](configuring-playbook-bridge-mautrix-whatsapp.md) | [mautrix/whatsapp](https://mau.dev/mautrix/whatsapp/container_registry) | ❌ | Bridge to [WhatsApp](https://www.whatsapp.com/) | | [mautrix-wsproxy](configuring-playbook-bridge-mautrix-wsproxy.md) | [mautrix/wsproxy](https://mau.dev/mautrix/wsproxy/container_registry) | ❌ | Bridge to Android SMS or Apple iMessage | | [mautrix-twitter](configuring-playbook-bridge-mautrix-twitter.md) | [mautrix/twitter](https://mau.dev/mautrix/twitter/container_registry) | ❌ | Bridge to [Twitter](https://twitter.com/) | @@ -99,8 +100,8 @@ Bridges can be used to connect your Matrix installation with third-party communi | mautrix-meta (for [Messenger](configuring-playbook-bridge-mautrix-meta-messenger.md) and [Instagram](configuring-playbook-bridge-mautrix-meta-instagram.md)) | [mautrix/meta](https://mau.dev/mautrix/meta/container_registry) | ❌ | Bridge to [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/) | | [mautrix-signal](configuring-playbook-bridge-mautrix-signal.md) | [mautrix/signal](https://mau.dev/mautrix/signal/container_registry) | ❌ | Bridge to [Signal](https://www.signal.org/) | | [beeper-linkedin](configuring-playbook-bridge-beeper-linkedin.md) | [beeper/linkedin](https://ghcr.io/beeper/linkedin) | ❌ | Bridge to [LinkedIn](https://www.linkedin.com/) | +| [beeper-line](configuring-playbook-bridge-beeper-line.md) | [crispyduck/beeper-line](https://hub.docker.com/r/crispyduck/beeper-line) | ❌ | Bridge to [LINE](https://line.me/) | | [matrix-appservice-irc](configuring-playbook-bridge-appservice-irc.md) | [matrixdotorg/matrix-appservice-irc](https://hub.docker.com/r/matrixdotorg/matrix-appservice-irc) | ❌ | Bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat) | -| [matrix-appservice-kakaotalk](configuring-playbook-bridge-appservice-kakaotalk.md) | Self-building | ❌ | Bridge to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG) | | [matrix-appservice-discord](configuring-playbook-bridge-appservice-discord.md) | [matrix-org/matrix-appservice-discord](https://ghcr.io/matrix-org/matrix-appservice-discord) | ❌ | Bridge to [Discord](https://discordapp.com/) | | [matrix-hookshot](configuring-playbook-bridge-hookshot.md) | [halfshot/matrix-hookshot](https://hub.docker.com/r/halfshot/matrix-hookshot) | ❌ | Bridge for generic webhooks and multiple project management services, such as GitHub, GitLab, Figma, and Jira in particular | | [matrix-sms-bridge](configuring-playbook-bridge-matrix-bridge-sms.md) | [folivonet/matrix-sms-bridge](https://hub.docker.com/repository/docker/folivonet/matrix-sms-bridge) | ❌ | Bridge to SMS | @@ -108,6 +109,7 @@ Bridges can be used to connect your Matrix installation with third-party communi | [Heisenbridge](configuring-playbook-bridge-heisenbridge.md) | [hif1/heisenbridge](https://hub.docker.com/r/hif1/heisenbridge) | ❌ | Bouncer-style bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat) | | [mx-puppet-groupme](configuring-playbook-bridge-mx-puppet-groupme.md) | [xangelix/mx-puppet-groupme](https://hub.docker.com/r/xangelix/mx-puppet-groupme) | ❌ | Bridge to [GroupMe](https://groupme.com/) | | [matrix-steam-bridge](configuring-playbook-bridge-steam.md) | [jasonlaguidice/matrix-steam-bridge](https://github.com/jasonlaguidice/matrix-steam-bridge/pkgs/container/matrix-steam-bridge) | ❌ | Bridge to [Steam](https://steampowered.com/) | +| [matrix-rustpush-bridge](configuring-playbook-bridge-rustpush.md) | [jasonlaguidice/imessage](https://github.com/jasonlaguidice/imessage/pkgs/container/imessage) | ❌ | Bridge to [iMessage](https://support.apple.com/messages) via Apple Push Notification service | | [mx-puppet-steam](configuring-playbook-bridge-mx-puppet-steam.md) | [icewind1991/mx-puppet-steam](https://hub.docker.com/r/icewind1991/mx-puppet-steam) | ❌ | Bridge to [Steam](https://steamapp.com/) | | [Postmoogle](configuring-playbook-bridge-postmoogle.md) | [etke.cc/postmoogle](https://github.com/etkecc/postmoogle/container_registry) | ❌ | Email to Matrix bridge | @@ -119,11 +121,11 @@ Bots provide various additional functionality to your installation. | ------- | --------------- | -------- | ----------- | | [baibot](configuring-playbook-bot-baibot.md) | [etke.cc/baibot](https://ghcr.io/etkecc/baibot) | ❌ | Bot that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you | | [matrix-reminder-bot](configuring-playbook-bot-matrix-reminder-bot.md) | [anoa/matrix-reminder-bot](https://hub.docker.com/r/anoa/matrix-reminder-bot) | ❌ | Bot for scheduling one-off & recurring reminders and alarms | -| [matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md) | [moanos/matrix-registration-bot](https://hub.docker.com/r/moanos/matrix-registration-bot/) | ❌ | Bot for invitations by creating and managing registration tokens | | [maubot](configuring-playbook-bot-maubot.md) | [dock.mau.dev/maubot/maubot](https://mau.dev/maubot/maubot/container_registry) | ❌ | Plugin-based Matrix bot system | | [Honoroit](configuring-playbook-bot-honoroit.md) | [etke.cc/honoroit](https://github.com/etkecc/honoroit/container_registry) | ❌ | Helpdesk bot | | [Mjolnir](configuring-playbook-bot-mjolnir.md) | [matrixdotorg/mjolnir](https://hub.docker.com/r/matrixdotorg/mjolnir) | ❌ | Moderation tool for Matrix | | [Draupnir](configuring-playbook-bot-draupnir.md) | [gnuxie/draupnir](https://hub.docker.com/r/gnuxie/draupnir) | ❌ | Moderation tool for Matrix (Fork of Mjolnir) | +| [Meowlnir](configuring-playbook-bot-meowlnir.md) | [maunium/meowlnir](https://mau.dev/maunium/meowlnir/container_registry) | ❌ | Moderation tool for Matrix, running in appservice mode | | [Buscarron](configuring-playbook-bot-buscarron.md) | [etke.cc/buscarron](https://ghcr.io/etkecc/buscarron) | ❌ | Web forms (HTTP POST) to Matrix | ## Administration @@ -134,7 +136,7 @@ Services that help you in administrating and monitoring your Matrix installation | ------- | --------------- | -------- | ----------- | | [matrix-alertmanager-receiver](configuring-playbook-alertmanager-receiver.md) | [metio/matrix-alertmanager-receiver](https://hub.docker.com/r/metio/matrix-alertmanager-receiver) | ❌ | Prometheus' [Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/) client | | [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) | [element-hq/matrix-authentication-service](https://ghcr.io/element-hq/matrix-authentication-service) | ❌ | OAuth 2.0 and OpenID Provider server | -| [synapse-admin](configuring-playbook-synapse-admin.md) | [etke.cc/synapse-admin](https://ghcr.io/etkecc/synapse-admin) | ❌ | Web UI tool for administrating users and rooms on your Matrix server | +| [Ketesa](configuring-playbook-ketesa.md) | [etkecc/ketesa](https://ghcr.io/etkecc/ketesa) | ❌ | Fully-featured web UI for administrating your Matrix homeserver — users, rooms, media, sessions, and more | | [Metrics and Graphs](configuring-playbook-prometheus-grafana.md) | [prom/prometheus](https://hub.docker.com/r/prom/prometheus/) | ❌ | [Prometheus](https://prometheus.io) time-series database server | | [Metrics and Graphs](configuring-playbook-prometheus-grafana.md) | [prom/node-exporter](https://hub.docker.com/r/prom/node-exporter/) | ❌ | Prometheus [node-exporter](https://prometheus.io/docs/guides/node-exporter/) host metrics exporter | | [Metrics and Graphs](configuring-playbook-prometheus-grafana.md) | [grafana/grafana](https://hub.docker.com/r/grafana/grafana/) | ❌ | Graphing tool that works well with the above two images. Our playbook also adds two dashboards for [Synapse](https://github.com/element-hq/synapse/tree/master/contrib/grafana) and [Node Exporter](https://github.com/rfrail3/grafana-dashboards) | @@ -153,10 +155,10 @@ Various services that don't fit any other categories. | [synapse_auto_compressor](configuring-playbook-synapse-auto-compressor.md) | [mb-saces/rust-synapse-tools](https://gitlab.com/mb-saces/rust-synapse-tools/container_registry) | ❌ | Cli tool that automatically compresses Synapse's `state_groups` database table in background | | [Matrix Corporal](configuring-playbook-matrix-corporal.md) (advanced) | [devture/matrix-corporal](https://hub.docker.com/r/devture/matrix-corporal/) | ❌ | Reconciliator and gateway for a managed Matrix server | | [Etherpad](configuring-playbook-etherpad.md) | [etherpad/etherpad](https://hub.docker.com/r/etherpad/etherpad/) | ❌ | Open source collaborative text editor | -| [Jitsi](configuring-playbook-jitsi.md) | [jitsi/web](https://hub.docker.com/r/jitsi/web) | ❌ | [Jitsi](https://jitsi.org/) web UI | -| [Jitsi](configuring-playbook-jitsi.md) | [jitsi/jicofo](https://hub.docker.com/r/jitsi/jicofo) | ❌ | [Jitsi](https://jitsi.org/) Focus component | -| [Jitsi](configuring-playbook-jitsi.md) | [jitsi/prosody](https://hub.docker.com/r/jitsi/prosody) | ❌ | [Jitsi](https://jitsi.org/) Prosody XMPP server component | -| [Jitsi](configuring-playbook-jitsi.md) | [jitsi/jvb](https://hub.docker.com/r/jitsi/jvb) | ❌ | [Jitsi](https://jitsi.org/) Video Bridge component | +| [Jitsi](configuring-playbook-jitsi.md) | [jitsi/web](https://github.com/jitsi/docker-jitsi-meet/pkgs/container/web) | ❌ | [Jitsi](https://jitsi.org/) web UI | +| [Jitsi](configuring-playbook-jitsi.md) | [jitsi/jicofo](https://github.com/jitsi/docker-jitsi-meet/pkgs/container/jicofo) | ❌ | [Jitsi](https://jitsi.org/) Focus component | +| [Jitsi](configuring-playbook-jitsi.md) | [jitsi/prosody](https://github.com/jitsi/docker-jitsi-meet/pkgs/container/prosody) | ❌ | [Jitsi](https://jitsi.org/) Prosody XMPP server component | +| [Jitsi](configuring-playbook-jitsi.md) | [jitsi/jvb](https://github.com/jitsi/docker-jitsi-meet/pkgs/container/jvb) | ❌ | [Jitsi](https://jitsi.org/) Video Bridge component | | [Cactus Comments](configuring-playbook-cactus-comments.md) | [cactuscomments/cactus-appservice](https://hub.docker.com/r/cactuscomments/cactus-appservice/) | ❌ | Federated comment system built on Matrix | | [Cactus Comments](configuring-playbook-cactus-comments.md) | [joseluisq/static-web-server](https://hub.docker.com/r/joseluisq/static-web-server) | ❌ | Federated comment system built on Matrix | | [Pantalaimon](configuring-playbook-pantalaimon.md) | [matrixdotorg/pantalaimon](https://hub.docker.com/r/matrixdotorg/pantalaimon) | ❌ | E2EE aware proxy daemon | @@ -178,6 +180,9 @@ The list of the deprecated or unmaintained services is available [here](configur | [matrix-appservice-slack](configuring-playbook-bridge-appservice-slack.md) | [matrixdotorg/matrix-appservice-slack](https://hub.docker.com/r/matrixdotorg/matrix-appservice-slack) | ❌ | Bridge to [Slack](https://slack.com/) | | [matrix-appservice-webhooks](configuring-playbook-bridge-appservice-webhooks.md) | [turt2live/matrix-appservice-webhooks](https://hub.docker.com/r/turt2live/matrix-appservice-webhooks) | ❌ | Bridge for slack compatible webhooks ([ConcourseCI](https://concourse-ci.org/), [Slack](https://slack.com/) etc. pp.) | | [matrix-chatgpt-bot](configuring-playbook-bot-chatgpt.md) | [matrixgpt/matrix-chatgpt-bot](https://ghcr.io/matrixgpt/matrix-chatgpt-bot) | ❌ | Accessing ChatGPT via your favourite Matrix client | +| [matrix-ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md) | [activism.international/matrix_ldap_registration_proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy/container_registry) | ❌ | Proxy that handles Matrix registration requests and forwards them to LDAP | +| [matrix-registration](configuring-playbook-matrix-registration.md) | [zeratax/matrix-registration](https://hub.docker.com/r/devture/zeratax-matrix-registration/) | ❌ | Simple python application to have a token based Matrix registration | +| [matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md) | [moanos/matrix-registration-bot](https://hub.docker.com/r/moanos/matrix-registration-bot/) | ❌ | Bot for invitations by creating and managing registration tokens | | [mautrix-facebook](configuring-playbook-bridge-mautrix-facebook.md) | [mautrix/facebook](https://mau.dev/mautrix/facebook/container_registry) | ❌ | Bridge to [Facebook](https://facebook.com/) | | [mautrix-instagram](configuring-playbook-bridge-mautrix-instagram.md) | [mautrix/instagram](https://mau.dev/mautrix/instagram/container_registry) | ❌ | Bridge to [Instagram](https://instagram.com/) | | [mx-puppet-discord](configuring-playbook-bridge-mx-puppet-discord.md) | [mx-puppet/discord/mx-puppet-discord](https://gitlab.com/mx-puppet/discord/mx-puppet-discord/container_registry) | ❌ | Bridge to [Discord](https://discordapp.com/) | diff --git a/docs/faq.md b/docs/faq.md index 309edfb8b..1e912b4e0 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -456,6 +456,12 @@ If it is correctly specified, look Traefik's logs (`journalctl -fu matrix-traefi ## Miscellaneous +### The role to manage the service which I deploy has been removed from the playbook. Does this mean that the service can no longer be used on my server? + +Not necessarily. Removing the role from the playbook does not always mean that the service has been deprecated by the upstream developers, so as long as the resource such as the Docker image is available, you should be able to keep running it by reverting the specific commit which has removed the role. This essentially means that you will need to maintain your own version of the playbook. + +Please keep in mind that you will occasionally need to fix code conflicts if any. + ### I would like to see this favorite service of mine integrated and become available on my Matrix server. How can I request it? You can freely create an issue for feature request on the repository at GitHub [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/new/choose). Note this is a community project with no financial backing, and there is not assurance that your request would be eventually picked up by others and the requested feature would become available. The easiest way to get a feature into this project is to just develop it yourself. diff --git a/docs/howto-server-delegation.md b/docs/howto-server-delegation.md index fb6a26f79..4c677b641 100644 --- a/docs/howto-server-delegation.md +++ b/docs/howto-server-delegation.md @@ -23,7 +23,7 @@ Both methods have their place and will continue to do so. You only need to use j For simplicity reasons, this playbook recommends you to set up server delegation via a `/.well-known/matrix/server` file. However, that method may have some downsides that are not to your liking. Hence this guide about alternative ways to set up Server Delegation. -**Note**: as an alternative, it is possible to install the server such that it uses only the `matrix.example.com` domain (instead of identifying as the shorter base domain — `example.com`). This should be helpful if you are not in control of anything on the base domain (`example.com`). In this case, you would not need to configure server delegation, but you would need to add other configuration. For more information, see [How do I install on matrix.example.com without involving the base domain?](faq.md#how-do-i-install-on-matrix-example-com-without-involving-the-base-domain) on our FAQ. +**Note**: as an alternative, it is possible to install the server such that it uses only the `matrix.example.com` domain (instead of identifying as the shorter base domain — `example.com`). This should be helpful if you are not in control of anything on the base domain (`example.com`). In this case, you would not need to configure server delegation, but you would need to add other configuration. For more information, see [How do I install on matrix.example.com without involving the base domain?](faq.md#how-do-i-install-on-matrixexamplecom-without-involving-the-base-domain) on our FAQ. ## Server Delegation via a well-known file diff --git a/docs/howto-srv-server-delegation.md b/docs/howto-srv-server-delegation.md index 5e0055c7e..cfd9989d8 100644 --- a/docs/howto-srv-server-delegation.md +++ b/docs/howto-srv-server-delegation.md @@ -26,7 +26,7 @@ The up-to-date list can be accessed on [traefik's documentation](https://doc.tra **Note**: the changes below instruct you how to do this for a basic Synapse installation. You will need to adapt the variable name and the content of the labels: -- if you're using another homeserver implementation (e.g. [Conduit](./configuring-playbook-conduit.md), [continuwuity](./configuring-playbook-continuwuity.md) or [Dendrite](./configuring-playbook-dendrite.md)) +- if you're using another homeserver implementation (e.g. [Conduit](./configuring-playbook-conduit.md), [continuwuity](./configuring-playbook-continuwuity.md), [Tuwunel](./configuring-playbook-tuwunel.md) or [Dendrite](./configuring-playbook-dendrite.md)) - if you're using [Synapse with workers enabled](./configuring-playbook-synapse.md#load-balancing-with-workers) (`matrix_synapse_workers_enabled: true`). In that case, it's actually the `matrix-synapse-reverse-proxy-companion` service which has Traefik labels attached Also, all instructions below are from an older version of the playbook and may not work anymore. @@ -49,8 +49,8 @@ This is because the Matrix specification expects the federation endpoint to be s ```yaml # To let Traefik know which domains' certificates to serve matrix_synapse_container_labels_additional_labels: | - traefik.http.routers.matrix-synapse-federation-api.tls.domains.main="example.com" - traefik.http.routers.matrix-synapse-federation-api.tls.domains.sans="*.example.com" + traefik.http.routers.matrix-synapse-public-federation-api.tls.domains.main="example.com" + traefik.http.routers.matrix-synapse-public-federation-api.tls.domains.sans="*.example.com" ``` ### Configure the DNS-01 challenge for let's encrypt @@ -137,8 +137,8 @@ matrix_synapse_container_labels_public_federation_api_traefik_rule: PathPrefix(` # To let Traefik know which domains' certificates to serve matrix_synapse_container_labels_additional_labels: | - traefik.http.routers.matrix-synapse-federation-api.tls.domains.main="example.com" - traefik.http.routers.matrix-synapse-federation-api.tls.domains.sans="*.example.com" + traefik.http.routers.matrix-synapse-public-federation-api.tls.domains.main="example.com" + traefik.http.routers.matrix-synapse-public-federation-api.tls.domains.sans="*.example.com" # Add a new ACME configuration without having to disable the default one, since it would have a wide range of side effects traefik_configuration_extension_yaml: | diff --git a/docs/importing-postgres.md b/docs/importing-postgres.md index a27c7d6d5..c9d0d72e2 100644 --- a/docs/importing-postgres.md +++ b/docs/importing-postgres.md @@ -25,6 +25,11 @@ The migration might be a good moment, to "reset" a not properly working bridge. Before doing the actual import, **you need to upload your Postgres dump file to the server** (any path is okay). +> [!WARNING] +> Do not import into a database that already contains tables (e.g. one that a service has already initialized and used). As the [official Synapse backup guide](https://element-hq.github.io/synapse/latest/usage/administration/backups.html) puts it: at best this will error, at worst it will lead to subtle database inconsistencies. Import into an empty (freshly created) database instead. + +**Note for Synapse users restoring an older backup**: if the server kept running (and users kept chatting) after the backup you are restoring was made, truncate the `e2e_one_time_keys_json` table after importing and before starting Synapse. Restoring an older backup can otherwise cause already-used one-time keys to be re-issued, leading to message decryption errors for your users. You can do this by [getting a database terminal](maintenance-postgres.md#getting-a-database-terminal), connecting to the Synapse database (`\c synapse`) and running `TRUNCATE e2e_one_time_keys_json;`. Clients will generate and upload fresh one-time keys automatically. + ## Importing To import, run this command (make sure to replace `SERVER_PATH_TO_POSTGRES_DUMP_FILE` with a file path on your server): diff --git a/docs/importing-synapse-media-store.md b/docs/importing-synapse-media-store.md index 08993f952..e06daf639 100644 --- a/docs/importing-synapse-media-store.md +++ b/docs/importing-synapse-media-store.md @@ -13,6 +13,8 @@ You can manually import your `media_store` files from a previous installation of Before doing the actual data restore, **you need to upload your media store directory to the server** (any path is okay). +You also need the [rsync](https://rsync.samba.org/) utility installed **on the server**, as the import performs a server-side `rsync` synchronization. The playbook does not install it for you. On most distributions, it is available as a package called `rsync`. + If you are [storing Matrix media files on Amazon S3](configuring-playbook-s3.md) (optional), restoring with this tool is not possible right now. As an alternative, you can perform a manual restore using the [AWS CLI tool](https://aws.amazon.com/cli/) (e.g. `aws s3 sync /path/to/server/media_store/. s3://name-of-bucket/`) diff --git a/docs/installing.md b/docs/installing.md index 9bbfd5873..cf78ad6ac 100644 --- a/docs/installing.md +++ b/docs/installing.md @@ -1,13 +1,13 @@ @@ -27,7 +27,7 @@ To update your playbook directory and all upstream Ansible roles (defined in the - either: `just update` - or: a combination of `git pull` and `just roles` (or `make roles` if you have `make` program on your computer instead of `just`) -If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly: `rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force` +If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly after updating the playbook: `git pull; rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force` For details about `just` commands, take a look at: [Running `just` commands](just.md). @@ -41,6 +41,8 @@ If you **don't** use SSH keys for authentication, but rather a regular password, If you **do** use SSH keys for authentication, **and** use a non-root user to *become* root (sudo), you may need to add `-K` (`--ask-become-pass`) to all Ansible commands. +Instead of typing the sudo password on each run (`-K`) or storing it in plain text in the inventory hosts file, you can also pull it from the [pass](https://www.passwordstore.org/) password manager by adding `ansible_become_password='{{ lookup("community.general.passwordstore", "path/to/password") }}'` to your host line. See the [passwordstore lookup documentation](https://docs.ansible.com/ansible/latest/collections/community/general/passwordstore_lookup.html) for more details. + There 2 ways to start the installation process — depending on whether you're [Installing a brand new server (without importing data)](#installing-a-brand-new-server-without-importing-data) or [Installing a server into which you'll import old data](#installing-a-server-into-which-youll-import-old-data). **Note**: if you are migrating from an old server to a new one, take a look at [this guide](maintenance-migrating.md) instead. This is an easier and more straightforward way than installing a server and importing old data into it. @@ -150,6 +152,12 @@ After completing the installation, you can: * or come say Hi in our support room — [#matrix-docker-ansible-deploy:devture.com](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com). You might learn something or get to help someone else new to Matrix hosting. - or help make this playbook better by contributing (code, documentation, or [coffee/beer](https://liberapay.com/s.pantaleev/donate)) +### Installing native Matrix clients on your computer + +As the playbook's aim is to help you to install and manage Matrix services on your server, if you are looking for dedicated native Matrix clients which run on your computer, you need to install ones by yourself. There is a convenient list which introduces known Matrix clients on this page: + +If you feel overwhelmed by the variety and the number of the available clients, you might want to install [**Komai**](https://github.com/etkecc/komai), a desktop-first Matrix chat application maintained by the team behind the playbook. It is stable, and just works without quirks! + ### ⚠️ Keep the playbook and services up-to-date While this playbook helps you to set up Matrix services and maintain them, it will **not** automatically run the maintenance task for you. You will need to update the playbook and re-run it **manually**. diff --git a/docs/maintenance-migrating.md b/docs/maintenance-migrating.md index 2b07201c4..9ef41f75b 100644 --- a/docs/maintenance-migrating.md +++ b/docs/maintenance-migrating.md @@ -37,7 +37,7 @@ cd /etc/systemd/system/ && systemctl disable --now matrix* ## Copy data directory to the new server -After you've confirmed that all services were stopped, copy the `/matrix` directory from the old server to the new server. When copying, make sure to preserve ownership and permissions (use `cp -p` or `rsync -ar`)! +After you've confirmed that all services were stopped, copy the `/matrix` directory from the old server to the new server. When copying, make sure to preserve ownership and permissions (use `cp -p` or `rsync -a`)! ## Adjust DNS records diff --git a/docs/maintenance-postgres.md b/docs/maintenance-postgres.md index 8c26669e0..720b3dae9 100644 --- a/docs/maintenance-postgres.md +++ b/docs/maintenance-postgres.md @@ -76,6 +76,8 @@ If you are using an [external Postgres server](configuring-playbook-external-pos Restoring a backup made this way can be done by [importing it](importing-postgres.md). +**Note for Synapse users**: the [official Synapse backup guide](https://element-hq.github.io/synapse/latest/usage/administration/backups.html) recommends that the `e2e_one_time_keys_json` table either not be backed up, or be truncated after restoring (before Synapse is started). The full-server dump command above does include it, so if you ever restore a backup that is older than the server's current state, remember to truncate that table as described in [the importing guide](importing-postgres.md). + ## Upgrading PostgreSQL Unless you are using an [external Postgres server](configuring-playbook-external-postgres.md), this playbook initially installs Postgres for you. diff --git a/docs/maintenance-synapse.md b/docs/maintenance-synapse.md index 7b7791227..9cd087def 100644 --- a/docs/maintenance-synapse.md +++ b/docs/maintenance-synapse.md @@ -105,6 +105,9 @@ Cache autotuning is **enabled by default** and controlled via the following vari You can **learn more about cache-autotuning and the global cache factor settings** in the [Synapse's documentation on caches and associated values](https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#caches-and-associated-values). +> [!NOTE] +> These limits apply **per Synapse process**. If you have [workers](configuring-playbook-synapse.md#load-balancing-with-workers) enabled, the main process and every worker each apply the configured limits independently, so the theoretical aggregate cache memory usage gets multiplied by the number of processes. When running many workers on a memory-constrained server, consider setting these variables to lower, explicitly chosen values. + To **disable cache auto-tuning**, unset all values: ```yaml diff --git a/docs/maintenance-upgrading-services.md b/docs/maintenance-upgrading-services.md index 7f0f1bc17..066333b6c 100644 --- a/docs/maintenance-upgrading-services.md +++ b/docs/maintenance-upgrading-services.md @@ -1,10 +1,10 @@ @@ -36,13 +36,25 @@ If it looks good to you, go to the `matrix-docker-ansible-deploy` directory, upd - either: `just update` - or: a combination of `git pull` and `just roles` (or `make roles` if you have `make` program on your computer instead of `just`) -If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly: `rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force` +If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly after updating the playbook: `git pull; rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force` **Note**: for details about `just` commands, take a look at: [Running `just` commands](just.md). +### Acknowledge breaking changes if any + +The playbook uses a migration validation system that ensures you are aware of breaking changes before they'll affect your deployment. If there is one, you are required to acknowledge each breaking change. + +Whenever a breaking change is introduced, the playbook will: + +- bump its expected version value (`matrix_playbook_migration_expected_version`), causing a discrepancy with what you validated (`matrix_playbook_migration_validated_version`) + +- fail when you run it with a helpful message listing what changed and linking to the relevant changelog entries + +After reviewing and adapting your setup, update the variable to the new version. + ### Re-run the playbook setup -After updating the Ansible roles, then re-run the [playbook setup](installing.md#maintaining-your-setup-in-the-future) and restart all services: +After updating the Ansible roles and the variable for the validation system when necessary, re-run the [playbook setup](installing.md#maintaining-your-setup-in-the-future) and restart all services: ```sh ansible-playbook -i inventory/hosts setup.yml --tags=install-all,start diff --git a/docs/molecule-testing.md b/docs/molecule-testing.md new file mode 100644 index 000000000..a5fe29cbc --- /dev/null +++ b/docs/molecule-testing.md @@ -0,0 +1,192 @@ + + +# Molecule testing for roles + +Roles in `roles/custom/` can carry a [Molecule](https://ansible.readthedocs.io/projects/molecule/) scenario, which installs the role into a container and then checks that the component actually came up with the configuration the role rendered. + +Not every role has one yet. Roles without a scenario are simply not tested. + +## Running a scenario + +```sh +just molecule # list roles that have a scenario +just molecule matrix-alertmanager-receiver # run one +just molecule matrix-alertmanager-receiver converge # any molecule subcommand +``` + +The first run creates a virtualenv in `var/molecule-venv/` (gitignored) from `molecule-shared/requirements.txt`. Docker must be working, and a run takes minutes because it pulls container images. + +`MOLECULE_DISTRO` selects the base image; it defaults to `ubuntu2604`. + +Molecule is deliberately **not** part of the `prek` hooks. A run is far too slow to sit in front of a commit, and it needs Docker. Run it when you have touched a role; CI runs it too, asynchronously. + +## What CI runs + +`.github/workflows/molecule.yml` does not run every scenario on every push — with one repository holding every role, that would be unaffordable. Its first job works out which roles the push actually touched, keeps the ones that have a scenario, and builds the job matrix from those. A documentation change runs nothing. + +When the diff base cannot be determined (a new branch, a force push), it falls back to running every scenario, which errs toward testing too much rather than too little. `workflow_dispatch` accepts an optional role name. + +## Automerge + +A role that has a scenario is listed in the Molecule patch-automerge rule in `.github/renovate.json`, so patch bumps of its component merge on their own once the scenario has passed on them. Some roles with a sufficiently weight-bearing compatibility gate are explicitly approved in a narrower minor-automerge rule too. Major updates are never included in these rules. + +Both rules use branch automerge: an update that passes its scenario merges without opening a pull request, while a failure surfaces as a pull request instead. + +**Add your role to the patch list when you add its scenario.** Add it to the minor list only when that broader policy has been explicitly approved and the scenario exercises enough real behavior to serve as a minor-release compatibility gate. `bin/check-molecule-automerge-list.py` runs from prek and fails the commit if the patch list and scenarios drift apart, or if a minor-automerge entry is not backed by both a scenario and the patch rule. + +## Writing a scenario + +Start from `roles/custom/matrix-alertmanager-receiver/molecule/default/` — it is the reference. Four things differ from a standalone role's scenario, all of them consequences of these roles living inside a playbook: + +### The playbook's context has to be supplied + +The role reads variables that `matrix-base` and `group_vars/matrix_servers` would normally provide. The set is small — `matrix_base_data_path`, `matrix_domain`, `matrix_user_name`, `matrix_group_name`, `matrix_user_uid`, `matrix_user_gid` — and belongs in the scenario's `group_vars`, rather than including `matrix-base`, which does much more than a role scenario needs. + +### The `matrix` user and group must exist first + +The roles' file tasks set `owner:` and `group:` by name, and Ansible resolves those through the passwd database, so `prepare.yml` has to create them before the role runs. + +### Most components need a homeserver to be present + +Many of these components contact the homeserver while starting up, and exit if it is unreachable — `matrix-alertmanager-receiver`, for example, fetches `/_matrix/client/v3/joined_rooms` to resolve its room mapping and exits with a failure if that call fails. + +A stub is enough, and is what the reference scenario stands up. The point of these scenarios is to prove that **the component starts and does not choke on the configuration the role rendered** — not to exercise real bridging. A scenario should never need a credential or an account on a third-party network; that is the line where it stops being a test of this repository. + +### `verify.yml` is a separate play + +Role defaults are out of scope there, so any path it reads has to be pinned in the scenario's `group_vars`. Deliberately do **not** pin the component's version that way: read it from the role's `defaults/main.yml` with `include_vars`, so the assertion compares the running image against what the role ships rather than against the scenario itself. + +## Shared files + +`molecule-shared/` holds what would otherwise be duplicated into every role: + +- `requirements.txt` — the Python packages, for both CI and `just molecule`. +- `requirements.yml` — the external Ansible roles and collections the scenarios need. Each scenario symlinks its own `molecule/default/requirements.yml` at this file: Molecule checks for a requirements file at that default path before it will install anything, so pointing at the shared one through `requirements-file` alone is silently ignored. +- `vars.yml` — helper container images used for probing, pinned once. They carry `# renovate:` annotations and a custom manager in `.github/renovate.json` keeps them current. + +A helper image is used to reach a role's container over its own container network. That indirection is deliberate: the roles publish no host port, matching a real deployment, and publishing one for the test would collide between scenarios running in parallel. + +## Making a scenario worth having + +A suite that only waits for the systemd unit to become `active` proves very little: these units carry `Restart=always`, so a container crash-looping on a bad configuration still reports `active`. Check the restart counter alongside it, and probe something the component can only answer correctly if the role's configuration reached it. + +Give the scenario values that differ from both the role's defaults and the component's own defaults. Otherwise a passing assertion cannot distinguish "the role configured this" from "it would have happened anyway". + +Then try to break it. If a scenario cannot be made to fail by deliberately breaking the thing it checks, it is not testing that thing. + +Falsify **every** assertion, not just enough of them to see the scenario go red. An assertion that +passes is not necessarily an assertion that works: one control here asserted that a component +emitted no DEBUG records from a particular module, and it passed just as happily with that module +set to `debug`, because the module emits none on a first run either way. It was green for the wrong +reason, and only breaking it deliberately exposed that. + +### Make a failure identify the broken control + +Write each independently falsifiable condition as its own item under `that`. Ansible evaluates the +items in order and reports the first false expression in its `assertion` result field. When several +conditions are folded into one expression with `and`, it can only report that whole expression: + +```yaml +that: + - service.status.ActiveState == 'active' + - service.status.NRestarts is defined + - service.status.NRestarts | int == 0 +``` + +Keeping related conditions in one assertion task is fine. Split them into separately named tasks +when they describe different operational claims or remedies — for example, the container image, +runtime identity, network attachment and published ports. `ansible.builtin.assert` runs on the +controller without connecting to the target, so the extra tasks add negligible runtime compared to +the probes that gathered the values. + +Falsify the real control by changing an observed input or an expected value. Adding a literal +`false` condition only proves that `ansible.builtin.assert` itself can fail; it does not prove that +the scenario detects the defect it claims to detect. + +Two traps make a falsification pass when it should fail: + +- `molecule converge` against an already-running instance rewrites the configuration but only does + `state: started`, so the container keeps the old one. Full `molecule test` is unaffected - this + bites the local iterate-with-converge loop, which is where falsifications get run. +- The failure must land on the assertion you aimed at. If it fails at an earlier gate, you have + proved something about that gate instead. + +### Work out whether the component crashes or retries + +Some components exit when their configuration is wrong; others catch everything and retry forever. +For the second kind, `ActiveState == active` and `NRestarts == 0` **both stay true while the +component is completely broken** - matrix-reminder-bot and baibot both behave this way, retrying a +failed login or profile step indefinitely. There the unit assertions prove nothing on their own, and +something the component says about itself has to carry the scenario. + +Establish which kind yours is before deciding what the weight-bearing assertion is. + +### Reading the journal + +Grep the whole journal rather than tailing it. Startup lines are the **oldest** entries, and a +component that syncs can bury them under thousands of lines within a minute, so `--lines=N` loses +exactly what you were looking for. Strip ANSI escapes too - some components colour their output, and +a plain substring match against raw journal text then fails silently. + +### Assert against parsed documents + +Where a scenario reads a rendered configuration, parse it and assert on the structure rather than +matching substrings. A value landing under the wrong key cannot then pass. + +## Running more than one scenario at once + +`bin/molecule.sh` points `ANSIBLE_HOME` at `var/molecule-ansible-home//`, so each role gets +its own copy of the Galaxy collections and roles. + +This is not an optimisation - it is a correctness fix. Scenarios install their dependencies with +`force: true`, so two runs sharing `~/.ansible` re-extract the same collections underneath each +other. The symptom is a collection that was working moments earlier going missing mid-play: + +``` +the connection plugin 'community.docker.docker' was not found +``` + +If you see that, a concurrent run took the collection out from under you. + +`ANSIBLE_HOME` is left alone if you have already set it, and is unset in CI - each role runs in its +own job there, so there is nothing to collide with. + +The directories are disposable; `var/` is gitignored. Delete `var/molecule-ansible-home/` to force +a fresh install. + +## Databases + +Scenarios for roles that have a database run against **Postgres**, not sqlite. + +That is what `group_vars/matrix_servers` selects whenever postgres is enabled, which is the +default, so it is what essentially every deployment runs. sqlite is a path almost nobody is on: +a bug that stopped the mautrix-meta bridges from starting at all under sqlite sat unreported +for a long time, which says plainly enough whose path is worth testing. + +`molecule-shared/tasks/postgres.yml` stands one up on the scenario's container network. Include +it from `prepare.yml` and point the role at it with its own `_database_engine`, `_database_hostname` +and credentials. Give the database and user names that differ from the role's defaults - then the +component reaching the database at all proves the role built its connection string out of them. + +The image is pinned in `molecule-shared/vars.yml` at the major the postgres role deploys to new +installations, and Renovate carries it forward. When a new major lands, the PR bumping that pin +runs every scenario against it, which is the earliest warning we get that a component does not +cope with it. + +Prefer asserting on the schema the component created over a file on disk: tables can only appear +once it has resolved the hostname, authenticated, and run its migrations. + +## Reclaiming the disk space + +`just molecule-clean` removes what the runs leave under `var/`. + +Two things live there. The per-role Ansible homes are ~7 MB each, rewritten on every run rather +than grown, so they are bounded by the number of roles that have a scenario. The shared virtualenv +is the bulk of it, over 500 MB, and is recreated on the next run at the cost of a `pip install`. + +`--idle-days N` restricts it to what has not been touched in N days, which is what makes it safe to +run unattended. `--yes` skips the confirmation. diff --git a/docs/quick-start.md b/docs/quick-start.md index ae9328f0a..8ad864c81 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -89,7 +89,23 @@ To install Matrix services with this playbook, you would at least need 2 configu For your convenience, we have prepared example files of them ([`vars.yml`](../examples/vars.yml) and [`hosts`](../examples/hosts)). -To start quickly based on these example files, go into the `matrix-docker-ansible-deploy` directory and follow the instructions below: +To start quickly based on these example files, go into the `matrix-docker-ansible-deploy` directory and initialize your configuration, either automatically or manually. + +To initialize it automatically (with the base domain and server address pre-filled and secrets generated for you), run: + +- either: `just add-inventory-host example.com 1.2.3.4` (if you have the [`just`](just.md) tool) +- or: `make add-inventory-host domain=example.com ip=1.2.3.4` (if you have the `make` program) + +… where `example.com` is your "base domain" (not `matrix.example.com`) and `1.2.3.4` is your server's external IP address (or domain name). + +Given a base domain of `example.com`, this creates: + +- an entry for `matrix.example.com` (the Matrix server's default hostname: `matrix.` + your base domain) in the inventory hosts file (`inventory/hosts`) +- a configuration file (`inventory/host_vars/matrix.example.com/vars.yml`) containing `matrix_domain: example.com` and automatically generated secrets + +Afterward, edit these 2 files to adjust them further, as necessary. Existing configuration is never overwritten (the command refuses to run if the host is already in your inventory), so it can also be used for adding more hosts later. + +To initialize it manually, follow the instructions below: 1. Create a directory to hold your configuration: `mkdir -p inventory/host_vars/matrix.example.com` where `example.com` is your "base domain" 2. Copy the sample configuration file: `cp examples/vars.yml inventory/host_vars/matrix.example.com/vars.yml` @@ -119,7 +135,7 @@ To update your playbook directory and all upstream Ansible roles, run: - either: `just update` - or: a combination of `git pull` and `just roles` (or `make roles` if you have `make` program on your computer instead of `just`) -If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly: `rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force` +If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly after updating the playbook: `git pull; rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force` ### Run installation command diff --git a/docs/registering-users.md b/docs/registering-users.md index aeecbd04b..e6479ae26 100644 --- a/docs/registering-users.md +++ b/docs/registering-users.md @@ -95,14 +95,7 @@ This `register-user` script actually invokes the `mas-cli manage register-user` ## Managing users via a Web UI -To manage users more easily (via a web user-interace), you can install [Synapse Admin](configuring-playbook-synapse-admin.md). - -> [!WARNING] -> If you're using [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md), note that user management via synapse-admin is not fully working yet. See the [Expectations](configuring-playbook-matrix-authentication-service.md#expectations) section for more information. - -## Letting certain users register on your private server - -If you'd rather **keep your server private** (public registration closed, as is the default), and **let certain people create accounts by themselves** (instead of creating user accounts manually like this), consider installing and making use of [matrix-registration](configuring-playbook-matrix-registration.md). +To manage users and your homeserver more easily (via a web interface), you can install [Ketesa](configuring-playbook-ketesa.md) — a fully-featured admin UI covering users, rooms, media, sessions, and MAS management. ## Enabling public user registration diff --git a/docs/self-building.md b/docs/self-building.md index 0d38e5f5a..fc725018f 100644 --- a/docs/self-building.md +++ b/docs/self-building.md @@ -26,22 +26,24 @@ Note that **not all components support self-building yet**. Possibly outdated list of roles where self-building the Docker image is currently possible: - `matrix-synapse` -- `matrix-synapse-admin` +- `matrix-ketesa` - `matrix-client-element` - `hydrogen` - `cinny` - `sable` -- `matrix-registration` - `coturn` - `matrix-corporal` - `exim-relay` - `matrix-bridge-hookshot` - `matrix-bridge-appservice-irc` - `matrix-bridge-beeper-linkedin` +- `matrix-bridge-beeper-line` - `matrix-bridge-mautrix-googlechat` - `matrix-bridge-mautrix-telegram` - `matrix-bridge-mautrix-signal` - `matrix-bridge-mautrix-gmessages` +- `matrix-bridge-mautrix-gvoice` +- `matrix-bridge-mautrix-linkedin` - `matrix-bridge-mautrix-whatsapp` - `matrix-bridge-mx-puppet-steam` - `matrix-bot-mjolnir` diff --git a/docs/style-guide.md b/docs/style-guide.md new file mode 100644 index 000000000..a288330a9 --- /dev/null +++ b/docs/style-guide.md @@ -0,0 +1,105 @@ + + +# Style guide for playbook developers + +This page describes the conventions used when developing this playbook and writing its documentation. Follow it when adding a new component (a role and its documentation page) or editing existing ones, so that everything stays consistent. + +The guide is meant for anyone preparing a contribution, humans and AI agents alike. If you find existing files that deviate from it, feel free to send a pull request bringing them in line. + +## Language + +- Write in English, using American spelling ("customize", not "customise"). +- Proper nouns are capitalized: Matrix, Element, Synapse, Ansible, Docker, Traefik, Postgres, Grafana, etc. Some projects deliberately brand themselves in lowercase (e.g. `baibot`, `rageshake`, `coturn`, `mautrix-telegram`) and keep their lowercase name even at the start of a sentence. When in doubt, follow the upstream project's own spelling. + +## Markdown style + +- Do not hard-wrap prose. Each paragraph is a single line in the source file, no matter how long. This keeps the source and the rendered result consistent and makes diffs and translations easier to work with. +- Number ordered lists sequentially (`1.`, `2.`, `3.`), instead of relying on the Markdown renderer to fix a repeated (`1.`, `1.`, `1.`) or wrong (`1.`, `2.`, `4.`) sequence. +- Use `-` for unordered lists. +- Wrap variable names, file paths, commands, domains, and service names in backticks (`` ` ``). +- Use fenced code blocks with a language hint (```` ```yaml ````, ```` ```sh ````) for configuration and command examples. +- Use relative links when linking between documentation pages (e.g. `[Configuring DNS](configuring-dns.md)`). +- Link to the upstream project's official documentation instead of duplicating its content (installation steps, distro-specific commands, etc.). Copied instructions go stale; links age much better. + +## Example values + +Use these placeholder values in documentation and code comments, so examples look the same everywhere: + +| What | Value | +|------|-------| +| base domain | `example.com` | +| Matrix server domain | `matrix.example.com` | +| another (federated) server | `example.org` | +| user IDs | `@alice:example.com`, `@bob:example.com` | +| room ID | `!qporfwt:example.com` | +| room alias | `#room:example.com` | + +The user and room ID values follow the examples in the [Matrix specification](https://spec.matrix.org/latest/#room-structure). Never use real domains, usernames, or tokens in examples. + +Component-specific identifiers (e.g. a bridge bot like `@telegrambot:example.com`) are fine where they make an example clearer. + +## Documentation page structure + +Each component gets its own documentation page: `docs/configuring-playbook-.md` (bridges use a `configuring-playbook-bridge-.md` file name, bots use `configuring-playbook-bot-.md`). + +A typical page looks like this, with sections appearing in this order (sections that do not apply can be omitted): + +```md +# Setting up ComponentName (optional) + +The playbook can install and configure [ComponentName](https://github.com/example/component) for you. + +See the project's [documentation](https://github.com/example/component/blob/main/README.md) to learn what it does and why it might be useful to you. + +## Prerequisites (optional) + +## Adjusting DNS records + +## Adjusting the playbook configuration + +### Extending the configuration + +## Installing + +## Usage + +## Troubleshooting +``` + +Notes: + +- Headings use sentence case ("Adjusting the playbook configuration", not "Adjusting The Playbook Configuration"). +- The "Adjusting the playbook configuration" section tells people to add configuration to their `inventory/host_vars/matrix.example.com/vars.yml` file and shows a minimal `yaml` example. +- The "Installing" section references [playbook tags](playbook-tags.md) and shows the `just` command or `ansible-playbook` invocation to run. +- Look at an existing page for a similar component (another bridge, bot, or service) and copy its structure. The mautrix bridge pages share common sections via [Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md), so bridge pages link there instead of repeating the shared content. + +## Adding a new component + +First, consider where the component belongs: + +- Matrix-specific components are developed as roles in this repository, under `roles/custom/`. +- Components that are not Matrix-specific should live as external roles, preferably in the [MASH organization](https://github.com/mother-of-all-self-hosting/), and get wired into the playbook via `requirements.yml`. +- For components that are not Matrix-specific, also consider whether they belong in this Matrix playbook at all, or rather in [mash-playbook](https://github.com/mother-of-all-self-hosting/mash-playbook). Certain components (like Grafana or backup tools) are suitable for both playbooks. If something is too far away from general usefulness on a Matrix server, we prefer not to include it here, and to only have it in mash-playbook. + +Besides the role itself and its documentation page, a new component touches a few other places. Make sure a pull request adding one covers all of them: + +1. The role, in `roles/custom/matrix-/` (or an external role wired via `requirements.yml`, as described above). +2. Role registration in `setup.yml`. +3. Wiring in `group_vars/matrix_servers`. Wire the component to the rest of the playbook there (referencing variables of other roles), but keep values that the role can construct by itself in the role's own `defaults/main.yml`. +4. The documentation page, `docs/configuring-playbook-.md`, linked from the table of contents in `docs/README.md`. +5. An entry in the supported services list in `README.md`. +6. A row in `docs/container-images.md`, if the component runs a container. +7. A `CHANGELOG.md` entry announcing the new component. +8. License headers: every new file carries `SPDX-FileCopyrightText` and `SPDX-License-Identifier` comments, as this project follows the [REUSE](https://reuse.software/) specification. + +Variable naming conventions: + +- The variable prefix matches the role directory name: the `matrix-bridge-mautrix-telegram` role uses `matrix_bridge_mautrix_telegram_*` variables, the `matrix-bot-mjolnir` role uses `matrix_bot_mjolnir_*` variables, and so on. +- List-type variables that the playbook may extend automatically follow the `_auto` + `_custom` split: the main variable combines an `_auto` component (managed by the playbook via `group_vars`) and a `_custom` component (reserved for users). Where it makes sense, there is also a `_default` component, containing sensible defaults provided by the role itself. See `matrix_bridge_hookshot_container_additional_networks` and `matrix_bridge_hookshot_systemd_required_services_list` for examples. +- When a variable is renamed or removed, deprecate it so that people with stale configuration get told about it instead of it being silently ignored. Each role deprecates its own variables, in its `validate_config.yml` tasks. The `matrix_playbook_migration` role handles the cases a role cannot: variables of completely eliminated roles (which no longer have their own `validate_config.yml`), and validation that needs to run very early for some reason. +- For breaking changes that require the user's attention (beyond a renamed variable that validation already catches), bump `matrix_playbook_migration_expected_version` and add a matching entry to the `matrix_playbook_migration_breaking_changes` list (a summary and a `CHANGELOG.md` link), in `roles/custom/matrix_playbook_migration/defaults/main.yml`. Users declare `matrix_playbook_migration_validated_version` in their configuration, and the playbook walks them through all breaking changes between their validated version and the expected one. Also update the recommended value in `examples/vars.yml`; a pre-commit check enforces that it matches the expected version. diff --git a/examples/reverse-proxies/caddy2-in-container/docker-compose.yaml b/examples/reverse-proxies/caddy2-in-container/docker-compose.yaml index d497660f9..ce20ba41b 100644 --- a/examples/reverse-proxies/caddy2-in-container/docker-compose.yaml +++ b/examples/reverse-proxies/caddy2-in-container/docker-compose.yaml @@ -19,7 +19,7 @@ services: volumes: - ./Caddyfile:/etc/caddy/Caddyfile # - ./site:/var/www - # Other configurations … + # Other configurations … networks: # add this as well diff --git a/examples/reverse-proxies/nginx-proxy-manager/README.md b/examples/reverse-proxies/nginx-proxy-manager/README.md index 1047ed615..db11755d7 100644 --- a/examples/reverse-proxies/nginx-proxy-manager/README.md +++ b/examples/reverse-proxies/nginx-proxy-manager/README.md @@ -1,7 +1,7 @@ " +#: ../../../docs/README.md:12 +msgid "⬇️ Installation guides " msgstr "" -#: ../../../docs/README.md:5 +#: ../../../docs/README.md:14 msgid "There are two installation guides available for beginners and advanced users." msgstr "" -#: ../../../docs/README.md:7 +#: ../../../docs/README.md:16 msgid "⚡ **[Quick start](quick-start.md) (for beginners)**: this is recommended for those who do not have an existing Matrix server and want to start quickly with \"opinionated defaults\"." msgstr "" -#: ../../../docs/README.md:9 +#: ../../../docs/README.md:18 msgid "**Full installation guide (for advanced users)**: if you need to import an existing Matrix server's data into the new server or want to learn more while setting up the server, follow this guide." msgstr "" -#: ../../../docs/README.md:11 +#: ../../../docs/README.md:20 msgid "[Prerequisites](prerequisites.md)" msgstr "" -#: ../../../docs/README.md:13 -msgid "[Configuring your DNS settings](configuring-dns.md)" +#: ../../../docs/README.md:22 +msgid "[Configuring DNS settings](configuring-dns.md)" msgstr "" -#: ../../../docs/README.md:15 +#: ../../../docs/README.md:24 msgid "[Getting the playbook](getting-the-playbook.md)" msgstr "" -#: ../../../docs/README.md:17 +#: ../../../docs/README.md:26 msgid "[Configuring the playbook](configuring-playbook.md)" msgstr "" -#: ../../../docs/README.md:19 +#: ../../../docs/README.md:28 msgid "[Installing](installing.md)" msgstr "" -#: ../../../docs/README.md:21 +#: ../../../docs/README.md:30 msgid "🛠️ Configuration options" msgstr "" -#: ../../../docs/README.md:28 +#: ../../../docs/README.md:37 msgid "You can check useful documentation for configuring components here: [Configuring the playbook](configuring-playbook.md)" msgstr "" -#: ../../../docs/README.md:30 +#: ../../../docs/README.md:39 msgid "[Administration](configuring-playbook.md#administration) — services that help you in administrating and monitoring your Matrix installation" msgstr "" -#: ../../../docs/README.md:32 +#: ../../../docs/README.md:41 msgid "[Authentication and user-related](configuring-playbook.md#authentication-and-user-related) — extend and modify how users are authenticated on your homeserver" msgstr "" -#: ../../../docs/README.md:34 +#: ../../../docs/README.md:43 msgid "[Bots](configuring-playbook.md#bots) — bots provide various additional functionality to your installation" msgstr "" -#: ../../../docs/README.md:36 +#: ../../../docs/README.md:45 msgid "[Bridges](configuring-playbook.md#bridging-other-networks) — bridges can be used to connect your Matrix installation with third-party communication networks" msgstr "" -#: ../../../docs/README.md:38 +#: ../../../docs/README.md:47 msgid "[Clients](configuring-playbook.md#clients) — web clients for Matrix that you can host on your own domains" msgstr "" -#: ../../../docs/README.md:40 +#: ../../../docs/README.md:49 msgid "[Core service adjustments](configuring-playbook.md#core-service-adjustments) — backbone of your Matrix system" msgstr "" -#: ../../../docs/README.md:42 +#: ../../../docs/README.md:51 msgid "[File Storage](configuring-playbook.md#file-storage) — use alternative file storage to the default `media_store` folder" msgstr "" -#: ../../../docs/README.md:46 +#: ../../../docs/README.md:55 msgid "[Other specialized services](configuring-playbook.md#other-specialized-services) — various services that don't fit any other categories" msgstr "" -#: ../../../docs/README.md:48 +#: ../../../docs/README.md:57 msgid "👨‍🔧 Maintenance" msgstr "" -#: ../../../docs/README.md:50 +#: ../../../docs/README.md:59 msgid "If your server and services experience issues, feel free to come to [our support room](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com) and ask for help." msgstr "" -#: ../../../docs/README.md:54 -msgid "[Checking if services work](maintenance-checking-services.md)" -msgstr "" - -#: ../../../docs/README.md:56 +#: ../../../docs/README.md:63 msgid "[Maintenance and Troubleshooting](maintenance-and-troubleshooting.md)" msgstr "" -#: ../../../docs/README.md:58 +#: ../../../docs/README.md:65 msgid "[PostgreSQL maintenance](maintenance-postgres.md)" msgstr "" -#: ../../../docs/README.md:60 +#: ../../../docs/README.md:67 msgid "[Synapse maintenance](maintenance-synapse.md)" msgstr "" -#: ../../../docs/README.md:62 +#: ../../../docs/README.md:69 msgid "[Upgrading services](maintenance-upgrading-services.md)" msgstr "" -#: ../../../docs/README.md:64 +#: ../../../docs/README.md:71 msgid "Other documentation pages " msgstr "" -#: ../../../docs/README.md:66 +#: ../../../docs/README.md:73 msgid "ℹ️ **[FAQ](faq.md)** — various Frequently Asked Questions about Matrix, with a focus on this Ansible playbook" msgstr "" -#: ../../../docs/README.md:70 +#: ../../../docs/README.md:77 msgid "[Alternative architectures](alternative-architectures.md)" msgstr "" -#: ../../../docs/README.md:72 +#: ../../../docs/README.md:79 msgid "[Container images used by the playbook](container-images.md)" msgstr "" -#: ../../../docs/README.md:74 +#: ../../../docs/README.md:81 msgid "[Obtaining an Access Token](obtaining-access-tokens.md)" msgstr "" -#: ../../../docs/README.md:76 +#: ../../../docs/README.md:83 msgid "[Playbook tags](playbook-tags.md)" msgstr "" -#: ../../../docs/README.md:78 +#: ../../../docs/README.md:85 msgid "[Registering users](registering-users.md)" msgstr "" -#: ../../../docs/README.md:80 +#: ../../../docs/README.md:87 msgid "[Running `just` commands](just.md)" msgstr "" -#: ../../../docs/README.md:82 +#: ../../../docs/README.md:89 msgid "[Self-building](self-building.md)" msgstr "" -#: ../../../docs/README.md:84 +#: ../../../docs/README.md:91 msgid "[Uninstalling](uninstalling.md)" msgstr "" -#: ../../../docs/README.md:86 +#: ../../../docs/README.md:93 msgid "[Updating users passwords](updating-users-passwords.md)" msgstr "" + +#: ../../../docs/README.md:95 +msgid "[Using Ansible for the playbook](ansible.md)" +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-appservice-draupnir-for-all.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-appservice-draupnir-for-all.po index cf34a967b..b83ed0435 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-appservice-draupnir-for-all.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-appservice-draupnir-for-all.po @@ -163,7 +163,7 @@ msgid "Granting Users the ability to use D4A" msgstr "" #: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:97 -msgid "Draupnir for all includes several security measures like that it only allows users that are on its allow list to ask for a bot. To add a user to this list we have 2 primary options. Using the chat to tell Draupnir to do this for us or if you want to automatically do it by sending `m.policy.rule.user` events that target the subject you want to allow provisioning for with the `org.matrix.mjolnir.allow` recomendation. Using the chat is recomended." +msgid "Draupnir for all includes several security measures like that it only allows users that are on its allow list to ask for a bot. To add a user to this list we have 2 primary options. Using the chat to tell Draupnir to do this for us or if you want to automatically do it by sending `m.policy.rule.user` events that target the subject you want to allow provisioning for with the `org.matrix.mjolnir.allow` recomendation. Using the chat is recommended." msgstr "" #: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:99 diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-baibot.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-baibot.po index e73266c27..d8a75de2d 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-baibot.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-baibot.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,431 +19,459 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-baibot.md:1 +#: ../../../docs/configuring-playbook-bot-baibot.md:8 msgid "Setting up baibot (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:8 +#: ../../../docs/configuring-playbook-bot-baibot.md:15 msgid "🤖 [baibot](https://github.com/etkecc/baibot) (pronounced bye-bot) is a [Matrix](https://matrix.org/) bot developed by [etke.cc](https://etke.cc/) that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you. 🤖" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:10 +#: ../../../docs/configuring-playbook-bot-baibot.md:17 msgid "It supports [OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/) models, as many well as other [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:12 +#: ../../../docs/configuring-playbook-bot-baibot.md:19 msgid "It's designed as a more private and [✨ featureful](https://github.com/etkecc/baibot/?tab=readme-ov-file#-features) alternative to [matrix-chatgpt-bot](./configuring-playbook-bot-chatgpt.md). See the [baibot](https://github.com/etkecc/baibot) project and its documentation for more information." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:14 +#: ../../../docs/configuring-playbook-bot-baibot.md:21 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:16 +#: ../../../docs/configuring-playbook-bot-baibot.md:23 msgid "API access to one or more LLM [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:18 +#: ../../../docs/configuring-playbook-bot-baibot.md:25 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:20 +#: ../../../docs/configuring-playbook-bot-baibot.md:27 msgid "There are **a lot of configuration options** (some required, some possibly required, some optional), so they're **split into multiple sections below**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:23 +#: ../../../docs/configuring-playbook-bot-baibot.md:30 msgid "[Base configuration](#base-configuration)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:24 +#: ../../../docs/configuring-playbook-bot-baibot.md:31 msgid "[👮‍♂️ Administrator configuration](#️-administrator-configuration)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:25 +#: ../../../docs/configuring-playbook-bot-baibot.md:32 msgid "[👥 Initial users configuration](#-initial-users-configuration)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:26 +#: ../../../docs/configuring-playbook-bot-baibot.md:33 msgid "[🤖 Configuring agents via Ansible](#-configuring-agents-via-ansible)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:27 +#: ../../../docs/configuring-playbook-bot-baibot.md:34 msgid "[🤝 Configuring initial default handlers](#-configuring-initial-default-handlers)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:29 +#: ../../../docs/configuring-playbook-bot-baibot.md:36 msgid "Depending on your current `vars.yml` file and desired configuration, **you may require more than just the [base configuration](#base-configuration)**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:31 +#: ../../../docs/configuring-playbook-bot-baibot.md:38 msgid "Base configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:33 +#: ../../../docs/configuring-playbook-bot-baibot.md:40 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:71 +#: ../../../docs/configuring-playbook-bot-baibot.md:42 +msgid "Authentication can be configured in one of two mutually-exclusive ways:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:44 +msgid "**Password authentication** (`matrix_bot_baibot_config_user_password`) - recommended for most playbook-managed setups, because it integrates with automatic user creation flow used by the playbook, and auto-creates the bot account" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:45 +msgid "**Access-token authentication** (`matrix_bot_baibot_config_user_access_token` + `matrix_bot_baibot_config_user_device_id`) - useful for specific [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md)/OIDC setups where password authentication is not available or not desired" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:47 +msgid "Even when [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) is enabled, password authentication is still typically the best fit for baibot if you're using a playbook-managed bot account." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:49 +msgid "For upstream details, see baibot's [🔐 Authentication](https://github.com/etkecc/baibot/blob/main/docs/configuration/authentication.md) documentation." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:97 msgid "As mentioned above, **this may not be enough**. Continue with the configuration sections below." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:73 +#: ../../../docs/configuring-playbook-bot-baibot.md:99 msgid "👮‍♂️ Administrator configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:75 -#: ../../../docs/configuring-playbook-bot-baibot.md:99 +#: ../../../docs/configuring-playbook-bot-baibot.md:101 +#: ../../../docs/configuring-playbook-bot-baibot.md:125 msgid "This is an addition to the [base configuration](#base-configuration)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:77 +#: ../../../docs/configuring-playbook-bot-baibot.md:103 msgid "To specify who is considered a bot [👮‍♂️ Administrator](https://github.com/etkecc/baibot/blob/main/docs/access.md#administrators), you either need to specify `matrix_bot_baibot_config_access_admin_patterns` or `matrix_admin`. The latter is a single variable which affects all bridges and bots." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:79 +#: ../../../docs/configuring-playbook-bot-baibot.md:105 msgid "If `matrix_admin` is already configured in your `vars.yml` configuration, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:81 -#: ../../../docs/configuring-playbook-bot-baibot.md:110 +#: ../../../docs/configuring-playbook-bot-baibot.md:107 +#: ../../../docs/configuring-playbook-bot-baibot.md:136 msgid "**If necessary**, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:95 +#: ../../../docs/configuring-playbook-bot-baibot.md:121 msgid "👥 Initial users configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:97 +#: ../../../docs/configuring-playbook-bot-baibot.md:123 msgid "By default, **all users on your homeserver are considered allowed users**. If that's OK, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:101 +#: ../../../docs/configuring-playbook-bot-baibot.md:127 msgid "To specify who is considered a bot [👥 User](https://github.com/etkecc/baibot/blob/main/docs/access.md#user), you may:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:103 +#: ../../../docs/configuring-playbook-bot-baibot.md:129 msgid "define an **initial** value for `matrix_bot_baibot_config_initial_global_config_user_patterns` Ansible variable, as shown below" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:104 +#: ../../../docs/configuring-playbook-bot-baibot.md:130 msgid "configure the list at runtime via the bot's `!bai access set-users SPACE_SEPARATED_PATTERNS` command" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:106 +#: ../../../docs/configuring-playbook-bot-baibot.md:132 msgid "Configuring `matrix_bot_baibot_config_initial_global_config_user_patterns` is optional, but it can be useful to pre-configure the bot with a list of users who should have access to the bot's features." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:108 +#: ../../../docs/configuring-playbook-bot-baibot.md:134 msgid "**Note**: Once initially configured, the allowed users list **cannot be managed via Ansible anymore**. It can only be managed subsequently via bot commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:122 +#: ../../../docs/configuring-playbook-bot-baibot.md:148 msgid "🤖 Configuring agents via Ansible" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:124 +#: ../../../docs/configuring-playbook-bot-baibot.md:150 msgid "You are **not required** to define agents [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration) via Ansible. **To get started quickly**, you can **skip this section and define agents at runtime via chat commands** (following the bot's guidance)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:126 +#: ../../../docs/configuring-playbook-bot-baibot.md:152 msgid "Privileged users (like the [👮‍♂️ Administrator](#️-administrator-configuration), but potentially others too — see the upstream [🔒 access](https://github.com/etkecc/baibot/blob/main/docs/access.md) documentation) can **define agents dynamically at any time** via chat commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:128 +#: ../../../docs/configuring-playbook-bot-baibot.md:154 msgid "The Ansible role includes preset variables for easily enabling some [🤖 agents](https://github.com/etkecc/baibot/blob/main/docs/agents.md) on various [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md) (e.g. OpenAI, etc)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:130 +#: ../../../docs/configuring-playbook-bot-baibot.md:156 msgid "Besides the presets, the Ansible role also includes support for configuring additional statically-defined agents via the `matrix_bot_baibot_config_agents_static_definitions_custom` Ansible variable." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:132 +#: ../../../docs/configuring-playbook-bot-baibot.md:158 msgid "Agents defined statically and those created dynamically (via chat) are named differently, so **conflict cannot arise**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:134 +#: ../../../docs/configuring-playbook-bot-baibot.md:160 msgid "Depending on your propensity for [GitOps](https://en.wikipedia.org/wiki/DevOps#GitOps), you may prefer to define agents statically via Ansible, or you may wish to do it dynamically via chat." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:136 +#: ../../../docs/configuring-playbook-bot-baibot.md:162 msgid "Before proceeding, we recommend reading the upstream documentation on [How to choose a provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#how-to-choose-a-provider). In short, it's probably best to go with [OpenAI](#openai)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:138 +#: ../../../docs/configuring-playbook-bot-baibot.md:164 msgid "Anthropic" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:140 +#: ../../../docs/configuring-playbook-bot-baibot.md:166 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [Anthropic provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#anthropic) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:142 -#: ../../../docs/configuring-playbook-bot-baibot.md:166 -#: ../../../docs/configuring-playbook-bot-baibot.md:197 -#: ../../../docs/configuring-playbook-bot-baibot.md:225 +#: ../../../docs/configuring-playbook-bot-baibot.md:168 +#: ../../../docs/configuring-playbook-bot-baibot.md:192 +#: ../../../docs/configuring-playbook-bot-baibot.md:223 +#: ../../../docs/configuring-playbook-bot-baibot.md:251 msgid "Here's an example **addition** to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:158 -#: ../../../docs/configuring-playbook-bot-baibot.md:189 +#: ../../../docs/configuring-playbook-bot-baibot.md:184 #: ../../../docs/configuring-playbook-bot-baibot.md:215 -#: ../../../docs/configuring-playbook-bot-baibot.md:243 +#: ../../../docs/configuring-playbook-bot-baibot.md:241 +#: ../../../docs/configuring-playbook-bot-baibot.md:275 msgid "If you'd like to use more than one model, take a look at the [Configuring additional agents (without a preset)](#configuring-additional-agents-without-a-preset) section below." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:160 -#: ../../../docs/configuring-playbook-bot-baibot.md:191 +#: ../../../docs/configuring-playbook-bot-baibot.md:186 #: ../../../docs/configuring-playbook-bot-baibot.md:217 -#: ../../../docs/configuring-playbook-bot-baibot.md:245 +#: ../../../docs/configuring-playbook-bot-baibot.md:243 +#: ../../../docs/configuring-playbook-bot-baibot.md:277 msgid "💡 You may also wish to use this new agent for [🤝 Configuring initial default handlers](#-configuring-initial-default-handlers)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:162 +#: ../../../docs/configuring-playbook-bot-baibot.md:188 msgid "Groq" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:164 +#: ../../../docs/configuring-playbook-bot-baibot.md:190 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [Groq provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#groq) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:187 +#: ../../../docs/configuring-playbook-bot-baibot.md:213 msgid "Because this is a [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agent, it will be given a `static/` ID prefix and will be named `static/groq`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:193 +#: ../../../docs/configuring-playbook-bot-baibot.md:219 msgid "Mistral" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:195 +#: ../../../docs/configuring-playbook-bot-baibot.md:221 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [🇫🇷 Mistral provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#mistral) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:213 +#: ../../../docs/configuring-playbook-bot-baibot.md:239 msgid "Because this is a [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agent, it will be given a `static/` ID prefix and will be named `static/mistral`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:219 +#: ../../../docs/configuring-playbook-bot-baibot.md:245 msgid "OpenAI" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:221 +#: ../../../docs/configuring-playbook-bot-baibot.md:247 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [OpenAI provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openai) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:223 +#: ../../../docs/configuring-playbook-bot-baibot.md:249 msgid "The OpenAI provider is **only meant to be used with OpenAI's official API** and compatibility with other services (which do not fully adhere to the OpenAI API spec completely) is limited. **If you're targeting an OpenAI-compatible service**, use the [OpenAI Compatible](#openai-compatible) provider instead." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:241 +#: ../../../docs/configuring-playbook-bot-baibot.md:273 msgid "Because this is a [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agent, it will be given a `static/` ID prefix and will be named `static/openai`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:247 +#: ../../../docs/configuring-playbook-bot-baibot.md:279 msgid "OpenAI Compatible" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:249 +#: ../../../docs/configuring-playbook-bot-baibot.md:281 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [OpenAI Compatible provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openai-compatible) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:251 +#: ../../../docs/configuring-playbook-bot-baibot.md:283 msgid "This provider allows you to use OpenAI-compatible API services like [OpenRouter](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openrouter), [Together AI](https://github.com/etkecc/baibot/blob/main/docs/providers.md#together-ai), etc." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:253 +#: ../../../docs/configuring-playbook-bot-baibot.md:285 msgid "Some of these popular services already have **shortcut** providers (see [supported providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md#supported-providers) leading to this one behind the scenes — this make it easier to get started." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:255 +#: ../../../docs/configuring-playbook-bot-baibot.md:287 msgid "As of this moment, the playbook does not include presets for any of these services, so you'll need to [Configuring additional agents (without a preset)](#configuring-additional-agents-without-a-preset)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:257 +#: ../../../docs/configuring-playbook-bot-baibot.md:289 msgid "Configuring additional agents (without a preset)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:259 +#: ../../../docs/configuring-playbook-bot-baibot.md:291 msgid "The Ansible role may be lacking preset variables for some [☁️ provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md), or you may wish to statically-define an agent on the same provider twice (or more) with different configuration." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:261 +#: ../../../docs/configuring-playbook-bot-baibot.md:293 msgid "It's possible to inject your own agent configuration using the `matrix_bot_baibot_config_agents_static_definitions_custom` Ansible variable." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:263 +#: ../../../docs/configuring-playbook-bot-baibot.md:295 msgid "You can also define providers at runtime, by chatting with the bot, so using Ansible is not a requirement." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:265 +#: ../../../docs/configuring-playbook-bot-baibot.md:297 msgid "Below is an an **example** demonstrating **statically-defining agents via Ansible without using presets**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:304 +#: ../../../docs/configuring-playbook-bot-baibot.md:336 msgid "Because these are [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agents, they will be given a `static/` ID prefix and will be named `static/my-openai-gpt-3.5-turbo-agent` and `static/my-ollama-agent`, respectively." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:306 +#: ../../../docs/configuring-playbook-bot-baibot.md:338 msgid "💡 To figure out what to put in the `config` section, refer to the [☁️ provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md) page, which contains **sample configuration YAML for each provider**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:308 +#: ../../../docs/configuring-playbook-bot-baibot.md:340 msgid "As with any [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md), defining them means they exist. To actually make use of them, they need to be configured as handlers globally or in a specific room — see [Mixing & matching models](https://github.com/etkecc/baibot/blob/main/docs/features.md#mixing--matching-models)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:310 +#: ../../../docs/configuring-playbook-bot-baibot.md:342 msgid "💡 You may also wish to use these new agents for [🤝 Configuring initial default handlers](#-configuring-initial-default-handlers)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:312 +#: ../../../docs/configuring-playbook-bot-baibot.md:344 msgid "🤝 Configuring initial default handlers" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:314 +#: ../../../docs/configuring-playbook-bot-baibot.md:346 msgid "This section is only useful if you're [🤖 Configuring agents via Ansible](#-configuring-agents-via-ansible), as it lets you put these agents to use as soon as the bot starts (by adjusting the bot's **initial global configuration**)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:316 +#: ../../../docs/configuring-playbook-bot-baibot.md:348 msgid "If you're not configuring agents via Ansible, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:318 +#: ../../../docs/configuring-playbook-bot-baibot.md:350 msgid "This section is only useful the first time around. **Once initially configured the global configuration cannot be managed Ansible**, but only via bot commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:320 +#: ../../../docs/configuring-playbook-bot-baibot.md:352 msgid "baibot supports [various purposes](https://github.com/etkecc/baibot/blob/main/docs/features.md):" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:322 +#: ../../../docs/configuring-playbook-bot-baibot.md:354 msgid "[💬 text-generation](https://github.com/etkecc/baibot/blob/main/docs/features.md#-text-generation): communicating with you via text" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:324 +#: ../../../docs/configuring-playbook-bot-baibot.md:356 msgid "[🦻 speech-to-text](https://github.com/etkecc/baibot/blob/main/docs/features.md#-speech-to-text): turning your voice messages into text" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:326 +#: ../../../docs/configuring-playbook-bot-baibot.md:358 msgid "[🗣️ text-to-speech](https://github.com/etkecc/baibot/blob/main/docs/features.md#-text-to-speech): turning bot or users text messages into voice messages" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:328 +#: ../../../docs/configuring-playbook-bot-baibot.md:360 msgid "[🖌️ image-generation](https://github.com/etkecc/baibot/blob/main/docs/features.md#-image-generation): generating images based on instructions" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:330 +#: ../../../docs/configuring-playbook-bot-baibot.md:362 msgid "❓ catch-all: special purposes, indicating use as a fallback (when no specific handler is configured)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:332 +#: ../../../docs/configuring-playbook-bot-baibot.md:364 msgid "[Mixing & matching models](https://github.com/etkecc/baibot/blob/main/docs/features.md#mixing--matching-models) is made possible by the bot's ability to have different [🤝 handlers](https://github.com/etkecc/baibot/blob/main/docs/configuration/handlers.md) configured for different purposes." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:334 +#: ../../../docs/configuring-playbook-bot-baibot.md:366 msgid "This configuration can be done as a global fallback, or per-room. Both of these [🛠️ configurations](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md) are managed at runtime (viat chat), but **the global configuration can have some initial defaults configured via Ansible**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:336 +#: ../../../docs/configuring-playbook-bot-baibot.md:368 msgid "You can configure the **initial values** for these via Ansible, via the `matrix_bot_baibot_config_initial_global_config_handler_*` variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:338 +#: ../../../docs/configuring-playbook-bot-baibot.md:370 msgid "Example **additional** `vars.yml` configuration:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:355 +#: ../../../docs/configuring-playbook-bot-baibot.md:387 msgid "**Note**: these are initial defaults for the bot's global configuration. As such, changing any of these values subsequently has no effect on the bot's behavior. **Once initially configured the global configuration cannot be managed Ansible**, but only via bot commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:357 +#: ../../../docs/configuring-playbook-bot-baibot.md:389 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:359 +#: ../../../docs/configuring-playbook-bot-baibot.md:391 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:361 +#: ../../../docs/configuring-playbook-bot-baibot.md:393 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:363 +#: ../../../docs/configuring-playbook-bot-baibot.md:395 msgid "`roles/custom/matrix-bot-baibot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:364 +#: ../../../docs/configuring-playbook-bot-baibot.md:396 msgid "`roles/custom/matrix-bot-baibot/templates/config.yaml.j2` for the bot's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_baibot_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:366 +#: ../../../docs/configuring-playbook-bot-baibot.md:398 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:368 +#: ../../../docs/configuring-playbook-bot-baibot.md:400 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:375 +#: ../../../docs/configuring-playbook-bot-baibot.md:407 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:377 -msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." +#: ../../../docs/configuring-playbook-bot-baibot.md:409 +msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account when password authentication is used." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:379 +#: ../../../docs/configuring-playbook-bot-baibot.md:411 +msgid "If you're using access-token authentication, the bot account must already exist and the configured token + device ID must match that account. This mode is mainly for MAS/OIDC setups where password-based bot login is not suitable." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:413 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:381 +#: ../../../docs/configuring-playbook-bot-baibot.md:415 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:383 -msgid "If you change the bot password (`matrix_bot_baibot_config_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_baibot_config_user_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-baibot.md:417 +msgid "If you change the bot password (`matrix_bot_baibot_config_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_baibot_config_user_password` to let the bot know its new password. (This note applies to password authentication mode.)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:385 +#: ../../../docs/configuring-playbook-bot-baibot.md:419 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:387 +#: ../../../docs/configuring-playbook-bot-baibot.md:421 msgid "To use the bot, invite it to any existing Matrix room (`/invite @baibot:example.com` where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:389 +#: ../../../docs/configuring-playbook-bot-baibot.md:423 msgid "If you're an allowed bot [👥 user](https://github.com/etkecc/baibot/blob/main/docs/access.md#user) (see [👥 Initial users configuration](#-initial-users-configuration)), the bot will accept your invitation and join the room." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:391 +#: ../../../docs/configuring-playbook-bot-baibot.md:425 msgid "After joining, the bot will introduce itself and show information about the [✨ features](https://github.com/etkecc/baibot/blob/main/docs/features.md) that are enabled for it." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:393 +#: ../../../docs/configuring-playbook-bot-baibot.md:427 msgid "If you've [🤖 configured one or more agents via Ansible](#-configuring-agents-via-ansible) and have [🤝 configured initial default handlers](#configuring-initial-default-handlers), the bot will immediately be able to make use of these agents for this new room. Otherwise, you will need to configure agents and/or handlers via chat commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:395 +#: ../../../docs/configuring-playbook-bot-baibot.md:429 msgid "Send `!bai help` to the bot in the room to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:397 +#: ../../../docs/configuring-playbook-bot-baibot.md:431 msgid "You can also refer to the upstream [baibot](https://github.com/etkecc/baibot) project's documentation." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:399 +#: ../../../docs/configuring-playbook-bot-baibot.md:433 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:401 -msgid "As with all other services, you can find service logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by running something like `journalctl -fu matrix-bot-baibot`" +#: ../../../docs/configuring-playbook-bot-baibot.md:435 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-baibot`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:403 -msgid "The default logging level for this service is `info`, but you can increase it to `debug` (or even `trace`) with the following additional configuration:" +#: ../../../docs/configuring-playbook-bot-baibot.md:437 +msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:417 +#: ../../../docs/configuring-playbook-bot-baibot.md:439 +msgid "The default logging level for this service is `info`. If you want to increase the verbosity to `debug` (or even `trace`), add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:453 msgid "**Alternatively**, you can use a single variable to set the logging level for all of the above (bot + all libraries):" msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-buscarron.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-buscarron.po index 0801dc12e..019aea3c1 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-buscarron.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-buscarron.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,156 +19,156 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-buscarron.md:1 +#: ../../../docs/configuring-playbook-bot-buscarron.md:9 msgid "Setting up Buscarron (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:3 +#: ../../../docs/configuring-playbook-bot-buscarron.md:11 msgid "The playbook can install and configure [Buscarron](https://github.com/etkecc/buscarron) for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:5 +#: ../../../docs/configuring-playbook-bot-buscarron.md:13 msgid "Buscarron is bot that receives HTTP POST submissions of web forms and forwards them to a Matrix room." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:7 +#: ../../../docs/configuring-playbook-bot-buscarron.md:15 msgid "See the project's [documentation](https://github.com/etkecc/buscarron/blob/main/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:9 +#: ../../../docs/configuring-playbook-bot-buscarron.md:17 msgid "Adjusting DNS records" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:11 +#: ../../../docs/configuring-playbook-bot-buscarron.md:19 msgid "By default, this playbook installs Buscarron on the `buscarron.` subdomain (`buscarron.example.com`) and requires you to create a CNAME record for `buscarron`, which targets `matrix.example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:13 +#: ../../../docs/configuring-playbook-bot-buscarron.md:21 msgid "When setting, replace `example.com` with your own." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:15 +#: ../../../docs/configuring-playbook-bot-buscarron.md:23 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:17 +#: ../../../docs/configuring-playbook-bot-buscarron.md:25 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:40 +#: ../../../docs/configuring-playbook-bot-buscarron.md:48 msgid "Adjusting the Buscarron URL (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:42 +#: ../../../docs/configuring-playbook-bot-buscarron.md:50 msgid "By tweaking the `matrix_bot_buscarron_hostname` and `matrix_bot_buscarron_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:44 +#: ../../../docs/configuring-playbook-bot-buscarron.md:52 msgid "Example additional configuration for your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:55 +#: ../../../docs/configuring-playbook-bot-buscarron.md:63 msgid "After changing the domain, **you may need to adjust your DNS** records to point the Buscarron domain to the Matrix server." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:57 +#: ../../../docs/configuring-playbook-bot-buscarron.md:65 msgid "If you've decided to reuse the `matrix.` domain, you won't need to do any extra DNS configuration." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:59 +#: ../../../docs/configuring-playbook-bot-buscarron.md:67 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:61 +#: ../../../docs/configuring-playbook-bot-buscarron.md:69 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:63 +#: ../../../docs/configuring-playbook-bot-buscarron.md:71 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:65 +#: ../../../docs/configuring-playbook-bot-buscarron.md:73 msgid "`roles/custom/matrix-bot-buscarron/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:67 +#: ../../../docs/configuring-playbook-bot-buscarron.md:75 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:69 +#: ../../../docs/configuring-playbook-bot-buscarron.md:77 msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:76 +#: ../../../docs/configuring-playbook-bot-buscarron.md:84 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:78 +#: ../../../docs/configuring-playbook-bot-buscarron.md:86 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:80 +#: ../../../docs/configuring-playbook-bot-buscarron.md:88 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:82 +#: ../../../docs/configuring-playbook-bot-buscarron.md:90 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:84 -msgid "If you change the bot password (`matrix_bot_buscarron_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_buscarron_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-buscarron.md:92 +msgid "If you change the bot password (`matrix_bot_buscarron_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_buscarron_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:86 +#: ../../../docs/configuring-playbook-bot-buscarron.md:94 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:88 +#: ../../../docs/configuring-playbook-bot-buscarron.md:96 msgid "To use the bot, invite it to the room you specified on your `vars.yml` file (`/invite @bot.buscarron:example.com` where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:90 +#: ../../../docs/configuring-playbook-bot-buscarron.md:98 msgid "After the bot joins the room, anyone can call the web form via HTTP POST method." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:92 +#: ../../../docs/configuring-playbook-bot-buscarron.md:100 msgid "Here is an example for the `contact` form:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:100 +#: ../../../docs/configuring-playbook-bot-buscarron.md:108 msgid "**Note**: to fight against spam, Buscarron is **very aggressive when it comes to banning** and will ban you if:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:102 +#: ../../../docs/configuring-playbook-bot-buscarron.md:110 msgid "you hit the homepage (HTTP `GET` request to `/`)" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:103 +#: ../../../docs/configuring-playbook-bot-buscarron.md:111 msgid "you submit a form to the wrong URL (`POST` request to `/non-existing-form`)" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:104 +#: ../../../docs/configuring-playbook-bot-buscarron.md:112 msgid "`hasemail` is enabled for the form (like in the example above) and you don't submit an `email` field" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:106 +#: ../../../docs/configuring-playbook-bot-buscarron.md:114 msgid "If you get banned, you'd need to restart the process by running the playbook with `--tags=start` or running `systemctl restart matrix-bot-buscarron` on the server." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:108 +#: ../../../docs/configuring-playbook-bot-buscarron.md:116 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:110 +#: ../../../docs/configuring-playbook-bot-buscarron.md:118 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-buscarron`." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:112 +#: ../../../docs/configuring-playbook-bot-buscarron.md:120 msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:114 +#: ../../../docs/configuring-playbook-bot-buscarron.md:122 msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-draupnir.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-draupnir.po index 0b48da629..af3f7216a 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-draupnir.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-draupnir.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,392 +19,421 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-draupnir.md:1 +#: ../../../docs/configuring-playbook-bot-draupnir.md:10 msgid "Setting up Draupnir (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:3 +#: ../../../docs/configuring-playbook-bot-draupnir.md:12 msgid "The playbook can install and configure the [Draupnir](https://github.com/the-draupnir-project/Draupnir) moderation bot for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:5 +#: ../../../docs/configuring-playbook-bot-draupnir.md:14 msgid "See the project's [documentation](https://the-draupnir-project.github.io/draupnir-documentation/) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:7 +#: ../../../docs/configuring-playbook-bot-draupnir.md:16 msgid "This documentation page is about installing Draupnir in bot mode. As an alternative, you can run a multi-instance Draupnir deployment by installing [Draupnir in appservice mode](./configuring-playbook-appservice-draupnir-for-all.md) (called Draupnir-for-all) instead." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:9 +#: ../../../docs/configuring-playbook-bot-draupnir.md:18 msgid "If your migrating from [Mjolnir](configuring-playbook-bot-mjolnir.md), skip to [this section](#migrating-from-mjolnir-only-required-if-migrating)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:11 +#: ../../../docs/configuring-playbook-bot-draupnir.md:20 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:13 +#: ../../../docs/configuring-playbook-bot-draupnir.md:22 msgid "Create a management room" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:15 +#: ../../../docs/configuring-playbook-bot-draupnir.md:24 msgid "Using your own account, create a new invite only room that you will use to manage the bot. This is the room where you will see the status of the bot and where you will send commands to the bot, such as the command to ban a user from another room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:17 +#: ../../../docs/configuring-playbook-bot-draupnir.md:26 msgid "[!WARNING] Anyone in this room can control the bot so it is important that you only invite trusted users to this room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:20 +#: ../../../docs/configuring-playbook-bot-draupnir.md:29 msgid "It is possible to make the management room encrypted (E2EE). If doing so, then you need to enable the native E2EE support (see [below](#native-e2ee-support))." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:22 +#: ../../../docs/configuring-playbook-bot-draupnir.md:31 msgid "Once you have created the room you need to copy the room ID so you can specify it on your `inventory/host_vars/matrix.example.com/vars.yml` file. In Element Web you can check the ID by going to the room's settings and clicking \"Advanced\". The room ID will look something like `!qporfwt:example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:24 +#: ../../../docs/configuring-playbook-bot-draupnir.md:33 msgid "End-to-End Encryption support" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:26 +#: ../../../docs/configuring-playbook-bot-draupnir.md:35 msgid "Decide whether you want to support having an encrypted management room or not. Draupnir can still protect encrypted rooms without encryption support enabled." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:28 +#: ../../../docs/configuring-playbook-bot-draupnir.md:37 msgid "Refer to Draupnir's [documentation](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#protecting-encrypted-rooms) for more details about why you might want to care about encryption support for protected rooms." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:30 +#: ../../../docs/configuring-playbook-bot-draupnir.md:39 msgid "Disable Pantalaimon for Draupnir (since v2.0.0; optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:32 +#: ../../../docs/configuring-playbook-bot-draupnir.md:41 msgid "It is known that running Draupnir along with Pantalaimon breaks all workflows that involve answering prompts with reactions." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:34 +#: ../../../docs/configuring-playbook-bot-draupnir.md:43 msgid "If you are updating Draupnir from v1.x.x and have enabled Pantalaimon for it, you can disable Pantalaimon in favor of the native E2EE support. To disable Pantalaimon, remove the configuration `matrix_bot_draupnir_pantalaimon_use: true` from your `vars.yml` file." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:36 +#: ../../../docs/configuring-playbook-bot-draupnir.md:45 msgid "**Note**: because the management room is still encrypted, disabling it without enabling the native E2EE support will break the management room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:38 +#: ../../../docs/configuring-playbook-bot-draupnir.md:47 msgid "Native E2EE support" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:40 +#: ../../../docs/configuring-playbook-bot-draupnir.md:49 msgid "To enable the native E2EE support, you need to obtain an access token for Draupnir and set it on your `vars.yml` file." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:42 +#: ../../../docs/configuring-playbook-bot-draupnir.md:51 msgid "Note that native E2EE requires a clean access token that has not touched E2EE so curl is recommended as a method to obtain it. **The access token obtained via Element Web does not work with it**. Refer to the documentation on [how to obtain an access token via curl](obtaining-access-tokens.md#obtain-an-access-token-via-curl)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:44 +#: ../../../docs/configuring-playbook-bot-draupnir.md:53 msgid "To enable the native E2EE support, add the following configuration to your `vars.yml` file. Make sure to replace `CLEAN_ACCESS_TOKEN_HERE` with the access token you obtained just now." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:55 +#: ../../../docs/configuring-playbook-bot-draupnir.md:64 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:57 +#: ../../../docs/configuring-playbook-bot-draupnir.md:66 msgid "To enable the bot, add the following configuration to your `vars.yml` file. Make sure to replace `MANAGEMENT_ROOM_ID_HERE` with the one of the room which you have created earlier." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:76 +#: ../../../docs/configuring-playbook-bot-draupnir.md:85 msgid "Create and invite the bot to the management room" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:78 +#: ../../../docs/configuring-playbook-bot-draupnir.md:87 msgid "Before proceeding to the next step, run the playbook with the following command to create the bot user." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:84 +#: ../../../docs/configuring-playbook-bot-draupnir.md:93 msgid "**Note**: the `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:86 +#: ../../../docs/configuring-playbook-bot-draupnir.md:95 msgid "Then, invite the bot (`@bot.draupnir:example.com`) to its management room which you have created earlier." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:88 +#: ../../../docs/configuring-playbook-bot-draupnir.md:97 msgid "Make sure the account is free from rate limiting (optional, recommended)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:90 +#: ../../../docs/configuring-playbook-bot-draupnir.md:99 msgid "If your homeserver's implementation is Synapse, you will need to prevent it from rate limiting the bot's account. **This is a highly recommended step. If you do not configure it, Draupnir performance will be degraded.**" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:92 +#: ../../../docs/configuring-playbook-bot-draupnir.md:101 msgid "This can be done using Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users). They can be accessed both externally and internally." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:94 +#: ../../../docs/configuring-playbook-bot-draupnir.md:103 msgid "**Note**: access to the APIs is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, doing so is not recommended for additional security. See [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:96 -msgid "The APIs can also be accessed via [Synapse Admin](https://github.com/etkecc/synapse-admin), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:105 +msgid "The APIs can also be accessed via [Ketesa](https://github.com/etkecc/ketesa), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:98 +#: ../../../docs/configuring-playbook-bot-draupnir.md:107 msgid "Add the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:100 +#: ../../../docs/configuring-playbook-bot-draupnir.md:109 msgid "To expose the APIs publicly, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:106 +#: ../../../docs/configuring-playbook-bot-draupnir.md:115 msgid "Obtain an access token for admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:108 +#: ../../../docs/configuring-playbook-bot-draupnir.md:117 msgid "Manual access to Synapse's Admin APIs requires an access token for a homeserver admin account. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:110 +#: ../../../docs/configuring-playbook-bot-draupnir.md:119 msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:113 +#: ../../../docs/configuring-playbook-bot-draupnir.md:122 msgid "Run the `curl` command" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:115 +#: ../../../docs/configuring-playbook-bot-draupnir.md:124 msgid "To disable rate limiting, run the following command on systems that ship curl. Before running it, make sure to replace:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:117 +#: ../../../docs/configuring-playbook-bot-draupnir.md:126 msgid "`ADMIN_ACCESS_TOKEN_HERE` with the access token of the admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:118 +#: ../../../docs/configuring-playbook-bot-draupnir.md:127 msgid "`example.com` with your base domain" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:119 +#: ../../../docs/configuring-playbook-bot-draupnir.md:128 msgid "`@bot.draupnir:example.com` with the MXID of your Draupnir bot user" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:125 +#: ../../../docs/configuring-playbook-bot-draupnir.md:134 +#: ../../../docs/configuring-playbook-bot-draupnir.md:207 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:126 +#: ../../../docs/configuring-playbook-bot-draupnir.md:135 msgid "This does not work on outdated Windows 10 as curl is not available there." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:127 +#: ../../../docs/configuring-playbook-bot-draupnir.md:136 msgid "Even if the APIs are not exposed to the internet, you should still be able to run the command on the homeserver locally." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:129 +#: ../../../docs/configuring-playbook-bot-draupnir.md:138 msgid "Abuse Reports" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:131 +#: ../../../docs/configuring-playbook-bot-draupnir.md:140 msgid "Draupnir can receive reports in the management room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:133 +#: ../../../docs/configuring-playbook-bot-draupnir.md:142 msgid "The bot can intercept the report API endpoint of the client-server API, which requires integration with the reverse proxy in front of the homeserver. If you are using Traefik, this playbook can set this up for you:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:145 +#: ../../../docs/configuring-playbook-bot-draupnir.md:148 +msgid "Enabling synapse-http-antispam support" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:150 +msgid "Certain protections in Draupnir require the [synapse-http-antispam](https://github.com/maunium/synapse-http-antispam) module and a Synapse homeserver plus homeserver admin status to function. This module can be enabled in the playbook via setting `matrix_bot_draupnir_config_web_synapseHTTPAntispam_enabled` to `true` and making sure that Draupnir admin API access is enabled." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:160 +msgid "These protections need to be manually activated and consulting the [enabling protections](#enabling-built-in-protections) guide can be helpful or consulting upstream documentation." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:168 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:147 +#: ../../../docs/configuring-playbook-bot-draupnir.md:170 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:149 +#: ../../../docs/configuring-playbook-bot-draupnir.md:172 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:151 +#: ../../../docs/configuring-playbook-bot-draupnir.md:174 msgid "`roles/custom/matrix-bot-draupnir/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_draupnir_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:153 +#: ../../../docs/configuring-playbook-bot-draupnir.md:176 msgid "For example, to change Draupnir's `acceptInvitesFromSpace` option to `!qporfwt:example.com`, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:167 +#: ../../../docs/configuring-playbook-bot-draupnir.md:190 msgid "Migrating from Mjolnir (Only required if migrating)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:169 +#: ../../../docs/configuring-playbook-bot-draupnir.md:192 msgid "Replace your `matrix_bot_mjolnir` config with `matrix_bot_draupnir` config. Also disable Mjolnir if you're doing migration." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:171 +#: ../../../docs/configuring-playbook-bot-draupnir.md:194 msgid "Note that Draupnir supports E2EE natively, so you can enable it instead of Pantalaimon. It is recommended to consult the instruction [here](#native-e2ee-support)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:173 +#: ../../../docs/configuring-playbook-bot-draupnir.md:196 msgid "That is all you need to do due to that Draupnir can complete migration on its own." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:175 +#: ../../../docs/configuring-playbook-bot-draupnir.md:198 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:177 +#: ../../../docs/configuring-playbook-bot-draupnir.md:200 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:184 +#: ../../../docs/configuring-playbook-bot-draupnir.md:209 +msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:211 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:186 +#: ../../../docs/configuring-playbook-bot-draupnir.md:213 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:188 +#: ../../../docs/configuring-playbook-bot-draupnir.md:215 +msgid "If you change the bot password (`matrix_bot_draupnir_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_draupnir_password` to let the bot know its new password." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:217 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:190 +#: ../../../docs/configuring-playbook-bot-draupnir.md:219 msgid "You can refer to the upstream [documentation](https://the-draupnir-project.github.io/draupnir-documentation/) for additional ways to use and configure Draupnir and for a more detailed usage guide." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:192 +#: ../../../docs/configuring-playbook-bot-draupnir.md:221 msgid "Below is a **non-exhaustive quick-start guide** for the impatient." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:194 +#: ../../../docs/configuring-playbook-bot-draupnir.md:223 msgid "Making Draupnir join and protect a room" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:196 +#: ../../../docs/configuring-playbook-bot-draupnir.md:225 msgid "Draupnir can be told to self-join public rooms, but it's better to follow this flow which works well for all kinds of rooms:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:198 +#: ../../../docs/configuring-playbook-bot-draupnir.md:227 msgid "Invite the bot to the room manually ([inviting Draupnir to rooms](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#inviting-draupnir-to-rooms)). Before joining, the bot *may* ask for confirmation in the Management Room" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:200 +#: ../../../docs/configuring-playbook-bot-draupnir.md:229 msgid "[Give the bot permissions to do its job](#giving-draupnir-permissions-to-do-its-job)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:202 +#: ../../../docs/configuring-playbook-bot-draupnir.md:231 msgid "Tell it to protect the room (using the [rooms command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#using-the-draupnir-rooms-command)) by sending the following command to the Management Room: `!draupnir rooms add !qporfwt:example.com`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:204 +#: ../../../docs/configuring-playbook-bot-draupnir.md:233 msgid "To have Draupnir provide useful room protection, you need do to a bit more work (at least the first time around). You may wish to [Subscribe to a public policy list](#subscribing-to-a-public-policy-list), [Create your own own policy and rules](#creating-your-own-policy-lists-and-rules) and [Enabling built-in protections](#enabling-built-in-protections)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:206 +#: ../../../docs/configuring-playbook-bot-draupnir.md:235 msgid "Giving Draupnir permissions to do its job" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:208 +#: ../../../docs/configuring-playbook-bot-draupnir.md:237 msgid "For Draupnir to do its job, you need to [give it permissions](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#giving-draupnir-permissions) in rooms it's protecting. This involves **giving it an Administrator power level**." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:210 +#: ../../../docs/configuring-playbook-bot-draupnir.md:239 msgid "**We recommend setting this power level as soon as the bot joins your room** (and before you create new rules), so that it can apply rules as soon as they are available. If the bot is under-privileged, it may fail to apply protections and may not retry for a while (or until your restart it)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:212 +#: ../../../docs/configuring-playbook-bot-draupnir.md:241 msgid "Subscribing to a public policy list" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:214 +#: ../../../docs/configuring-playbook-bot-draupnir.md:243 msgid "We recommend **subscribing to a public [policy list](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists)** using the [watch command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-policy-lists#using-draupnirs-watch-command-to-subscribe-to-policy-rooms)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:216 -msgid "Polcy lists are maintained in Matrix rooms. A popular policy list is maintained in the public `#community-moderation-effort-bl:neko.dev` room." +#: ../../../docs/configuring-playbook-bot-draupnir.md:245 +msgid "Policy lists are maintained in Matrix rooms. Popular ones maintained in the public are:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:218 -msgid "You can tell Draupnir to subscribe to it by sending the following command to the Management Room: `!draupnir watch #community-moderation-effort-bl:neko.dev`" +#: ../../../docs/configuring-playbook-bot-draupnir.md:247 +msgid "`#community-moderation-effort-bl:neko.dev`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:220 +#: ../../../docs/configuring-playbook-bot-draupnir.md:248 +msgid "`#huginn-muninn-active-threats:feline.support`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:250 +msgid "You can tell Draupnir to subscribe to each of these by sending the following command to the Management Room: `!draupnir watch POLICY_LIST_ADDRESS_HERE` (e.g. `!draupnir watch #community-moderation-effort-bl:neko.dev`)" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:252 msgid "Creating your own policy lists and rules" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:222 +#: ../../../docs/configuring-playbook-bot-draupnir.md:254 msgid "We also recommend **creating your own policy lists** with the [list create](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-policy-lists#using-draupnirs-list-create-command-to-create-a-policy-room) command." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:224 +#: ../../../docs/configuring-playbook-bot-draupnir.md:256 msgid "You can do so by sending the following command to the Management Room: `!draupnir list create my-bans my-bans-bl`. This will create a policy list having a name (shortcode) of `my-bans` and stored in a public `#my-bans-bl:example.com` room on your server. As soon as you run this command, the bot will invite you to the policy list room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:226 +#: ../../../docs/configuring-playbook-bot-draupnir.md:258 msgid "A policy list does nothing by itself, so the next step is **adding some rules to your policy list**. Policies target a so-called `entity` (one of: `user`, `room` or `server`). These entities are mentioned on the [policy lists](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists) documentation page and in the Matrix Spec [here](https://spec.matrix.org/v1.11/client-server-api/#mban-recommendation)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:228 +#: ../../../docs/configuring-playbook-bot-draupnir.md:260 msgid "The simplest and most useful entity to target is `user`. Below are a few examples using the [ban command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#the-ban-command) and targeting users." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:230 +#: ../../../docs/configuring-playbook-bot-draupnir.md:262 msgid "To create rules, you run commands in the Management Room (**not** in the policy list room)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:232 +#: ../../../docs/configuring-playbook-bot-draupnir.md:264 msgid "(ban a single user on a given homeserver): `!draupnir ban @charles:example.com my-bans Rude to others`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:233 -msgid "(ban all users on a given homeserver by using a [wildcard](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#wildcards)): `!draupnir ban @*:example.org my-bans Spam server - all users are fake`" +#: ../../../docs/configuring-playbook-bot-draupnir.md:265 +msgid "(ban all users on a given homeserver by using a [wildcard](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#wildcards)): `!draupnir ban @*:example.org my-bans Spam server, all users are fake`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:235 +#: ../../../docs/configuring-playbook-bot-draupnir.md:267 msgid "As a result of running these commands, you may observe:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:237 +#: ../../../docs/configuring-playbook-bot-draupnir.md:269 msgid "Draupnir creating `m.policy.rule.user` state events in the `#my-bans-bl:example.com` room on your server" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:238 +#: ../../../docs/configuring-playbook-bot-draupnir.md:270 msgid "applying these rules against all rooms that Draupnir is an Administrator in" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:240 +#: ../../../docs/configuring-playbook-bot-draupnir.md:272 msgid "You can undo bans with the [unban command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#the-unban-command)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:242 +#: ../../../docs/configuring-playbook-bot-draupnir.md:274 msgid "Enabling built-in protections" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:244 -msgid "You can also **turn on various built-in [protections](https://the-draupnir-project.github.io/draupnir-documentation/protections)** like `JoinWaveShortCircuit` (\"If X amount of users join in Y time, set the room to invite-only\")." +#: ../../../docs/configuring-playbook-bot-draupnir.md:276 +msgid "You can also **turn on various built-in [protections](https://the-draupnir-project.github.io/draupnir-documentation/protections)** like `JoinWaveShortCircuitProtection` (\"If X amount of users join in Y time, set the room to invite-only\")." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:246 +#: ../../../docs/configuring-playbook-bot-draupnir.md:278 msgid "To **see which protections are available and which are enabled**, send a `!draupnir protections` command to the Management Room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:248 -msgid "To **see the configuration options for a given protection**, send a `!draupnir protections show PROTECTION_NAME` (e.g. `!draupnir protections show JoinWaveShortCircuit`)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:280 +msgid "To [**see the configuration options for a given protection**](https://the-draupnir-project.github.io/draupnir-documentation/protections/configuring-protections#displaying-the-protection-settings), send a `!draupnir protections show PROTECTION_NAME` (e.g. `!draupnir protections show JoinWaveShortCircuitProtection`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:250 -msgid "To **set a specific option for a given protection**, send a command like this: `!draupnir config set PROTECTION_NAME.OPTION VALUE` (e.g. `!draupnir config set JoinWaveShortCircuit.timescaleMinutes 30`)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:282 +msgid "To [**set a specific option for a given protection**](https://the-draupnir-project.github.io/draupnir-documentation/protections/configuring-protections#changing-protection-settings), send a command like this: `!draupnir protections config set PROTECTION_NAME OPTION VALUE` (e.g. `!draupnir protections config set JoinWaveShortCircuitProtection timescaleMinutes 30`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:252 -msgid "To **enable a given protection**, send a command like this: `!draupnir enable PROTECTION_NAME` (e.g. `!draupnir enable JoinWaveShortCircuit`)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:284 +msgid "To [**enable a given protection**](https://the-draupnir-project.github.io/draupnir-documentation/protections/block-invitations-on-server-protection#enabling-the-protection), send a command like this: `!draupnir protections enable PROTECTION_NAME` (e.g. `!draupnir protections enable JoinWaveShortCircuitProtection`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:254 -msgid "To **disable a given protection**, send a command like this: `!draupnir disable PROTECTION_NAME` (e.g. `!draupnir disable JoinWaveShortCircuit`)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:286 +msgid "To **disable a given protection**, send a command like this: `!draupnir protections disable PROTECTION_NAME` (e.g. `!draupnir protections disable JoinWaveShortCircuitProtection`)." msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-honoroit.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-honoroit.po index 355bfcd89..f002d7a61 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-honoroit.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-honoroit.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,108 +19,140 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-honoroit.md:1 +#: ../../../docs/configuring-playbook-bot-honoroit.md:9 msgid "Setting up Honoroit (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:3 +#: ../../../docs/configuring-playbook-bot-honoroit.md:11 msgid "The playbook can install and configure [Honoroit](https://github.com/etkecc/honoroit) for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:5 +#: ../../../docs/configuring-playbook-bot-honoroit.md:13 msgid "It's a bot you can use to setup **your own helpdesk on matrix**" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:7 +#: ../../../docs/configuring-playbook-bot-honoroit.md:15 msgid "See the project's [documentation](https://github.com/etkecc/honoroit/blob/main/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:9 +#: ../../../docs/configuring-playbook-bot-honoroit.md:17 msgid "Adjusting DNS records (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:11 +#: ../../../docs/configuring-playbook-bot-honoroit.md:19 msgid "By default, this playbook installs Honoroit on the `matrix.` subdomain, at the `/honoroit` path (https://matrix.example.com/honoroit). This makes it easy to install it, because it **doesn't require additional DNS records to be set up**. If that's okay, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:13 +#: ../../../docs/configuring-playbook-bot-honoroit.md:21 msgid "If you wish to adjust it, see the section [below](#adjusting-the-honoroit-url-optional) for details about DNS configuration." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:15 +#: ../../../docs/configuring-playbook-bot-honoroit.md:23 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:17 +#: ../../../docs/configuring-playbook-bot-honoroit.md:25 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:32 +#: ../../../docs/configuring-playbook-bot-honoroit.md:40 msgid "Adjusting the Honoroit URL (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:34 +#: ../../../docs/configuring-playbook-bot-honoroit.md:42 msgid "By tweaking the `matrix_bot_honoroit_hostname` and `matrix_bot_honoroit_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:36 +#: ../../../docs/configuring-playbook-bot-honoroit.md:44 msgid "Example additional configuration for your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:44 +#: ../../../docs/configuring-playbook-bot-honoroit.md:52 msgid "If you've changed the default hostname, you may need to create a CNAME record for the Honoroit domain (`honoroit.example.com`), which targets `matrix.example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:46 +#: ../../../docs/configuring-playbook-bot-honoroit.md:54 msgid "When setting, replace `example.com` with your own." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:48 +#: ../../../docs/configuring-playbook-bot-honoroit.md:56 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:58 +msgid "There are some additional things you may wish to configure about the bot." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:60 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:62 +msgid "`roles/custom/matrix-bot-honoroit/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:64 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:50 +#: ../../../docs/configuring-playbook-bot-honoroit.md:66 msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:57 +#: ../../../docs/configuring-playbook-bot-honoroit.md:73 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:59 +#: ../../../docs/configuring-playbook-bot-honoroit.md:75 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:61 +#: ../../../docs/configuring-playbook-bot-honoroit.md:77 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:63 +#: ../../../docs/configuring-playbook-bot-honoroit.md:79 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:65 -msgid "If you change the bot password (`matrix_bot_honoroit_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_honoroit_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-honoroit.md:81 +msgid "If you change the bot password (`matrix_bot_honoroit_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_honoroit_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:67 +#: ../../../docs/configuring-playbook-bot-honoroit.md:83 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:69 +#: ../../../docs/configuring-playbook-bot-honoroit.md:85 msgid "To use the bot, invite it to the room you specified on your `vars.yml` file (`/invite @honoroit:example.com` where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:71 +#: ../../../docs/configuring-playbook-bot-honoroit.md:87 msgid "After the bot joins the room, any Matrix user can send a message to it to start a new thread in that room." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:73 +#: ../../../docs/configuring-playbook-bot-honoroit.md:89 msgid "Send `!ho help` to the bot in the room to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:75 +#: ../../../docs/configuring-playbook-bot-honoroit.md:91 msgid "You can also refer to the upstream [documentation](https://github.com/etkecc/honoroit#features)." msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:93 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:95 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-honoroit`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:97 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:99 +msgid "If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-matrix-registration-bot.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-matrix-registration-bot.po index 3471823b4..095b41d16 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-matrix-registration-bot.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-matrix-registration-bot.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-23 13:09+0900\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,84 +19,120 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:1 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:13 msgid "Setting up matrix-registration-bot (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:3 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:15 msgid "The playbook can install and configure [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot) for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:5 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:17 msgid "The bot allows you to easily **create and manage registration tokens** aka. invitation codes. It can be used for an invitation-based server, where you invite someone by sending them a registration token (tokens look like this: `rbalQ0zkaDSRQCOp`). They can register as per normal but have to provide a valid registration token in the final step of the registration process." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:7 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:19 msgid "See the project's [documentation](https://github.com/moan0s/matrix-registration-bot/blob/master/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:9 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:21 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:11 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:23 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:30 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:46 msgid "The bot account will be created automatically." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:32 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:48 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:50 +msgid "There are some additional things you may wish to configure about the bot." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:52 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:54 +msgid "`roles/custom/matrix-bot-matrix-registration-bot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:55 +msgid "`roles/custom/matrix-bot-matrix-registration-bot/templates/config.yaml.j2` for the bridge's default configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:57 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:34 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:59 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:41 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:66 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:43 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:68 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:45 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:70 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:47 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:72 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:49 -msgid "If you change the bot password (`matrix_bot_matrix_registration_bot_bot_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_matrix_registration_bot_bot_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:74 +msgid "If you change the bot password (`matrix_bot_matrix_registration_bot_bot_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_matrix_registration_bot_bot_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:51 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:76 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:53 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:78 msgid "To use the bot, start a chat with `@bot.matrix-registration-bot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:55 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:80 msgid "Send `help` to the bot to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:57 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:82 msgid "You can also refer to the upstream [Usage documentation](https://github.com/moan0s/matrix-registration-bot#supported-commands)." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:59 -msgid "If you have any questions, or if you need help setting it up, read the [troublshooting guide](https://github.com/moan0s/matrix-registration-bot/blob/main/docs/troubleshooting.md) or join [#matrix-registration-bot:hyteck.de](https://matrix.to/#/#matrix-registration-bot:hyteck.de)." +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:84 +msgid "If you have any questions, or if you need help setting it up, read the [troubleshooting guide](https://github.com/moan0s/matrix-registration-bot/blob/main/docs/troubleshooting.md) or join [#matrix-registration-bot:hyteck.de](https://matrix.to/#/#matrix-registration-bot:hyteck.de)." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:61 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:86 msgid "To clean the cache (session & encryption data) after you changed the bot's username, changed the login method from access_token to password etc… you can use:" msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:92 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:94 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-matrix-registration-bot`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:96 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:98 +msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-matrix-reminder-bot.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-matrix-reminder-bot.po index 84f39a049..f23c8b587 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-matrix-reminder-bot.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-matrix-reminder-bot.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-23 13:09+0900\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,80 +19,116 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:1 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:9 msgid "Setting up matrix-reminder-bot (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:3 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:11 msgid "The playbook can install and configure [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot) for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:5 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:13 msgid "It's a bot you can use to **schedule one-off & recurring reminders and alarms**." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:7 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:15 msgid "See the project's [documentation](https://github.com/anoadragon453/matrix-reminder-bot/blob/master/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:9 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:17 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:11 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:19 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:26 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:34 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:36 +msgid "There are some additional things you may wish to configure about the bot." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:38 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:40 +msgid "`roles/custom/matrix-bot-matrix-reminder-bot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:41 +msgid "`roles/custom/matrix-bot-matrix-reminder-bot/templates/config.yaml.j2` for the bot's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_matrix_reminder_bot_configuration_extension_yaml` variable" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:43 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:28 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:45 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:35 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:52 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:37 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:54 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:39 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:56 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:41 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:58 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:43 -msgid "If you change the bot password (`matrix_bot_matrix_reminder_bot_matrix_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_matrix_reminder_bot_matrix_user_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:60 +msgid "If you change the bot password (`matrix_bot_matrix_reminder_bot_matrix_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_matrix_reminder_bot_matrix_user_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:45 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:62 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:47 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:64 msgid "To use the bot, start a chat with `@bot.matrix-reminder-bot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:49 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:66 msgid "You can also add the bot to any existing Matrix room (`/invite @bot.matrix-reminder-bot:example.com`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:51 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:68 msgid "Basic usage is like this: `!remindme in 2 minutes; This is a test`" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:53 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:70 msgid "Send `!help reminders` to the room to see the bot's help menu for additional commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:55 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:72 msgid "You can also refer to the upstream [Usage documentation](https://github.com/anoadragon453/matrix-reminder-bot#usage)." msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:74 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:76 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-matrix-reminder-bot`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:78 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:80 +msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-maubot.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-maubot.po index 3cd9e33f9..df65ff5d0 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-maubot.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-maubot.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,149 +19,185 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-maubot.md:1 +#: ../../../docs/configuring-playbook-bot-maubot.md:12 msgid "Setting up maubot (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:3 +#: ../../../docs/configuring-playbook-bot-maubot.md:14 msgid "The playbook can install and configure [maubot](https://github.com/maubot/maubot) for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:5 +#: ../../../docs/configuring-playbook-bot-maubot.md:16 msgid "After setting up maubot, you can use the web management interface to make it do things. The default location of the management interface is `matrix.example.com/_matrix/maubot/`" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:7 +#: ../../../docs/configuring-playbook-bot-maubot.md:18 msgid "See the project's [documentation](https://docs.mau.fi/maubot/usage/basic.html) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:9 +#: ../../../docs/configuring-playbook-bot-maubot.md:20 msgid "Adjusting DNS records (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:11 +#: ../../../docs/configuring-playbook-bot-maubot.md:22 msgid "By default, this playbook installs maubot on the `matrix.` subdomain, at the `/_matrix/maubot/` path (https://matrix.example.com/_matrix/maubot/). This makes it easy to install it, because it **doesn't require additional DNS records to be set up**." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:13 +#: ../../../docs/configuring-playbook-bot-maubot.md:24 msgid "If you wish to adjust it, see the section [below](#adjusting-the-maubot-url-optional) for details about DNS configuration." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:15 +#: ../../../docs/configuring-playbook-bot-maubot.md:26 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:17 +#: ../../../docs/configuring-playbook-bot-maubot.md:28 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:32 +#: ../../../docs/configuring-playbook-bot-maubot.md:43 msgid "You can add multiple admins. The admin accounts are only used to access the maubot administration interface." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:34 +#: ../../../docs/configuring-playbook-bot-maubot.md:45 msgid "Adjusting the maubot URL (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:36 +#: ../../../docs/configuring-playbook-bot-maubot.md:47 msgid "By tweaking the `matrix_bot_maubot_hostname` and `matrix_bot_maubot_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:38 -#: ../../../docs/configuring-playbook-bot-maubot.md:56 +#: ../../../docs/configuring-playbook-bot-maubot.md:49 +#: ../../../docs/configuring-playbook-bot-maubot.md:76 msgid "Example additional configuration for your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:46 +#: ../../../docs/configuring-playbook-bot-maubot.md:57 msgid "If you've changed the default hostname, you may need to create a CNAME record for the maubot domain (`maubot.example.com`), which targets `matrix.example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:48 +#: ../../../docs/configuring-playbook-bot-maubot.md:59 msgid "When setting, replace `example.com` with your own." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:50 +#: ../../../docs/configuring-playbook-bot-maubot.md:61 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:63 +msgid "There are some additional things you may wish to configure about the bot." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:65 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:67 +msgid "`roles/custom/matrix-bot-maubot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:68 +msgid "`roles/custom/matrix-bot-maubot/templates/config.yaml.j2` for the bot's default configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:70 msgid "Customizing the maubot container image" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:52 +#: ../../../docs/configuring-playbook-bot-maubot.md:72 msgid "Certain [maubot plugins](https://plugins.mau.bot/) require additional dependencies to be installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:54 +#: ../../../docs/configuring-playbook-bot-maubot.md:74 msgid "You can customize the default maubot container image and install your own dependencies." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:67 +#: ../../../docs/configuring-playbook-bot-maubot.md:87 msgid "Consult the [Dockerfile reference](https://docs.docker.com/reference/dockerfile/) for more information about the syntax." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:69 +#: ../../../docs/configuring-playbook-bot-maubot.md:89 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:71 +#: ../../../docs/configuring-playbook-bot-maubot.md:91 msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:78 +#: ../../../docs/configuring-playbook-bot-maubot.md:98 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:80 +#: ../../../docs/configuring-playbook-bot-maubot.md:100 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:82 +#: ../../../docs/configuring-playbook-bot-maubot.md:102 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:84 +#: ../../../docs/configuring-playbook-bot-maubot.md:104 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:86 -msgid "If you change the bot password (`matrix_bot_maubot_initial_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_maubot_initial_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-maubot.md:106 +msgid "If you change the bot password (`matrix_bot_maubot_initial_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_maubot_initial_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:88 +#: ../../../docs/configuring-playbook-bot-maubot.md:108 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:90 +#: ../../../docs/configuring-playbook-bot-maubot.md:110 msgid "By default, you can visit `matrix.example.com/_matrix/maubot/` to manage your available plugins, clients and instances." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:92 +#: ../../../docs/configuring-playbook-bot-maubot.md:112 msgid "You should start in the following order" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:93 +#: ../../../docs/configuring-playbook-bot-maubot.md:113 msgid "**Create one or more clients**: A client is a Matrix account which the bot will use to message. By default, the playbook creates a `bot.maubot` account (as per the configuration above). You only need to [obtain an access token](#obtaining-an-access-token) for it" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:94 +#: ../../../docs/configuring-playbook-bot-maubot.md:114 msgid "**Upload some Plugins**: Plugins can be obtained from [here](https://github.com/maubot/maubot#plugins) or any other source." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:95 +#: ../../../docs/configuring-playbook-bot-maubot.md:115 msgid "**Create an instance**: An instance is the actual bot. You have to specify a client which the bot instance will use and the plugin (how the bot will behave)" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:97 +#: ../../../docs/configuring-playbook-bot-maubot.md:117 msgid "Obtain an access token" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:99 +#: ../../../docs/configuring-playbook-bot-maubot.md:119 msgid "This can be done via `mbc login` then `mbc auth` (see the [maubot documentation](https://docs.mau.fi/maubot/usage/cli/auth.html)). To run these commands, you'll first need to `exec` into the maubot container with `docker exec -it matrix-bot-maubot sh`." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:101 +#: ../../../docs/configuring-playbook-bot-maubot.md:121 msgid "Alternatively, you can refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md). Be aware that you'd better use the **Obtain an access token via curl** method (not **Obtain an access token via Element Web**) as the latter will causes issues to your bot in encrypted rooms. Read [more](https://docs.mau.fi/maubot/usage/basic.html#creating-clients)." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:103 +#: ../../../docs/configuring-playbook-bot-maubot.md:123 msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:126 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:128 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-maubot`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:130 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:132 +msgid "The default logging level for this component is `WARNING`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-mjolnir.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-mjolnir.po index 4240cbd70..c70fcc272 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-mjolnir.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bot-mjolnir.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,254 +19,266 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:1 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:12 msgid "Setting up Mjolnir (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:3 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:14 msgid "The playbook can install and configure the [Mjolnir](https://github.com/matrix-org/mjolnir) moderation bot for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:5 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:16 msgid "See the project's [documentation](https://github.com/matrix-org/mjolnir/blob/main/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:7 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:18 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:9 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:20 msgid "Register the bot account" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:11 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:22 msgid "The playbook does not automatically create users for you. You **need to register the bot user manually** before setting up the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:13 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:24 msgid "Generate a strong password for the bot. You can create one with a command like `pwgen -s 64 1`." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:15 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:26 msgid "You can use the playbook to [register a new user](registering-users.md):" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:21 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:32 msgid "If you would like Mjolnir to be able to deactivate users, move aliases, shutdown rooms, etc then it must be a server admin so you need to change `admin=no` to `admin=yes` in the command above." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:23 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:34 msgid "Obtain an access token" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:25 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:36 msgid "The bot requires an access token to be able to connect to your homeserver. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:27 -#: ../../../docs/configuring-playbook-bot-mjolnir.md:52 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:38 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:63 msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:30 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:41 msgid "Make sure the account is free from rate limiting" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:32 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:43 msgid "If your homeserver's implementation is Synapse, you will need to prevent it from rate limiting the bot's account. **This is a required step. If you do not configure it, Mjolnir will crash.**" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:34 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:45 msgid "This can be done using Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users). They can be accessed both externally and internally." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:36 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:47 msgid "**Note**: access to the APIs is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, doing so is not recommended for additional security. See [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:38 -msgid "The APIs can also be accessed via [Synapse Admin](https://github.com/etkecc/synapse-admin), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md)." +#: ../../../docs/configuring-playbook-bot-mjolnir.md:49 +msgid "The APIs can also be accessed via [Ketesa](https://github.com/etkecc/ketesa), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:40 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:51 msgid "Add the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:42 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:53 msgid "To expose the APIs publicly, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:48 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:59 msgid "Obtain an access token for admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:50 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:61 msgid "Manual access to Synapse's Admin APIs requires an access token for a homeserver admin account. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md). If you have made Mjolnir an admin, you can just use the Mjolnir token." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:55 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:66 msgid "Run the `curl` command" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:57 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:68 msgid "To disable rate limiting, run the following command on systems that ship curl. Before running it, make sure to replace:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:59 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:70 msgid "`ADMIN_ACCESS_TOKEN_HERE` with the access token of the admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:60 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:71 msgid "`example.com` with your base domain" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:61 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:72 msgid "`@bot.mjolnir:example.com` with the MXID of your Mjolnir bot user" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:67 -#: ../../../docs/configuring-playbook-bot-mjolnir.md:184 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:78 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:195 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:68 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:79 msgid "This does not work on outdated Windows 10 as curl is not available there." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:69 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:80 msgid "Even if the APIs are not exposed to the internet, you should still be able to run the command on the homeserver locally." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:71 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:82 msgid "Create a management room" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:73 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:84 msgid "Using your own account, create a new invite only room that you will use to manage the bot. This is the room where you will see the status of the bot and where you will send commands to the bot, such as the command to ban a user from another room." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:75 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:86 msgid "[!WARNING] Anyone in this room can control the bot so it is important that you only invite trusted users to this room." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:78 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:89 msgid "It is possible to make the management room encrypted (E2EE). If doing so, then you MUST enable and use Pantalaimon (see [below](#configuration-with-e2ee-support))." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:80 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:91 msgid "Once you have created the room you need to copy the room ID so you can specify it on your `vars.yml` file. In Element Web you can check the ID by going to the room's settings and clicking \"Advanced\". The room ID will look something like `!qporfwt:example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:82 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:93 msgid "Finally invite the `@bot.mjolnir:example.com` account you created earlier into the room." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:84 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:95 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:86 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:97 msgid "To enable the bot, add the following configuration to your `vars.yml` file. Make sure to replace `MANAGEMENT_ROOM_ID_HERE` with the one of the room which you have created just now." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:95 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:106 msgid "End-to-End Encryption support" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:97 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:108 msgid "Decide whether you want Mjolnir to be capable of operating in end-to-end encrypted (E2EE) rooms. This includes the management room and the moderated rooms." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:99 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:110 msgid "To support E2EE, Mjolnir needs to [use Pantalaimon](configuring-playbook-pantalaimon.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:101 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:112 msgid "Configuration with E2EE support" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:103 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:114 msgid "When using Pantalaimon, Mjolnir will log in to its bot account itself through Pantalaimon, so configure its username and password." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:105 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:116 msgid "Add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:119 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:130 msgid "The playbook's `group_vars` will configure other required settings. If using this role separately without the playbook, you also need to configure the two URLs that Mjolnir uses to reach the homeserver, one through Pantalaimon and one \"raw\". This example is taken from the playbook's `group_vars`:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:131 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:142 msgid "Configuration without E2EE support" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:133 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:144 msgid "When NOT using Pantalaimon, Mjolnir does not log in by itself and you must give it an access token for its bot account." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:135 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:146 msgid "Add the following configuration to your `vars.yml` file. Make sure to replace `ACCESS_TOKEN_HERE` with the one created [above](#obtain-an-access-token)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:141 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:152 msgid "Adding Mjolnir synapse antispam module (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:143 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:154 msgid "To enable Mjolnir synapse antispam module, add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:153 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:164 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:155 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:166 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:157 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:168 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:159 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:170 msgid "`roles/custom/matrix-bot-mjolnir/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_mjolnir_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:161 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:172 msgid "For example, to change Mjolnir's `recordIgnoredInvites` option to `true`, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:175 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:186 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:177 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:188 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:186 -msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-mjolnir.md:188 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:197 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:190 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:199 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:192 -msgid "If you change the Pantalaimon's password (`matrix_bot_mjolnir_pantalaimon_password` in your `vars.yml` file) subsequently, its credentials on the homeserver won't be updated automatically. If you'd like to change the password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_mjolnir_pantalaimon_password` to let Pantalaimon know its new password." +#: ../../../docs/configuring-playbook-bot-mjolnir.md:201 +msgid "If you change the Pantalaimon's password (`matrix_bot_mjolnir_pantalaimon_password` in your `vars.yml` file) subsequently, its credentials on the homeserver won't be updated automatically. If you'd like to change the password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_mjolnir_pantalaimon_password` to let Pantalaimon know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:194 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:203 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:196 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:205 msgid "You can refer to the upstream [documentation](https://github.com/matrix-org/mjolnir) for additional ways to use and configure Mjolnir. Check out their [quickstart guide](https://github.com/matrix-org/mjolnir#quickstart-guide) for some basic commands you can give to the bot." msgstr "" + +#: ../../../docs/configuring-playbook-bot-mjolnir.md:207 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-mjolnir.md:209 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-mjolnir`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-mjolnir.md:211 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-mjolnir.md:213 +msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bridge-postmoogle.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bridge-postmoogle.po index 3c5a68453..c01b54bce 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bridge-postmoogle.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-bridge-postmoogle.po @@ -8,60 +8,60 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:1 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:10 msgid "Setting up Postmoogle email bridging (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:3 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:12 msgid "The playbook can install and configure [Postmoogle](https://github.com/etkecc/postmoogle) for you." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:5 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:14 msgid "Postmoogle is a bridge you can use to have its bot user forward emails to Matrix rooms. It runs an SMTP email server and allows you to assign mailbox addresses to the rooms." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:7 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:16 msgid "See the project's [documentation](https://github.com/etkecc/postmoogle/blob/master/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:9 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:18 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:11 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:20 msgid "Open the following ports on your server to be able to receive incoming emails:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:13 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:22 msgid "`25/tcp`: SMTP" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:14 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:23 msgid "`587/tcp`: Submission (TLS-encrypted SMTP)" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:16 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:25 msgid "If you don't open these ports, you will still be able to send emails, but not receive any." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:18 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:27 msgid "These port numbers are configurable via the `matrix_postmoogle_smtp_host_bind_port` and `matrix_postmoogle_submission_host_bind_port` variables, but other email servers will try to deliver on these default (standard) ports, so changing them is of little use." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:20 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:29 msgid "Adjusting DNS records" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:22 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:31 msgid "To make Postmoogle enable its email sending features, you need to configure MX and TXT (SPF, DMARC, and DKIM) records. See the table below for values which need to be specified." msgstr "" @@ -137,90 +137,94 @@ msgstr "" msgid "get it from `!pm dkim`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:31 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:40 msgid "**Note**: the DKIM record can be retrieved after configuring and installing the bridge's bot." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:33 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:42 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:35 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:44 msgid "Add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:56 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:65 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:58 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:67 msgid "There are some additional things you may wish to configure about the bridge." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:60 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:69 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:62 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:71 msgid "`roles/custom/matrix-bridge-postmoogle/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:64 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:73 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:66 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:75 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:73 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:82 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:75 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:84 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create a user account of the bridge's bot." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:77 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:86 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:79 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:88 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:81 -msgid "If you change the bridge's bot password (`matrix_postmoogle_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_postmoogle_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:90 +msgid "If you change the bridge's bot password (`matrix_postmoogle_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_postmoogle_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:83 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:92 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:85 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:94 msgid "To use the bridge, invite the `@postmoogle:example.com` bot user into a room you want to use as a mailbox." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:87 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:96 msgid "Then send `!pm mailbox NAME` to expose this Matrix room as an inbox with the email address `NAME@matrix.example.com`. Emails sent to that email address will be forwarded to the room." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:89 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:98 msgid "Send `!pm help` to the bot in the room to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:91 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:100 msgid "You can also refer to the upstream [documentation](https://github.com/etkecc/postmoogle)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:93 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:102 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:95 -msgid "As with all other services, you can find their logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by running something like `journalctl -fu matrix-postmoogle`" +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:104 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-postmoogle`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:106 +msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:97 -msgid "The default logging level for this bridge is `INFO`, but you can increase it to `DEBUG` with the following additional configuration:" +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:108 +msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-element-admin.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-element-admin.po new file mode 100644 index 000000000..b76d5f2a0 --- /dev/null +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-element-admin.po @@ -0,0 +1,118 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community +# members +# This file is distributed under the same license as the +# matrix-docker-ansible-deploy package. +# FIRST AUTHOR , 2026. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: bg\n" +"Language-Team: bg \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" + +#: ../../../docs/configuring-playbook-element-admin.md:8 +msgid "Setting up Element Admin (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:10 +msgid "The playbook can install and configure [Element Admin](https://github.com/element-hq/element-admin) for you." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:12 +msgid "Element Admin is a web-based administration panel for Synapse and [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md)." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:14 +msgid "See the project's [documentation](https://github.com/element-hq/element-admin) to learn more." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:16 +msgid "💡 **Note**: This project is still very young and doesn't have many features. [Ketesa](./configuring-playbook-ketesa.md) is the fully-featured alternative — it covers all Synapse and MAS Admin APIs, including complete user management, session management, and MAS policy data. Element Admin remains a valid choice if you prefer its interface." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:18 +msgid "Prerequisites" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:20 +msgid "A [Synapse](configuring-playbook-synapse.md) homeserver with its Admin API enabled (the playbook automatically enables it for you when you enable Element Admin)" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:21 +msgid "[Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) with its Admin API enabled (the playbook automatically enables it for you when you enable Element Admin)" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:23 +msgid "Decide on a domain and path" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:25 +msgid "By default, the Element Admin is configured to be served on the `admin.element.example.com` domain." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:27 +msgid "If you'd like to run Element Admin on another hostname, see the [Adjusting the Element Admin URL](#adjusting-the-element-admin-url-optional) section below." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:29 +msgid "Adjusting DNS records (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:31 +msgid "By default, this playbook installs Element Admin on the `admin.element.` subdomain (`admin.element.example.com`) and requires you to create a `CNAME` record for `admin.element`, which targets `matrix.example.com`." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:33 +msgid "When setting these values, replace `example.com` with your own." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:35 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:37 +msgid "Add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:43 +msgid "Adjusting the Element Admin URL (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:45 +msgid "By tweaking the `matrix_element_admin_hostname` variable, you can easily make the service available at a **different hostname** than the default one." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:47 +msgid "Example additional configuration for your `vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:53 +msgid "[!WARNING] A `matrix_element_admin_path_prefix` variable is also available and mean to let you configure a path prefix for the Element Admin service, but **Element Admin does not support running under a sub-path yet**." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:56 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:58 +msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:65 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:67 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-ketesa.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-ketesa.po new file mode 100644 index 000000000..5fcb09741 --- /dev/null +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-ketesa.po @@ -0,0 +1,166 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community +# members +# This file is distributed under the same license as the +# matrix-docker-ansible-deploy package. +# FIRST AUTHOR , 2026. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-04-03 12:02+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: bg\n" +"Language-Team: bg \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" + +#: ../../../docs/configuring-playbook-ketesa.md:14 +msgid "Setting up Ketesa (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:16 +msgid "The playbook can install and configure [Ketesa](https://github.com/etkecc/ketesa) for you." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:18 +msgid "Ketesa is a fully-featured admin interface for Matrix homeservers — manage users, rooms, media, sessions, and more from one clean, responsive web UI. It is the evolution of [Awesome-Technologies/synapse-admin](https://github.com/Awesome-Technologies/synapse-admin): what began as a fork has grown into its own independent project with a redesigned interface, comprehensive Synapse and MAS API coverage, and multi-language support." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:20 +msgid "[!NOTE]" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:22 +msgid "Ketesa does not work with other homeserver implementations than Synapse due to API's incompatibility." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:23 +msgid "The latest version of Ketesa is hosted by [etke.cc](https://etke.cc/) at [admin.etke.cc](https://admin.etke.cc/). If you only need this service occasionally and trust giving your admin credentials to a 3rd party Single Page Application, you can consider using it from there and avoiding the (small) overhead of self-hosting." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:24 +msgid "This playbook also supports an alternative management UI in the shape of [Element Admin](./configuring-playbook-element-admin.md). Please note that it's currently less feature-rich than Ketesa and requires [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md)." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:26 +msgid "Adjusting DNS records (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:28 +msgid "By default, this playbook installs Ketesa on the `matrix.` subdomain, at the `/synapse-admin` path (https://matrix.example.com/synapse-admin) — the legacy path is kept for backward compatibility. This makes it easy to install it, because it **doesn't require additional DNS records to be set up**. If that's okay, you can skip this section." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:30 +msgid "If you wish to adjust it, see the section [below](#adjusting-the-ketesa-url-optional) for details about DNS configuration." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:32 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:34 +msgid "To enable Ketesa, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:40 +msgid "**Note**: Ketesa requires Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/usage/administration/admin_api/index.html) to function. Access to them is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, for additional security, we normally leave them unexposed, following [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints). Because Ketesa needs these APIs to function, when installing Ketesa, the playbook **automatically** exposes the Synapse Admin API publicly for you. Depending on the homeserver implementation you're using (Synapse, Dendrite), this is equivalent to:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:42 +msgid "for [Synapse](./configuring-playbook-synapse.md) (our default homeserver implementation): `matrix_synapse_container_labels_public_client_synapse_admin_api_enabled: true`" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:43 +msgid "for [Dendrite](./configuring-playbook-dendrite.md): `matrix_dendrite_container_labels_public_client_synapse_admin_api_enabled: true`" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:45 +msgid "By default, Ketesa installation will be [restricted to only work with one homeserver](https://github.com/etkecc/ketesa/blob/main/README.md#restricting-available-homeserver) — the one managed by the playbook. To adjust these restrictions, tweak the `matrix_ketesa_config_restrictBaseUrl` variable." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:47 +msgid "Adjusting the Ketesa URL (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:49 +msgid "By tweaking the `matrix_ketesa_hostname` and `matrix_ketesa_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:51 +msgid "We recommend updating the path prefix to `/ketesa` to align with the new branding, while the default `/synapse-admin` is kept for backward compatibility:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:57 +msgid "Or to change the hostname entirely:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:65 +msgid "If you've changed the default hostname, you may need to create a CNAME record for the Ketesa domain (`admin.example.com`), which targets `matrix.example.com`." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:67 +msgid "When setting, replace `example.com` with your own." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:69 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:71 +msgid "There are some additional things you may wish to configure about the component." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:73 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:75 +msgid "`roles/custom/matrix-ketesa/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_ketesa_configuration_extension_json` variable" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:77 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:79 +msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:86 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:88 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:90 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:92 +msgid "After installation, Ketesa will be accessible at: `https://matrix.example.com/synapse-admin/` (or `/ketesa/` if you updated the path prefix as recommended)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:94 +msgid "To use Ketesa, you need to have [registered at least one administrator account](registering-users.md) on your server." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:96 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:98 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-ketesa`." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:100 +msgid "If you have questions, you can join this community room and feel free to ask: [#ketesa:etke.cc](https://matrix.to/#/#ketesa:etke.cc)" +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-matrix-authentication-service.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-matrix-authentication-service.po index 554766af6..23112f83e 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-matrix-authentication-service.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-matrix-authentication-service.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,150 +19,134 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:1 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:8 msgid "Setting up Matrix Authentication Service (optional)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:3 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:10 msgid "The playbook can install and configure [Matrix Authentication Service](https://github.com/element-hq/matrix-authentication-service/) (MAS) — a service operating alongside your existing [Synapse](./configuring-playbook-synapse.md) homeserver and providing [better authentication, session management and permissions in Matrix](https://matrix.org/blog/2023/09/better-auth/)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:5 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:12 msgid "Matrix Authentication Service is an implementation of [MSC3861: Next-generation auth for Matrix, based on OAuth 2.0/OIDC](https://github.com/matrix-org/matrix-spec-proposals/pull/3861) and still work in progress, tracked at the [areweoidcyet.com](https://areweoidcyet.com/) website." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:7 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:14 msgid "**Before going through with starting to use Matrix Authentication Service**, make sure to read:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:9 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:16 msgid "the [Reasons to use Matrix Authentication Service](#reasons-to-use-matrix-authentication-service) section below" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:10 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:17 msgid "the [Expectations](#expectations) section below" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:11 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:18 msgid "the [FAQ section on areweoidcyet.com](https://areweoidcyet.com/#faqs)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:13 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:20 msgid "**If you've already been using Synapse** and have user accounts in its database, you can [migrate to Matrix Authentication Service](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:15 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:22 msgid "Reasons to use Matrix Authentication Service" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:17 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:24 msgid "You may be wondering whether you should make the switch to Matrix Authentication Service (MAS) or keep using your existing authentication flow via Synapse (password-based or [OIDC](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on)-enabled)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:19 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:26 msgid "Matrix Authentication Service is **still an experimental service** and **not a default** for this Ansible playbook." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:21 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:28 msgid "The [Expectations](#expectations) section contains a list of what works and what doesn't (**some services don't work with MAS yet**), as well as the **relative irreversability** of the migration process." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:23 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:30 msgid "Below, we'll try to **highlight some potential reasons for switching** to Matrix Authentication Service:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:25 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:32 msgid "To use SSO in [Element X](https://element.io/blog/element-x-ignition/). The old [Synapse OIDC](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on) login flow is only supported in old Element clients and will not be supported in Element X. Element X will only support the new SSO-based login flow provided by MAS, so if you want to use SSO with Element X, you will need to switch to MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:27 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:34 msgid "To help drive adoption of the \"Next-generation auth for Matrix\" by switching to what's ultimately coming anyway" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:29 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:36 msgid "To help discover (and potentially fix) MAS integration issues with this Ansible playbook" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:31 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:38 msgid "To help discover (and potentially fix) MAS integration issues with various other Matrix components (bridges, bots, clients, etc.)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:33 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:40 msgid "To reap some of the security benefits that Matrix Authentication Service offers, as outlined in the [Better authentication, session management and permissions in Matrix](https://matrix.org/blog/2023/09/better-auth/) article." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:35 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:42 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:37 -msgid "⚠️ the [Synapse](configuring-playbook-synapse.md) homeserver implementation (which is the default for this playbook). Other homeserver implementations ([Dendrite](./configuring-playbook-dendrite.md), [Conduit](./configuring-playbook-conduit.md), etc.) do not support integrating wtih Matrix Authentication Service yet." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:44 +msgid "⚠️ the [Synapse](configuring-playbook-synapse.md) homeserver implementation (which is the default for this playbook). Other homeserver implementations ([Dendrite](./configuring-playbook-dendrite.md), [Conduit](./configuring-playbook-conduit.md), etc.) do not support integrating with Matrix Authentication Service yet." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:39 -msgid "⚠️ **email sending** configured (see [Adjusting email-sending settings](./configuring-playbook-email.md)), because **Matrix Authentication Service [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user** going through the new SSO-based login flow. It's also possible to [work around email deliverability issues](#working-around-email-deliverability-issues) if your email configuration is not working." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:41 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:46 msgid "❌ **disabling all password providers** for Synapse (things like [shared-secret-auth](./configuring-playbook-shared-secret-auth.md), [rest-auth](./configuring-playbook-rest-auth.md), [LDAP auth](./configuring-playbook-ldap-auth.md), etc.) More details about this are available in the [Expectations](#expectations) section below." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:43 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:48 msgid "Expectations" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:45 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:50 msgid "This section details what you can expect when switching to the Matrix Authentication Service (MAS)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:47 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:52 msgid "❌ **Synapse password providers will need to be disabled**. You can no longer use [shared-secret-auth](./configuring-playbook-shared-secret-auth.md), [rest-auth](./configuring-playbook-rest-auth.md), [LDAP auth](./configuring-playbook-ldap-auth.md), etc. When the authentication flow is handled by MAS (not by Synapse anymore), it doesn't make sense to extend the Synapse authentication flow with additional modules. Many bridges used to rely on shared-secret-auth for doing double-puppeting (impersonating other users), but most (at least the mautrix bridges) nowadays use [Appservice Double Puppet](./configuring-playbook-appservice-double-puppet.md) as a better alternative. Older/maintained bridges may still rely on shared-secret-auth, as do other services like [matrix-corporal](./configuring-playbook-matrix-corporal.md)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:49 -msgid "❌ Certain **tools like [synapse-admin](./configuring-playbook-synapse-admin.md) do not have full compatibility with MAS yet**. synapse-admin already supports [login with access token](https://github.com/etkecc/synapse-admin/pull/58), browsing users (which Synapse will internally fetch from MAS) and updating user avatars. However, editing users (passwords, etc.) now needs to happen directly against MAS using the [MAS Admin API](https://element-hq.github.io/matrix-authentication-service/api/index.html), which synapse-admin cannot interact with yet." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:54 +msgid "✅ **[Ketesa](./configuring-playbook-ketesa.md) has full MAS integration**. Ketesa supports OIDC auth, user management, all session types (browser, OAuth2, compatibility), linked email addresses, upstream OAuth provider links, MAS policy data, and user creation through MAS. It is the recommended tool for managing homeservers running MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:51 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:56 msgid "❌ **Some services experience issues when authenticating via MAS**:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:53 -msgid "[Postmoogle](./configuring-playbook-bridge-postmoogle.md) works the first time around, but it consistently fails after restarting:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:55 -msgid "cannot initialize matrix bot error=\"olm account is marked as shared, keys seem to have disappeared from the server\"" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:57 -msgid "[matrix-reminder-bot](./configuring-playbook-bot-matrix-reminder-bot.md) fails to start (see [element-hq/matrix-authentication-service#3439](https://github.com/element-hq/matrix-authentication-service/issues/3439))" -msgstr "" - #: ../../../docs/configuring-playbook-matrix-authentication-service.md:58 -msgid "Other services may be similarly affected. This list is not exhaustive." +msgid "[Reminder bot](configuring-playbook-bot-matrix-reminder-bot.md) seems to be losing some of its state on each restart and may reschedule old reminders once again" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:60 -msgid "❌ **Encrypted appservices** do not work yet (related to [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190) and [PR 17705 for Synapse](https://github.com/element-hq/synapse/pull/17705)), so all bridges/bots that rely on encryption will fail to start (see [this issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3658) for Hookshot). You can use these bridges/bots only if you **keep end-to-bridge encryption disabled** (which is the default setting)." +msgid "[Postmoogle](./configuring-playbook-bridge-postmoogle.md) works the first time around, but it consistently fails after restarting:" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:62 -msgid "⚠️ **You will need to have email sending configured** (see [Adjusting email-sending settings](./configuring-playbook-email.md)), because **Matrix Authentication Service [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user** going through the new SSO-based login flow. It's also possible to [work around email deliverability issues](#working-around-email-deliverability-issues) if your email configuration is not working." +msgid "cannot initialize matrix bot error=\"olm account is marked as shared, keys seem to have disappeared from the server\"" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:64 -msgid "⚠️ [Migrating an existing Synapse homeserver to Matrix Authentication Service](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) is **possible**, but requires **some playbook-assisted manual work**. Migration is **reversible with no or minor issues if done quickly enough**, but as users start logging in (creating new login sessions) via the new MAS setup, disabling MAS and reverting back to the Synapse user database will cause these new sessions to break." +msgid "❌ **Encrypted appservices** do not work yet (related to [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190) and [PR 17705 for Synapse](https://github.com/element-hq/synapse/pull/17705)), so all bridges/bots that rely on encryption will fail to start (see [this issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3658) for Hookshot). You can use these bridges/bots only if you **keep end-to-bridge encryption disabled** (which is the default setting)." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:66 -msgid "⚠️ [Migrating an existing Synapse homeserver to Matrix Authentication Service](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) does not currently seem to preserve the \"admin\" flag for users (as found in the Synapse database). All users are imported as non-admin — see [element-hq/matrix-authentication-service#3440](https://github.com/element-hq/matrix-authentication-service/issues/3440). You may need update the Matrix Authentication Service's database manually and adjust the `can_request_admin` column in the `users` table to `true` for users that need to be administrators (e.g. `UPDATE users SET can_request_admin = true WHERE username = 'someone';`)" +msgid "⚠️ [Migrating an existing Synapse homeserver to Matrix Authentication Service](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) is **possible**, but requires **some playbook-assisted manual work**. Migration is **reversible with no or minor issues if done quickly enough**, but as users start logging in (creating new login sessions) via the new MAS setup, disabling MAS and reverting back to the Synapse user database will cause these new sessions to break." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:68 -msgid "⚠️ Delegating user authentication to MAS causes **your Synapse server to be completely dependant on one more service** for its operations. MAS is quick & lightweight and should be stable enough already, but this is something to keep in mind when making the switch." +msgid "⚠️ Delegating user authentication to MAS causes **your Synapse server to be completely dependent on one more service** for its operations. MAS is quick & lightweight and should be stable enough already, but this is something to keep in mind when making the switch." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:70 @@ -182,7 +166,7 @@ msgid "✅ Various clients ([Cinny](./configuring-playbook-client-cinny.md), [El msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:78 -msgid "✅ The **old login flow** (called `m.login.password`) **will still continue to work**, so clients (old Element Web, etc.) and bridges/bots that don't support the new OIDC-based login flow will still work. Going through the old login flow does not require users to have a verified email address, as [is the case](https://github.com/element-hq/matrix-authentication-service/issues/1505) for the new SSO-based login flow." +msgid "✅ The **old login flow** (called `m.login.password`) **will still continue to work**, so clients (old Element Web, etc.) and bridges/bots that don't support the new OIDC-based login flow will still work" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:80 @@ -210,7 +194,7 @@ msgid "Existing homeserver" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:92 -msgid "Other homeserver implementations ([Dendrite](./configuring-playbook-dendrite.md), [Conduit](./configuring-playbook-conduit.md), etc.) do not support integrating wtih Matrix Authentication Service yet." +msgid "Other homeserver implementations ([Dendrite](./configuring-playbook-dendrite.md), [Conduit](./configuring-playbook-conduit.md), etc.) do not support integrating with Matrix Authentication Service yet." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:94 @@ -298,326 +282,346 @@ msgstr "" msgid "The playbook exposes a `matrix_authentication_service_config_upstream_oauth2_providers` variable for controlling this setting." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:269 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:273 msgid "💡 Refer to the [`upstream_oauth2.providers` setting](https://element-hq.github.io/matrix-authentication-service/reference/configuration.html#upstream_oauth2providers) for the most up-to-date schema and example for providers. The value shown above here may be out of date." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:271 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:275 msgid "⚠️ The syntax for existing [OIDC providers configured in Synapse](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on) is slightly different, so you will need to adjust your configuration when switching from Synapse OIDC to MAS upstream OAuth2." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:273 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:277 msgid "⚠️ When [migrating an existing homeserver](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) which contains OIDC-sourced users, you will need to:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:275 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:279 msgid "[Configure upstream OIDC provider mapping for syn2mas](#configuring-upstream-oidc-provider-mapping-for-syn2mas)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:276 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:280 msgid "go through the [migrating an existing homeserver](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) process" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:277 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:281 msgid "remove all Synapse OIDC-related configuration (`matrix_synapse_oidc_*`) to prevent it being in conflict with the MAS OIDC configuration" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:279 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:283 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:285 +msgid "There are some additional things you may wish to configure about the component." +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:287 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:289 +msgid "`roles/custom/matrix-authentication-service/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:290 +msgid "`roles/custom/matrix-authentication-service/templates/config.yaml.j2` for the component's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_authentication_service_configuration_extension_yaml` variable" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:292 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:281 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:294 msgid "Now that you've [adjusted the playbook configuration](#adjusting-the-playbook-configuration) and [your DNS records](#adjusting-dns-records), you can run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:288 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:301 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:290 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:303 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:292 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:305 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:294 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:307 msgid "If you're in the process of migrating an existing Synapse homeserver to MAS, you should now follow the rest of the steps in the [Migrating an existing Synapse homeserver to Matrix Authentication Service](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) guide." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:296 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:309 msgid "💡 After installation, you should [verify that Matrix Authentication Service is installed correctly](#verify-that-matrix-authentication-service-is-installed-correctly)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:298 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:311 msgid "Migrating an existing Synapse homeserver to Matrix Authentication Service" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:300 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:313 msgid "Our migration guide is loosely based on the upstream [Migrating an existing homeserver](https://element-hq.github.io/matrix-authentication-service/setup/migration.html) guide." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:302 -msgid "Migration is done via a tool called `syn2mas`, which the playbook could run for you (in a container)." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:315 +msgid "Migration is done via a sub-command called `syn2mas`, which the playbook could run for you (in a container)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:304 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:317 msgid "The installation + migration steps are like this:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:306 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:319 msgid "[Adjust your configuration](#adjusting-the-playbook-configuration) to **disable the integration between the homeserver and MAS**. This is done by **uncommenting** the `matrix_authentication_service_migration_in_progress: true` line." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:308 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:321 msgid "Perform the initial [installation](#installing). At this point:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:310 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:323 msgid "Matrix Authentication Service will be installed. Its database will be empty, so it cannot validate existing access tokens or authentication users yet." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:312 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:325 msgid "The homeserver will still continue to use its local database for validating existing access tokens." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:314 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:327 msgid "Various [compatibility layer URLs](https://element-hq.github.io/matrix-authentication-service/setup/homeserver.html#set-up-the-compatibility-layer) are not yet installed. New login sessions will still be forwarded to the homeserver, which is capable of completing them." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:316 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:329 msgid "The `matrix-user-creator` role would be suppressed, so that it doesn't automatically attempt to create users (for bots, etc.) in the MAS database. These user accounts likely already exist in Synapse's user database and could be migrated over (via syn2mas, as per the steps below), so creating them in the MAS database would have been unnecessary and potentially problematic (conflicts during the syn2mas migration)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:318 -msgid "Consider taking a full [backup of your Postgres database](./maintenance-postgres.md#backing-up-postgresql). This is done just in case. The **syn2mas migration tool does not delete any data**, so it should be possible to revert to your previous setup by merely disabling MAS and re-running the playbook (no need to restore a Postgres backup). However, do note that as users start logging in (creating new login sessions) via the new MAS setup, disabling MAS and reverting back to the Synapse user database will cause these new sessions to break." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:331 +msgid "Consider taking a full [backup of your Postgres database](./maintenance-postgres.md#backing-up-postgresql). This is done just in case. The **syn2mas migration command does not delete any data**, so it should be possible to revert to your previous setup by merely disabling MAS and re-running the playbook (no need to restore a Postgres backup). However, do note that as users start logging in (creating new login sessions) via the new MAS setup, disabling MAS and reverting back to the Synapse user database will cause these new sessions to break." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:320 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:333 msgid "[Migrate your data from Synapse to Matrix Authentication Service using syn2mas](#migrate-your-data-from-synapse-to-matrix-authentication-service-using-syn2mas)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:322 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:335 msgid "[Adjust your configuration](#adjusting-the-playbook-configuration) again, to:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:324 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:337 msgid "remove the `matrix_authentication_service_migration_in_progress: false` line" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:326 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:339 msgid "if you had been using [OIDC providers configured in Synapse](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on), remove all Synapse OIDC-related configuration (`matrix_synapse_oidc_*`) to prevent it being in conflict with the MAS OIDC configuration" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:328 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:341 msgid "Perform the [installation](#installing) again. At this point:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:330 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:343 msgid "The homeserver will start delegating authentication to MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:332 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:345 msgid "The compatibility layer URLs will be installed. New login sessions will be completed by MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:334 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:347 msgid "[Verify that Matrix Authentication Service is installed correctly](#verify-that-matrix-authentication-service-is-installed-correctly)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:336 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:349 msgid "Migrate your data from Synapse to Matrix Authentication Service using syn2mas" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:338 -msgid "We **don't** ask you to [run the `syn2mas` migration advisor command](https://element-hq.github.io/matrix-authentication-service/setup/migration.html#run-the-migration-advisor), because it only gives you the green light if your Synapse configuration (`homeserver.yaml`) is configured in a way that's compatible with MAS (delegating authentication to MAS; disabling Synapse's password config; etc.). Until we migrate your data with the `syn2mas` tool, we intentionally avoid doing these changes to allow existing user sessions to work." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:340 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:351 msgid "You can invoke the `syn2mas` tool via the playbook by running the playbook's `matrix-authentication-service-mas-cli-syn2mas` tag. We recommend first doing a [dry-run](#performing-a-syn2mas-dry-run) and then a [real migration](#performing-a-real-syn2mas-migration)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:342 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:353 msgid "Configuring syn2mas" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:344 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:355 msgid "If you're using [OIDC with Synapse](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on), you will need to [Configuring upstream OIDC provider mapping for syn2mas](#configuring-upstream-oidc-provider-mapping-for-syn2mas)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:346 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:357 msgid "If you only have local (non-OIDC) users in your Synapse database, you can likely run `syn2mas` as-is (without doing additional configuration changes)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:348 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:359 msgid "When you're done with potentially configuring `syn2mas`, proceed to doing a [dry-run](#performing-a-syn2mas-dry-run) and then a [real migration](#performing-a-real-syn2mas-migration)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:350 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:361 msgid "Configuring upstream OIDC provider mapping for syn2mas" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:352 -msgid "If you have existing OIDC users in your Synapse user database (which will be the case if when using [OIDC with Synapse](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on)), you may need to pass an additional `--upstreamProviderMapping` argument to the `syn2mas` tool to tell it which provider (on the Synapse side) maps to which other provider on the MAS side." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:354 -msgid "If you don't do this, `syn2mas` would report errors like this one:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:356 -msgid "[FATAL] migrate - [Failed to import external id 4264b0f0-4f11-4ddd-aedb-b500e4d07c25 with oidc-keycloak for user @alice:example.com: Error: Unknown upstream provider oidc-keycloak]" +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:363 +msgid "Since Matrix Authentication Service v0.16.0 (which replaced the standalone `syn2mas` tool with a `mas-cli syn2mas` sub-command), OIDC configuration (mapping from your old OIDC configuration to your new one, etc) is meant to be configured in the Matrix Authentication Service configuration (via `matrix_authentication_service_config_upstream_oauth2_providers`) as a `synapse_idp_id` property for each provider." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:358 -msgid "Below is an example situation and a guide for how to solve it." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:365 +msgid "You can refer to the [Map any upstream SSO providers](https://element-hq.github.io/matrix-authentication-service/setup/migration.html#map-any-upstream-sso-providers) section of the MAS documentation for figuring out how to set the `synapse_idp_id` value in `matrix_authentication_service_config_upstream_oauth2_providers` correctly." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:360 -msgid "If in `matrix_synapse_oidc_providers` your provider `idp_id` is (was) named `keycloak`, in the Synapse database users would be associated with the `oidc-keycloak` provider (note the `oidc-` prefix that was added automatically by Synapse to your `idp_id` value)." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:362 -msgid "The same OIDC provider may have an `id` of `01HFVBY12TMNTYTBV8W921M5FA` on the MAS side, as defined in `matrix_authentication_service_config_upstream_oauth2_providers` (see the [Upstream OAuth2 configuration](#upstream-oauth2-configuration) section above)." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:364 -msgid "To tell `syn2mas` how the Synapse-configured OIDC provider maps to the new MAS-configured OIDC provider, add this additional configuration to your `vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:373 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:367 msgid "Performing a syn2mas dry-run" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:375 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:369 msgid "Having [configured syn2mas](#configuring-syn2mas), we recommend doing a [dry-run](https://en.wikipedia.org/wiki/Dry_run_(testing)) first to verify that everything will work out as expected." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:377 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:371 msgid "A dry-run would not cause downtime, because it avoids stopping Synapse." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:379 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:373 msgid "To perform a dry-run, run:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:385 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:379 msgid "Observe the command output (especially the last line of the the syn2mas output). If you are confident that the migration will work out as expected, you can proceed with a [real migration](#performing-a-real-syn2mas-migration)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:387 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:381 msgid "Performing a real syn2mas migration" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:389 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:383 msgid "Before performing a real migration make sure:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:391 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:385 msgid "you've familiarized yourself with the [expectations](#expectations)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:393 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:387 msgid "you've performed a Postgres backup, just in case" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:395 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:389 msgid "you're aware of the irreversibility of the migration process without disruption after users have created new login sessions via the new MAS setup" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:397 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:391 msgid "you've [configured syn2mas](#configuring-syn2mas), especially if you've used [OIDC with Synapse](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:399 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:393 msgid "you've performed a [syn2mas dry-run](#performing-a-syn2mas-dry-run) and don't see any issues in its output" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:401 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:395 msgid "To perform a real migration, run the `matrix-authentication-service-mas-cli-syn2mas` tag **without** the `matrix_authentication_service_syn2mas_migrate_dry_run` variable:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:407 -msgid "Having performed a `syn2mas` migration once, trying to do it again will report errors for users that were already migrated (e.g. \"Error: Unknown upstream provider oauth-delegated\")." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:401 +msgid "After `syn2mas` completes, Synapse will intentionally remain stopped to avoid new registrations or other authentication changes from being accepted before the migration is completed. Continue with the next steps in this guide before re-running the installation." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:409 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:403 +msgid "Having performed a `syn2mas` migration once, trying to do it again will report errors (e.g. \"Error: The MAS database is not empty: rows found in at least `users`. Please drop and recreate the database, then try again.\")." +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:405 msgid "Verify that Matrix Authentication Service is installed correctly" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:411 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:407 msgid "After [installation](#installing), run the `doctor` subcommand of the [`mas-cli` command-line tool](https://element-hq.github.io/matrix-authentication-service/reference/cli/index.html) to verify that MAS is installed correctly." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:413 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:409 msgid "You can do it:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:415 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:411 msgid "either via the Ansible playbook's `matrix-authentication-service-mas-cli-doctor` tag: `just run-tags matrix-authentication-service-mas-cli-doctor`" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:417 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:413 msgid "or by running the `mas-cli` script on the server (which invokes the `mas-cli` tool inside a container): `/matrix/matrix-authentication-service/bin/mas-cli doctor`" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:419 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:415 msgid "If successful, you should see some output that looks like this:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:431 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:427 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:429 msgid "Management" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:433 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:431 msgid "You can use the [`mas-cli` command-line tool](https://element-hq.github.io/matrix-authentication-service/reference/cli/index.html) (exposed via the `/matrix/matrix-authentication-service/bin/mas-cli` script) to perform administrative tasks against MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:435 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:433 msgid "This documentation page already mentions:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:437 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:435 msgid "the `mas-cli doctor` sub-command in the [Verify that Matrix Authentication Service is installed correctly](#verify-that-matrix-authentication-service-is-installed-correctly) section, which you can run via the CLI and via the Ansible playbook's `matrix-authentication-service-mas-cli-doctor` tag" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:439 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:437 msgid "the `mas-cli manage register-user` sub-command in the [Registering users](./registering-users.md) documentation" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:441 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:439 msgid "There are other sub-commands available. Run `/matrix/matrix-authentication-service/bin/mas-cli` to get an overview." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:443 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:441 msgid "User registration" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:445 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:443 msgid "After Matrix Authentication Service is [installed](#installing), users need to be managed there (unless you're managing them in an [upstream OAuth2 provider](#upstream-oauth2-configuration))." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:447 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:445 msgid "You can register users new users as described in the [Registering users](./registering-users.md) documentation (via `mas-cli manage register-user` or the Ansible playbook's `register-user` tag)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:449 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:447 msgid "Working around email deliverability issues" msgstr "" +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:449 +msgid "Matrix Authentication Service only sends emails when:" +msgstr "" + #: ../../../docs/configuring-playbook-matrix-authentication-service.md:451 -msgid "Because Matrix Authentication Service [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user, you may need to work around email deliverability issues if [your email-sending configuration](./configuring-playbook-email.md) is not working." +msgid "it verifies email addresses for users who are self-registering with a password" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:453 -msgid "Matrix Authentication Service attempts to verify email addresses by sending a verification email to the address specified by the user whenever they log in to an account without a verified email address." +msgid "a user tries to add an email to their account" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:455 -msgid "If email delivery is not working, **you can retrieve the email configuration code from the Matrix Authentication Service's logs** (`journalctl -fu matrix-authentication-service`)." +msgid "If Matrix Authentication Service tries to send an email and it fails because [your email-sending configuration](./configuring-playbook-email.md) is not working, you may need to work around email deliverability." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:457 +msgid "If email delivery is not working, **you can retrieve the email verification code from the Matrix Authentication Service's logs** (`journalctl -fu matrix-authentication-service`)." +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:459 msgid "Alternatively, you can use the [`mas-cli` management tool](#management) to manually verify email addresses for users. Example: `/matrix/matrix-authentication-service/bin/mas-cli manage verify-email some.username email@example.com`" msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:461 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:463 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-authentication-service`." +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-synapse.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-synapse.po index 579bd895c..280cb6a51 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-synapse.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook-synapse.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,261 +19,305 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-synapse.md:1 +#: ../../../docs/configuring-playbook-synapse.md:12 msgid "Configuring Synapse (optional)" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:3 +#: ../../../docs/configuring-playbook-synapse.md:14 msgid "By default, this playbook configures the [Synapse](https://github.com/element-hq/synapse) Matrix server, so that it works for the general case. If that's okay, you can skip this document." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:5 +#: ../../../docs/configuring-playbook-synapse.md:16 +msgid "💡 See this page for details about maintaining Synapse: [Synapse maintenance](maintenance-synapse.md)" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:18 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:7 +#: ../../../docs/configuring-playbook-synapse.md:20 msgid "Load balancing with workers" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:9 +#: ../../../docs/configuring-playbook-synapse.md:22 msgid "To have Synapse gracefully handle thousands of users, worker support should be enabled. It factors out some homeserver tasks and spreads the load of incoming client and server-to-server traffic between multiple processes. More information can be found in the [official Synapse workers documentation](https://github.com/element-hq/synapse/blob/master/docs/workers.md) and [Tom Foster](https://github.com/tcpipuk)'s [Synapse homeserver guide](https://tcpipuk.github.io/synapse/index.html)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:11 +#: ../../../docs/configuring-playbook-synapse.md:24 msgid "To enable Synapse worker support, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:19 +#: ../../../docs/configuring-playbook-synapse.md:32 msgid "By default, this enables the `one-of-each` [worker preset](#worker-presets), but you may wish to use another preset or [control the number of worker instances](#controlling-the-number-of-worker-instances)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:21 +#: ../../../docs/configuring-playbook-synapse.md:34 msgid "Worker presets" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:23 +#: ../../../docs/configuring-playbook-synapse.md:36 msgid "We support a few configuration presets (`matrix_synapse_workers_preset: one-of-each` being the default configuration right now):" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:25 +#: ../../../docs/configuring-playbook-synapse.md:38 msgid "(federation-only) `little-federation-helper` — a very minimal worker configuration to improve federation performance" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:26 +#: ../../../docs/configuring-playbook-synapse.md:39 msgid "(generic) `one-of-each` — defaults to one worker of each supported type — no smart routing, just generic workers" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:27 +#: ../../../docs/configuring-playbook-synapse.md:40 msgid "(specialized) `specialized-workers` — defaults to one worker of each supported type, but disables generic workers and uses [specialized workers](#specialized-workers) instead" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:29 +#: ../../../docs/configuring-playbook-synapse.md:42 msgid "These presets represent a few common configurations. There are many worker types which can be mixed and matched based on your needs." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:31 +#: ../../../docs/configuring-playbook-synapse.md:44 msgid "Generic workers" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:33 +#: ../../../docs/configuring-playbook-synapse.md:46 msgid "Previously, the playbook only supported the most basic type of load-balancing. We call it **generic load-balancing** below, because incoming HTTP requests are sent to a generic worker. Load-balancing was done based on the requestor's IP address. This is simple, but not necessarily optimal. If you're accessing your account from multiple IP addresses (e.g. your mobile phone being on a different network than your PC), these separate requests may potentially be routed to different workers, each of which would need to cache roughly the same data." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:35 +#: ../../../docs/configuring-playbook-synapse.md:48 msgid "This is **still the default load-balancing method (preset) used by the playbook**." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:37 +#: ../../../docs/configuring-playbook-synapse.md:50 msgid "To use generic load-balancing, do not specify `matrix_synapse_workers_preset` to make it use the default value (`one-of-each`), or better yet — explicitly set it as `one-of-each`." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:39 +#: ../../../docs/configuring-playbook-synapse.md:52 msgid "You may also consider [tweaking the number of workers of each type](#controlling-the-number-of-worker-instances) from the default (one of each)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:41 +#: ../../../docs/configuring-playbook-synapse.md:54 msgid "Specialized workers" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:43 -msgid "The playbook now supports a smarter **specialized load-balancing** inspired by [Tom Foster](https://github.com/tcpipuk)'s [Synapse homeserver guide](https://tcpipuk.github.io/synapse/index.html). Instead of routing requests to one or more [generic workers](#generic-workers) based only on the requestor's IP adddress, specialized load-balancing routes to **4 different types of specialized workers** based on **smarter criteria** — the access token (username) of the requestor and/or on the resource (room, etc.) being requested." +#: ../../../docs/configuring-playbook-synapse.md:56 +msgid "The playbook now supports a smarter **specialized load-balancing** inspired by [Tom Foster](https://github.com/tcpipuk)'s [Synapse homeserver guide](https://tcpipuk.github.io/synapse/index.html). Instead of routing requests to one or more [generic workers](#generic-workers) based only on the requester's IP address, specialized load-balancing routes to **4 different types of specialized workers** based on **smarter criteria** — the access token (username) of the requester and/or on the resource (room, etc.) being requested." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:45 +#: ../../../docs/configuring-playbook-synapse.md:58 msgid "The playbook supports these **4 types** of specialized workers:" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:47 +#: ../../../docs/configuring-playbook-synapse.md:60 msgid "Room workers — handles various [Client-Server](https://spec.matrix.org/v1.9/client-server-api/) & [Federation](https://spec.matrix.org/v1.9/server-server-api) APIs dedicated to handling specific rooms" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:48 +#: ../../../docs/configuring-playbook-synapse.md:61 msgid "Sync workers — handles various [Client-Server](https://spec.matrix.org/v1.9/client-server-api/) APIs related to synchronization (most notably [the `/sync` endpoint](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3sync))" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:49 +#: ../../../docs/configuring-playbook-synapse.md:62 msgid "Client readers — handles various [Client-Server](https://spec.matrix.org/v1.9/client-server-api/) APIs which are not for specific rooms (handled by **room workers**) or for synchronization (handled by **sync workers**)" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:50 +#: ../../../docs/configuring-playbook-synapse.md:63 msgid "Federation readers — handles various [Federation](https://spec.matrix.org/v1.9/server-server-api) APIs which are not for specific rooms (handled by **room workers**)" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:52 +#: ../../../docs/configuring-playbook-synapse.md:65 msgid "To use specialized load-balancing, consider enabling the `specialized-workers` [worker preset](#worker-presets) and potentially [tweaking the number of workers of each type](#controlling-the-number-of-worker-instances) from the default (one of each)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:54 +#: ../../../docs/configuring-playbook-synapse.md:67 msgid "Controlling the number of worker instances" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:56 +#: ../../../docs/configuring-playbook-synapse.md:69 msgid "If you'd like more customization power, you can start with one of the [worker presets](#worker-presets) and then tweak various `matrix_synapse_workers_*_count` variables manually." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:58 +#: ../../../docs/configuring-playbook-synapse.md:71 msgid "To find what variables are available for you to override in your own `vars.yml` configuration file, see the [`defaults/main.yml` file for the `matrix-synapse` Ansible role](../roles/custom/matrix-synapse/defaults/main.yml)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:60 +#: ../../../docs/configuring-playbook-synapse.md:73 msgid "The only thing you **cannot** do is mix [generic workers](#generic-workers) and [specialized workers](#specialized-workers)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:62 +#: ../../../docs/configuring-playbook-synapse.md:75 msgid "Effect of enabling workers on the rest of your server" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:64 +#: ../../../docs/configuring-playbook-synapse.md:77 msgid "When Synapse workers are enabled, the integrated [Postgres database is tuned](maintenance-postgres.md#tuning-postgresql), so that the maximum number of Postgres connections are increased from `200` to `500`. If you need to decrease or increase the number of maximum Postgres connections further, use the `postgres_max_connections` variable." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:66 -msgid "A separate Ansible role (`matrix-synapse-reverse-proxy-companion`) and component handles load-balancing for workers. This role/component is automatically enabled when you enable workers. Make sure to use the `setup-all` tag (not `install-all`!) during the playbook's [installation](./installing.md) process, especially if you're disabling workers, so that components may be installed/uninstalled correctly." +#: ../../../docs/configuring-playbook-synapse.md:79 +msgid "The `matrix-synapse` role also manages the `matrix-synapse-reverse-proxy-companion` component for load-balancing with workers. This component is automatically enabled when you enable workers. Make sure to use the `setup-all` tag (not `install-all`!) during the playbook's [installation](./installing.md) process, especially if you're disabling workers, so that components may be installed/uninstalled correctly." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:68 +#: ../../../docs/configuring-playbook-synapse.md:81 msgid "In case any problems occur, make sure to have a look at the [list of synapse issues about workers](https://github.com/element-hq/synapse/issues?q=workers+in%3Atitle) and your `journalctl --unit 'matrix-*'`." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:70 +#: ../../../docs/configuring-playbook-synapse.md:83 +msgid "Limit joining heavy rooms on constrained hosts" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:85 +msgid "If your server is underpowered, joining heavy rooms can cause Synapse to consume a lot of resources and be unavailable for long (while it catches up)." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:87 +msgid "To avoid this, Synapse can be configured to reject joins for remote rooms that are too complex before users enter them." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:89 +msgid "Complexity is computed as `current_state_events / 500` (Synapse state event count for current room state). When the resulting value is higher than `matrix_synapse_limit_remote_rooms_complexity` and `matrix_synapse_limit_remote_rooms_enabled` is `true`, Synapse blocks joining the room." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:91 +msgid "We recommend using this as a guardrail on low-resource servers:" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:106 msgid "Synapse + OpenID Connect for Single-Sign-On" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:72 +#: ../../../docs/configuring-playbook-synapse.md:108 msgid "💡 An alternative to setting up OIDC in Synapse is to use [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) (MAS). Newer clients (like Element X) only support SSO-based authentication via MAS and not via the legacy Synapse OIDC setup described below. That said, MAS is still a new experimental service which comes with its own downsides. Consult its documentation to learn if it will be a good fit for your deployment." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:74 +#: ../../../docs/configuring-playbook-synapse.md:110 msgid "If you'd like to use OpenID Connect authentication with Synapse, you'll need some additional configuration." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:76 +#: ../../../docs/configuring-playbook-synapse.md:112 msgid "This example configuration is for [keycloak](https://www.keycloak.org/), an opensource Identity Provider maintained by Red Hat." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:78 +#: ../../../docs/configuring-playbook-synapse.md:114 msgid "For more detailed documentation on available options and how to setup keycloak, see the [Synapse documentation on OpenID Connect with keycloak](https://github.com/element-hq/synapse/blob/develop/docs/openid.md#keycloak)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:80 -#, python-format +#: ../../../docs/configuring-playbook-synapse.md:116 +#, python-format, python-brace-format msgid "In case you encounter errors regarding the parsing of the variables, you can try to add `{% raw %}` and `{% endraw %}` blocks around them. For example ;" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:101 +#: ../../../docs/configuring-playbook-synapse.md:137 msgid "Customizing templates" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:103 +#: ../../../docs/configuring-playbook-synapse.md:139 msgid "[Templates](https://github.com/element-hq/synapse/blob/develop/docs/templates.md) are used by Synapse for showing **certain web pages** handled by the server, as well as for **email notifications**." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:105 +#: ../../../docs/configuring-playbook-synapse.md:141 msgid "This playbook allows you to customize the default templates (see the [`synapse/res/templates` directory](https://github.com/element-hq/synapse/tree/develop/synapse/res/templates))." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:107 +#: ../../../docs/configuring-playbook-synapse.md:143 msgid "If template customization is enabled, the playbook will build a custom container image based on the official one." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:109 +#: ../../../docs/configuring-playbook-synapse.md:145 msgid "Your custom templates need to live in a public or private git repository. This repository will be cloned during Synapse image customization (during the playbook run)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:111 +#: ../../../docs/configuring-playbook-synapse.md:147 msgid "To enable template customizations, add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:137 +#: ../../../docs/configuring-playbook-synapse.md:173 msgid "As mentioned in Synapse's Templates documentation, Synapse will fall back to its own templates if a template is not found in that directory. Due to this, it's recommended to only store and maintain template files in your repository if you need to make custom changes. Other files (which you don't need to change), should not be duplicated, so that you don't need to worry about getting out-of-sync with the original Synapse templates." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:139 +#: ../../../docs/configuring-playbook-synapse.md:175 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:141 +#: ../../../docs/configuring-playbook-synapse.md:177 msgid "There are some additional things you may wish to configure about the server." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:143 +#: ../../../docs/configuring-playbook-synapse.md:179 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:145 +#: ../../../docs/configuring-playbook-synapse.md:181 msgid "`roles/custom/matrix-synapse/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:146 +#: ../../../docs/configuring-playbook-synapse.md:182 msgid "`roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2` for the server's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_synapse_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:148 +#: ../../../docs/configuring-playbook-synapse.md:184 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:150 +#: ../../../docs/configuring-playbook-synapse.md:186 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:157 +#: ../../../docs/configuring-playbook-synapse.md:193 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:159 +#: ../../../docs/configuring-playbook-synapse.md:195 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:161 +#: ../../../docs/configuring-playbook-synapse.md:197 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:163 -msgid "Synapse Admin" +#: ../../../docs/configuring-playbook-synapse.md:199 +msgid "Ketesa" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:165 -msgid "With [Synapse Admin](configuring-playbook-synapse-admin.md), certain Synapse administration tasks (managing users and rooms, etc.) can be performed via a web user-interace." +#: ../../../docs/configuring-playbook-synapse.md:201 +msgid "[Ketesa](configuring-playbook-ketesa.md) is a fully-featured web UI for administrating your homeserver — managing users, rooms, media, sessions, and more." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:167 -msgid "The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md)." +#: ../../../docs/configuring-playbook-synapse.md:203 +msgid "The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:169 +#: ../../../docs/configuring-playbook-synapse.md:205 msgid "Monitoring Synapse Metrics with Prometheus and Grafana" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:171 +#: ../../../docs/configuring-playbook-synapse.md:207 msgid "This playbook allows you to enable Synapse metrics, which can provide insight into the performance and activity of Synapse." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:173 -msgid "To enable Synapse runtime metrics see: [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md)" +#: ../../../docs/configuring-playbook-synapse.md:209 +msgid "To enable Synapse runtime metrics, see: [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md) and [its subsection](configuring-playbook-prometheus-grafana.md#expose-metrics-of-other-services-roles)" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:175 +#: ../../../docs/configuring-playbook-synapse.md:211 msgid "To enable Synapse usage metrics, see: [Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md)" msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:213 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:215 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-synapse`." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:217 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:219 +msgid "Because Synapse is originally very chatty when it comes to logging, we intentionally reduce its [logging level](https://docs.python.org/3/library/logging.html#logging-levels) from `INFO` to `WARNING`." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:221 +msgid "If you'd like to debug an issue or [report a Synapse bug](https://github.com/element-hq/synapse/issues/new/choose) to the developers, it'd be better if you temporarily increase the logging verbosity to `INFO`. To do so, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook.po b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook.po index 68873c18e..427a912fe 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/configuring-playbook.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,528 +19,568 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook.md:1 +#: ../../../docs/configuring-playbook.md:17 msgid "Configuring the playbook" msgstr "" -#: ../../../docs/configuring-playbook.md:3 -msgid "[Prerequisites](prerequisites.md) > [Configuring your DNS settings](configuring-dns.md) > [Getting the playbook](getting-the-playbook.md) > Configuring the playbook > [Installing](installing.md)" +#: ../../../docs/configuring-playbook.md:19 +msgid "[Prerequisites](prerequisites.md) > [Configuring DNS settings](configuring-dns.md) > [Getting the playbook](getting-the-playbook.md) > Configuring the playbook > [Installing](installing.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:5 +#: ../../../docs/configuring-playbook.md:21 msgid "If you've configured your DNS records and retrieved the playbook's source code to your computer, you can start configuring the playbook. To do so, follow these steps inside the playbook directory:" msgstr "" -#: ../../../docs/configuring-playbook.md:7 +#: ../../../docs/configuring-playbook.md:23 msgid "create a directory to hold your configuration (`mkdir -p inventory/host_vars/matrix.example.com` where `example.com` is your \"base domain\")" msgstr "" -#: ../../../docs/configuring-playbook.md:9 +#: ../../../docs/configuring-playbook.md:25 msgid "copy the sample configuration file (`cp examples/vars.yml inventory/host_vars/matrix.example.com/vars.yml`)" msgstr "" -#: ../../../docs/configuring-playbook.md:11 -msgid "edit the configuration file (`inventory/host_vars/matrix.example.com/vars.yml`) to your liking. You may also take a look at the various `roles/*/ROLE_NAME_HERE/defaults/main.yml` files and see if there's something you'd like to copy over and override in your `vars.yml` configuration file." +#: ../../../docs/configuring-playbook.md:27 +msgid "edit the configuration file (`inventory/host_vars/matrix.example.com/vars.yml`) to your liking. You may also take a look at the various `roles/*/ROLE_NAME_HERE/defaults/main.yml` files (after importing external roles with `just update` into `roles/galaxy`) and see if there's something you'd like to copy over and override in your `vars.yml` configuration file." msgstr "" -#: ../../../docs/configuring-playbook.md:13 +#: ../../../docs/configuring-playbook.md:29 msgid "copy the sample inventory hosts file (`cp examples/hosts inventory/hosts`)" msgstr "" -#: ../../../docs/configuring-playbook.md:15 +#: ../../../docs/configuring-playbook.md:31 msgid "edit the inventory hosts file (`inventory/hosts`) to your liking" msgstr "" -#: ../../../docs/configuring-playbook.md:17 -msgid "(optional, advanced) you may wish to keep your `inventory` directory under version control with [git](https://git-scm.com/) or any other version-control system." +#: ../../../docs/configuring-playbook.md:33 +msgid "(optional, advanced) you may wish to keep your `inventory` directory under version control with [git](https://git-scm.com/) or any other version-control system. The `inventory` directory path is ignored via `.gitignore`, so it won't be part of the playbook repository. You can safely create a new git repository inside that directory with `git init`, etc." msgstr "" -#: ../../../docs/configuring-playbook.md:19 +#: ../../../docs/configuring-playbook.md:35 msgid "(optional, advanced) to run Ansible against multiple servers with different `sudo` credentials, you can copy the sample inventory hosts yaml file for each of your hosts: (`cp examples/host.yml inventory/my_host1.yml` …) and use the [`ansible-all-hosts.sh`](../bin/ansible-all-hosts.sh) script [in the installation step](installing.md)." msgstr "" -#: ../../../docs/configuring-playbook.md:21 +#: ../../../docs/configuring-playbook.md:37 msgid "For a basic Matrix installation, that's all you need." msgstr "" -#: ../../../docs/configuring-playbook.md:23 +#: ../../../docs/configuring-playbook.md:39 msgid "For a more custom setup, see the [Other configuration options](#other-configuration-options) below." msgstr "" -#: ../../../docs/configuring-playbook.md:25 +#: ../../../docs/configuring-playbook.md:41 msgid "[▶️](installing.md) When you're done with all the configuration you'd like to do, continue with [Installing](installing.md)." msgstr "" -#: ../../../docs/configuring-playbook.md:27 +#: ../../../docs/configuring-playbook.md:43 msgid "Other configuration options" msgstr "" -#: ../../../docs/configuring-playbook.md:29 +#: ../../../docs/configuring-playbook.md:45 msgid "**Note**: some of the roles like one for integrating Etherpad or Jitsi are managed by their own repositories, and the configuration files for them cannot be found locally (in `roles/galaxy`) until those roles are fetched from the upstream projects. Check [requirements.yml](../requirements.yml) for the URLs of those roles." msgstr "" -#: ../../../docs/configuring-playbook.md:31 +#: ../../../docs/configuring-playbook.md:47 msgid "Core service adjustments" msgstr "" -#: ../../../docs/configuring-playbook.md:33 +#: ../../../docs/configuring-playbook.md:49 msgid "Homeserver configuration:" msgstr "" -#: ../../../docs/configuring-playbook.md:34 +#: ../../../docs/configuring-playbook.md:50 msgid "[Configuring Synapse](configuring-playbook-synapse.md), if you're going with the default/recommended homeserver implementation" msgstr "" -#: ../../../docs/configuring-playbook.md:36 +#: ../../../docs/configuring-playbook.md:52 msgid "[Configuring Conduit](configuring-playbook-conduit.md), if you've switched to the [Conduit](https://conduit.rs) homeserver implementation" msgstr "" -#: ../../../docs/configuring-playbook.md:38 -msgid "[Configuring conduwuit](configuring-playbook-conduwuit.md), if you've switched to the [conduwuit](https://conduwuit.puppyirl.gay/) homeserver implementation" +#: ../../../docs/configuring-playbook.md:54 +msgid "[Configuring continuwuity](configuring-playbook-continuwuity.md), if you've switched to the [continuwuity](https://continuwuity.org) homeserver implementation" msgstr "" -#: ../../../docs/configuring-playbook.md:40 +#: ../../../docs/configuring-playbook.md:56 msgid "[Configuring Dendrite](configuring-playbook-dendrite.md), if you've switched to the [Dendrite](https://matrix-org.github.io/dendrite) homeserver implementation" msgstr "" -#: ../../../docs/configuring-playbook.md:42 +#: ../../../docs/configuring-playbook.md:58 msgid "Server components:" msgstr "" -#: ../../../docs/configuring-playbook.md:43 +#: ../../../docs/configuring-playbook.md:59 msgid "[Using an external PostgreSQL server](configuring-playbook-external-postgres.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:45 +#: ../../../docs/configuring-playbook.md:61 msgid "[Configuring a TURN server](configuring-playbook-turn.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:47 +#: ../../../docs/configuring-playbook.md:63 msgid "[Configuring the Traefik reverse-proxy](configuring-playbook-traefik.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:49 +#: ../../../docs/configuring-playbook.md:65 msgid "[Using your own webserver, instead of this playbook's Traefik reverse-proxy](configuring-playbook-own-webserver.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:51 +#: ../../../docs/configuring-playbook.md:67 msgid "[Adjusting SSL certificate retrieval](configuring-playbook-ssl-certificates.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:53 +#: ../../../docs/configuring-playbook.md:69 msgid "[Adjusting email-sending settings](configuring-playbook-email.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:55 -msgid "[Setting up ma1sd Identity Server](configuring-playbook-ma1sd.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:57 +#: ../../../docs/configuring-playbook.md:71 msgid "[Setting up Dynamic DNS](configuring-playbook-dynamic-dns.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:59 +#: ../../../docs/configuring-playbook.md:73 msgid "Server connectivity:" msgstr "" -#: ../../../docs/configuring-playbook.md:60 +#: ../../../docs/configuring-playbook.md:74 msgid "[Enabling Telemetry for your Matrix server](configuring-playbook-telemetry.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:62 +#: ../../../docs/configuring-playbook.md:76 msgid "[Controlling Matrix federation](configuring-playbook-federation.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:64 +#: ../../../docs/configuring-playbook.md:78 +msgid "[Configuring IPv6](./configuring-ipv6.md)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:80 msgid "Clients" msgstr "" -#: ../../../docs/configuring-playbook.md:66 +#: ../../../docs/configuring-playbook.md:82 msgid "Web clients for Matrix that you can host on your own domains." msgstr "" -#: ../../../docs/configuring-playbook.md:68 +#: ../../../docs/configuring-playbook.md:84 msgid "[Configuring Element Web](configuring-playbook-client-element-web.md), if you're going with the default/recommended client" msgstr "" -#: ../../../docs/configuring-playbook.md:70 +#: ../../../docs/configuring-playbook.md:86 msgid "[Setting up Hydrogen](configuring-playbook-client-hydrogen.md), if you've enabled [Hydrogen](https://github.com/element-hq/hydrogen-web), a lightweight Matrix client with legacy and mobile browser support" msgstr "" -#: ../../../docs/configuring-playbook.md:72 +#: ../../../docs/configuring-playbook.md:88 msgid "[Setting up Cinny](configuring-playbook-client-cinny.md), if you've enabled [Cinny](https://github.com/ajbura/cinny), a web client focusing primarily on simple, elegant and secure interface" msgstr "" -#: ../../../docs/configuring-playbook.md:74 +#: ../../../docs/configuring-playbook.md:90 +msgid "[Setting up Sable](configuring-playbook-client-sable.md), if you've enabled [Sable](https://github.com/7w1/sable), a web client focusing primarily on simple, elegant and secure interface" +msgstr "" + +#: ../../../docs/configuring-playbook.md:92 msgid "[Setting up SchildiChat Web](configuring-playbook-client-schildichat-web.md), if you've enabled [SchildiChat Web](https://schildi.chat/), a web client based on [Element Web](https://element.io/) with some extras and tweaks" msgstr "" -#: ../../../docs/configuring-playbook.md:76 +#: ../../../docs/configuring-playbook.md:94 +msgid "[Setting up FluffyChat Web](configuring-playbook-client-fluffychat-web.md), if you've enabled [FluffyChat Web](https://github.com/krille-chan/fluffychat), a cute cross-platform messenger (web, iOS, Android) for Matrix written in [Flutter](https://flutter.dev/)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:97 msgid "Authentication and user-related" msgstr "" -#: ../../../docs/configuring-playbook.md:78 +#: ../../../docs/configuring-playbook.md:99 msgid "Extend and modify how users are authenticated on your homeserver." msgstr "" -#: ../../../docs/configuring-playbook.md:80 +#: ../../../docs/configuring-playbook.md:101 msgid "[Setting up Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) (Next-generation auth for Matrix, based on OAuth 2.0/OIDC)" msgstr "" -#: ../../../docs/configuring-playbook.md:82 +#: ../../../docs/configuring-playbook.md:103 msgid "[Setting up Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:84 -msgid "[Setting up Synapse Admin](configuring-playbook-synapse-admin.md)" +#: ../../../docs/configuring-playbook.md:105 +msgid "[Setting up Ketesa](configuring-playbook-ketesa.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:86 +#: ../../../docs/configuring-playbook.md:107 msgid "[Setting up matrix-registration](configuring-playbook-matrix-registration.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:88 +#: ../../../docs/configuring-playbook.md:109 msgid "[Setting up the REST authentication password provider module](configuring-playbook-rest-auth.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:90 +#: ../../../docs/configuring-playbook.md:111 msgid "[Setting up the Shared Secret Auth password provider module](configuring-playbook-shared-secret-auth.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:92 +#: ../../../docs/configuring-playbook.md:113 msgid "[Setting up the LDAP authentication password provider module](configuring-playbook-ldap-auth.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:94 +#: ../../../docs/configuring-playbook.md:115 msgid "[Setting up matrix-ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:96 +#: ../../../docs/configuring-playbook.md:117 msgid "[Setting up Synapse Simple Antispam](configuring-playbook-synapse-simple-antispam.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:98 +#: ../../../docs/configuring-playbook.md:119 msgid "[Setting up Matrix User Verification Service](configuring-playbook-user-verification-service.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:100 +#: ../../../docs/configuring-playbook.md:121 msgid "File Storage" msgstr "" -#: ../../../docs/configuring-playbook.md:102 +#: ../../../docs/configuring-playbook.md:123 msgid "Use alternative file storage to the default `media_store` folder." msgstr "" -#: ../../../docs/configuring-playbook.md:104 -msgid "[Storing Matrix media files on Amazon S3 with Goofys](configuring-playbook-s3-goofys.md)" +#: ../../../docs/configuring-playbook.md:125 +msgid "[Storing Matrix media files using matrix-media-repo](configuring-playbook-matrix-media-repo.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:106 +#: ../../../docs/configuring-playbook.md:127 msgid "[Storing Synapse media files on Amazon S3 or another compatible Object Storage](configuring-playbook-s3.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:108 -msgid "[Storing Matrix media files using matrix-media-repo](configuring-playbook-matrix-media-repo.md)" +#: ../../../docs/configuring-playbook.md:129 +msgid "[Storing Synapse media files on Amazon S3 with Goofys](configuring-playbook-s3-goofys.md)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:131 +msgid "[Storing Synapse media files on Amazon S3 with synapse-s3-storage-provider](configuring-playbook-synapse-s3-storage-provider.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:110 +#: ../../../docs/configuring-playbook.md:133 msgid "Bridging other networks" msgstr "" -#: ../../../docs/configuring-playbook.md:112 +#: ../../../docs/configuring-playbook.md:135 msgid "Bridges can be used to connect your Matrix installation with third-party communication networks." msgstr "" -#: ../../../docs/configuring-playbook.md:114 +#: ../../../docs/configuring-playbook.md:137 msgid "[Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md) — a common guide for configuring mautrix bridges" msgstr "" -#: ../../../docs/configuring-playbook.md:116 +#: ../../../docs/configuring-playbook.md:139 +msgid "[Setting up Mautrix Bluesky bridging](configuring-playbook-bridge-mautrix-bluesky.md)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:141 msgid "[Setting up Mautrix Discord bridging](configuring-playbook-bridge-mautrix-discord.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:118 +#: ../../../docs/configuring-playbook.md:143 msgid "[Setting up Mautrix Telegram bridging](configuring-playbook-bridge-mautrix-telegram.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:120 +#: ../../../docs/configuring-playbook.md:145 msgid "[Setting up Mautrix Slack bridging](configuring-playbook-bridge-mautrix-slack.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:122 +#: ../../../docs/configuring-playbook.md:147 msgid "[Setting up Mautrix Google Messages bridging](configuring-playbook-bridge-mautrix-gmessages.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:124 +#: ../../../docs/configuring-playbook.md:149 msgid "[Setting up Mautrix Whatsapp bridging](configuring-playbook-bridge-mautrix-whatsapp.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:126 +#: ../../../docs/configuring-playbook.md:151 msgid "[Setting up Instagram bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-instagram.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:128 +#: ../../../docs/configuring-playbook.md:153 msgid "[Setting up Messenger bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-messenger.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:130 +#: ../../../docs/configuring-playbook.md:155 msgid "[Setting up Mautrix Google Chat bridging](configuring-playbook-bridge-mautrix-googlechat.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:132 +#: ../../../docs/configuring-playbook.md:157 msgid "[Setting up Mautrix Twitter bridging](configuring-playbook-bridge-mautrix-twitter.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:134 +#: ../../../docs/configuring-playbook.md:159 msgid "[Setting up Mautrix Signal bridging](configuring-playbook-bridge-mautrix-signal.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:136 +#: ../../../docs/configuring-playbook.md:161 msgid "[Setting up Mautrix wsproxy for bridging Android SMS or Apple iMessage](configuring-playbook-bridge-mautrix-wsproxy.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:138 +#: ../../../docs/configuring-playbook.md:163 msgid "[Setting up Appservice IRC bridging](configuring-playbook-bridge-appservice-irc.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:140 +#: ../../../docs/configuring-playbook.md:165 msgid "[Setting up Appservice Discord bridging](configuring-playbook-bridge-appservice-discord.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:142 -msgid "[Setting up Appservice Slack bridging](configuring-playbook-bridge-appservice-slack.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:144 +#: ../../../docs/configuring-playbook.md:167 msgid "[Setting up Appservice Kakaotalk bridging](configuring-playbook-bridge-appservice-kakaotalk.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:146 +#: ../../../docs/configuring-playbook.md:169 msgid "[Setting up Beeper LinkedIn bridging](configuring-playbook-bridge-beeper-linkedin.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:148 +#: ../../../docs/configuring-playbook.md:171 msgid "[Setting up matrix-hookshot](configuring-playbook-bridge-hookshot.md) — a bridge between Matrix and multiple project management services, such as [GitHub](https://github.com), [GitLab](https://about.gitlab.com) and [JIRA](https://www.atlassian.com/software/jira)." msgstr "" -#: ../../../docs/configuring-playbook.md:150 -msgid "[Setting up MX Puppet Slack bridging](configuring-playbook-bridge-mx-puppet-slack.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:152 -msgid "[Setting up MX Puppet Instagram bridging](configuring-playbook-bridge-mx-puppet-instagram.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:154 -msgid "[Setting up MX Puppet Twitter bridging](configuring-playbook-bridge-mx-puppet-twitter.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:156 -msgid "[Setting up MX Puppet Discord bridging](configuring-playbook-bridge-mx-puppet-discord.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:158 +#: ../../../docs/configuring-playbook.md:173 msgid "[Setting up MX Puppet GroupMe bridging](configuring-playbook-bridge-mx-puppet-groupme.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:160 -msgid "[Setting up MX Puppet Steam bridging](configuring-playbook-bridge-mx-puppet-steam.md)" +#: ../../../docs/configuring-playbook.md:175 +msgid "[Setting up Steam bridging](configuring-playbook-bridge-steam.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:162 -msgid "[Setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md)" +#: ../../../docs/configuring-playbook.md:177 +msgid "[Setting up MX Puppet Steam bridging](configuring-playbook-bridge-mx-puppet-steam.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:164 +#: ../../../docs/configuring-playbook.md:179 msgid "[Setting up Postmoogle email bridging](configuring-playbook-bridge-postmoogle.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:166 +#: ../../../docs/configuring-playbook.md:181 msgid "[Setting up Matrix SMS bridging](configuring-playbook-bridge-matrix-bridge-sms.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:168 +#: ../../../docs/configuring-playbook.md:183 msgid "[Setting up Heisenbridge bouncer-style IRC bridging](configuring-playbook-bridge-heisenbridge.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:170 +#: ../../../docs/configuring-playbook.md:185 msgid "[Setting up WeChat bridging](configuring-playbook-bridge-wechat.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:172 +#: ../../../docs/configuring-playbook.md:187 msgid "Bots" msgstr "" -#: ../../../docs/configuring-playbook.md:174 +#: ../../../docs/configuring-playbook.md:189 msgid "Bots provide various additional functionality to your installation." msgstr "" -#: ../../../docs/configuring-playbook.md:176 +#: ../../../docs/configuring-playbook.md:191 msgid "[Setting up baibot](configuring-playbook-bot-baibot.md) — a bot through which you can talk to various [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) services ([OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/) and [others](https://github.com/etkecc/baibot/blob/main/docs/providers.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:178 +#: ../../../docs/configuring-playbook.md:193 msgid "[Setting up matrix-reminder-bot](configuring-playbook-bot-matrix-reminder-bot.md) — a bot to remind you about stuff" msgstr "" -#: ../../../docs/configuring-playbook.md:180 +#: ../../../docs/configuring-playbook.md:195 msgid "[Setting up matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md) — a bot to create and manage registration tokens to invite users" msgstr "" -#: ../../../docs/configuring-playbook.md:182 +#: ../../../docs/configuring-playbook.md:197 msgid "[Setting up maubot](configuring-playbook-bot-maubot.md) — a plugin-based Matrix bot system" msgstr "" -#: ../../../docs/configuring-playbook.md:184 +#: ../../../docs/configuring-playbook.md:199 msgid "[Setting up Honoroit](configuring-playbook-bot-honoroit.md) — a helpdesk bot" msgstr "" -#: ../../../docs/configuring-playbook.md:186 +#: ../../../docs/configuring-playbook.md:201 msgid "[Setting up Mjolnir](configuring-playbook-bot-mjolnir.md) — a moderation tool/bot" msgstr "" -#: ../../../docs/configuring-playbook.md:188 +#: ../../../docs/configuring-playbook.md:203 msgid "[Setting up Draupnir](configuring-playbook-bot-draupnir.md) — a moderation tool/bot, forked from Mjolnir and maintained by its former leader developer" msgstr "" -#: ../../../docs/configuring-playbook.md:190 +#: ../../../docs/configuring-playbook.md:205 msgid "[Setting up Draupnir for all/D4A](configuring-playbook-appservice-draupnir-for-all.md) — like the [Draupnir bot](configuring-playbook-bot-draupnir.md) mentioned above, but running in appservice mode and supporting multiple instances" msgstr "" -#: ../../../docs/configuring-playbook.md:192 +#: ../../../docs/configuring-playbook.md:207 msgid "[Setting up Buscarron](configuring-playbook-bot-buscarron.md) — a bot you can use to send any form (HTTP POST, HTML) to a (encrypted) Matrix room" msgstr "" -#: ../../../docs/configuring-playbook.md:194 +#: ../../../docs/configuring-playbook.md:209 msgid "Administration" msgstr "" -#: ../../../docs/configuring-playbook.md:196 +#: ../../../docs/configuring-playbook.md:211 msgid "Services that help you in administrating and monitoring your Matrix installation." msgstr "" -#: ../../../docs/configuring-playbook.md:198 +#: ../../../docs/configuring-playbook.md:213 msgid "[Setting up Prometheus Alertmanager integration via matrix-alertmanager-receiver](configuring-playbook-alertmanager-receiver.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:200 +#: ../../../docs/configuring-playbook.md:215 msgid "[Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:202 -msgid "[Enabling metrics and graphs for NginX logs](configuring-playbook-prometheus-nginxlog.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:204 +#: ../../../docs/configuring-playbook.md:217 msgid "[Setting up the rageshake bug report server](configuring-playbook-rageshake.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:206 +#: ../../../docs/configuring-playbook.md:219 msgid "[Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:208 +#: ../../../docs/configuring-playbook.md:221 msgid "Backups:" msgstr "" -#: ../../../docs/configuring-playbook.md:209 +#: ../../../docs/configuring-playbook.md:222 msgid "[Setting up BorgBackup](configuring-playbook-backup-borg.md) — a full Matrix server backup solution, including the Postgres database" msgstr "" -#: ../../../docs/configuring-playbook.md:211 -msgid "[Setting up postgres backup](configuring-playbook-postgres-backup.md) — a Postgres-database backup solution (note: does not include other files)" +#: ../../../docs/configuring-playbook.md:224 +msgid "[Setting up Postgres backup](configuring-playbook-postgres-backup.md) — a Postgres-database backup solution (note: does not include other files)" msgstr "" -#: ../../../docs/configuring-playbook.md:213 +#: ../../../docs/configuring-playbook.md:226 msgid "Other specialized services" msgstr "" -#: ../../../docs/configuring-playbook.md:215 +#: ../../../docs/configuring-playbook.md:228 msgid "Various services that don't fit any other categories." msgstr "" -#: ../../../docs/configuring-playbook.md:217 -msgid "[Setting up Synapse Auto Invite Accept](configuring-playbook-synapse-auto-accept-invite.md)" +#: ../../../docs/configuring-playbook.md:230 +msgid "[Setting up Element Call](configuring-playbook-element-call.md) — a native Matrix video conferencing application, built on top of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" msgstr "" -#: ../../../docs/configuring-playbook.md:219 +#: ../../../docs/configuring-playbook.md:232 +msgid "[Setting up LiveKit JWT Service](configuring-playbook-livekit-jwt-service.md) - a component of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:234 +msgid "[Setting up LiveKit Server](configuring-playbook-livekit-server.md) - a component of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:236 +msgid "[Setting up Matrix RTC](configuring-playbook-matrix-rtc.md) (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:238 msgid "[Setting up synapse-auto-compressor](configuring-playbook-synapse-auto-compressor.md) for compressing the database on Synapse homeservers" msgstr "" -#: ../../../docs/configuring-playbook.md:221 +#: ../../../docs/configuring-playbook.md:240 msgid "[Setting up Matrix Corporal](configuring-playbook-matrix-corporal.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:223 +#: ../../../docs/configuring-playbook.md:242 +msgid "[Setting up Matrix.to](configuring-playbook-matrixto.md)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:244 msgid "[Setting up Etherpad](configuring-playbook-etherpad.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:225 +#: ../../../docs/configuring-playbook.md:246 msgid "[Setting up the Jitsi video-conferencing platform](configuring-playbook-jitsi.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:227 +#: ../../../docs/configuring-playbook.md:248 msgid "[Setting up Cactus Comments](configuring-playbook-cactus-comments.md) — a federated comment system built on Matrix" msgstr "" -#: ../../../docs/configuring-playbook.md:229 +#: ../../../docs/configuring-playbook.md:250 msgid "[Setting up Pantalaimon (E2EE aware proxy daemon)](configuring-playbook-pantalaimon.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:231 +#: ../../../docs/configuring-playbook.md:252 msgid "[Setting up the Sygnal push gateway](configuring-playbook-sygnal.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:233 +#: ../../../docs/configuring-playbook.md:254 msgid "[Setting up the ntfy push notifications server](configuring-playbook-ntfy.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:235 +#: ../../../docs/configuring-playbook.md:256 msgid "Deprecated / unmaintained / removed services" msgstr "" -#: ../../../docs/configuring-playbook.md:237 +#: ../../../docs/configuring-playbook.md:258 msgid "**Note**: since a deprecated or unmaintained service will not be updated, its bug or vulnerability will be unlikely to get patched. It is recommended to migrate from the service to an alternative if any, and make sure to do your own research before you decide to keep it running nonetheless." msgstr "" -#: ../../../docs/configuring-playbook.md:239 +#: ../../../docs/configuring-playbook.md:260 +msgid "[Configuring conduwuit](configuring-playbook-conduwuit.md) (removed; this component has been abandoned and unmaintained)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:262 msgid "[Setting up the Sliding Sync proxy](configuring-playbook-sliding-sync-proxy.md) for clients which require Sliding Sync support (like old Element X versions, before it got switched to Simplified Sliding Sync)" msgstr "" -#: ../../../docs/configuring-playbook.md:241 -msgid "[Setting up Appservice Webhooks bridging](configuring-playbook-bridge-appservice-webhooks.md) (deprecated; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be installed using [this playbook](configuring-playbook-bridge-hookshot.md))" +#: ../../../docs/configuring-playbook.md:264 +msgid "[Setting up Appservice Slack bridging](configuring-playbook-bridge-appservice-slack.md) (removed; this component has been discontinued)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:266 +msgid "[Setting up Appservice Webhooks bridging](configuring-playbook-bridge-appservice-webhooks.md) (deprecated; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:243 +#: ../../../docs/configuring-playbook.md:268 msgid "[Setting up the Dimension integration manager](configuring-playbook-dimension.md) ([unmaintained](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2806#issuecomment-1673559299); after [installing](installing.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:245 -msgid "[Setting up Email2Matrix](configuring-playbook-email2matrix.md) (unmaintained; the author suggests taking a look at [Postmoogle](https://github.com/etkecc/postmoogle) as a replacement, which can also be installed using [this playbook](configuring-playbook-bridge-postmoogle.md))" +#: ../../../docs/configuring-playbook.md:270 +msgid "[Setting up Email2Matrix](configuring-playbook-email2matrix.md) (removed; the author suggests taking a look at [Postmoogle](https://github.com/etkecc/postmoogle) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-postmoogle.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:247 -msgid "[Setting up Go-NEB](configuring-playbook-bot-go-neb.md) (unmaintained; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be installed using [this playbook](configuring-playbook-bridge-hookshot.md))" +#: ../../../docs/configuring-playbook.md:272 +msgid "[Setting up Go-NEB](configuring-playbook-bot-go-neb.md) (unmaintained; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:249 -msgid "[Setting up matrix-bot-chatgpt](configuring-playbook-bot-chatgpt.md) (unmaintained; the bridge's author suggests taking a look at [baibot](https://github.com/etkecc/baibot) as a replacement, which can also be installed using [this playbook](configuring-playbook-bot-baibot.md))" +#: ../../../docs/configuring-playbook.md:274 +msgid "[Setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md) (removed; Skype has been discontinued since May 2025)" msgstr "" -#: ../../../docs/configuring-playbook.md:251 -msgid "[Setting up Mautrix Facebook bridging](configuring-playbook-bridge-mautrix-facebook.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-messenger](configuring-playbook-bridge-mautrix-meta-messenger.md))" +#: ../../../docs/configuring-playbook.md:276 +msgid "[Setting up ma1sd Identity Server](configuring-playbook-ma1sd.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook.)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:278 +msgid "[Setting up matrix-bot-chatgpt](configuring-playbook-bot-chatgpt.md) (unmaintained; the bridge's author suggests taking a look at [baibot](https://github.com/etkecc/baibot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bot-baibot.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:253 -msgid "[Setting up Mautrix Hangouts bridging](configuring-playbook-bridge-mautrix-hangouts.md) (deprecated in favor of the Google Chat bridge with [mautrix-googlechat](configuring-playbook-bridge-mautrix-googlechat.md))" +#: ../../../docs/configuring-playbook.md:280 +msgid "[Setting up Mautrix Facebook bridging](configuring-playbook-bridge-mautrix-facebook.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-messenger](configuring-playbook-bridge-mautrix-meta-messenger.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:255 +#: ../../../docs/configuring-playbook.md:282 msgid "[Setting up Mautrix Instagram bridging](configuring-playbook-bridge-mautrix-instagram.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-instagram](configuring-playbook-bridge-mautrix-meta-instagram.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:257 +#: ../../../docs/configuring-playbook.md:284 +msgid "[Setting up MX Puppet Discord bridging](configuring-playbook-bridge-mx-puppet-discord.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Discord bridging](configuring-playbook-bridge-mautrix-discord.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:286 +msgid "[Setting up MX Puppet Instagram bridging](configuring-playbook-bridge-mx-puppet-instagram.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Instagram bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-instagram.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:288 msgid "[Setting up MX Puppet Skype bridging](configuring-playbook-bridge-mx-puppet-skype.md) (removed; this component has been broken for a long time, so it has been removed from the playbook. Consider [setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md))" msgstr "" + +#: ../../../docs/configuring-playbook.md:290 +msgid "[Setting up MX Puppet Slack bridging](configuring-playbook-bridge-mx-puppet-slack.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Slack bridging](configuring-playbook-bridge-mautrix-slack.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:292 +msgid "[Setting up MX Puppet Twitter bridging](configuring-playbook-bridge-mx-puppet-twitter.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Twitter bridging](configuring-playbook-bridge-mautrix-twitter.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:294 +msgid "[Setting up Synapse Auto Invite Accept](configuring-playbook-synapse-auto-accept-invite.md) (removed; since Synapse [v1.109.0](https://github.com/element-hq/synapse/releases/tag/v1.109.0) the same feature is available natively.)" +msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/container-images.po b/i18n/locales/bg/LC_MESSAGES/docs/container-images.po index e4e665f10..e25bc0a8b 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/container-images.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/container-images.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,21 +19,21 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/container-images.md:1 +#: ../../../docs/container-images.md:18 msgid "Container images used by the playbook" msgstr "" -#: ../../../docs/container-images.md:3 +#: ../../../docs/container-images.md:20 msgid "This page summarizes the container ([Docker](https://www.docker.com/)) images used by the playbook when setting up your server." msgstr "" -#: ../../../docs/container-images.md:5 +#: ../../../docs/container-images.md:22 msgid "We try to stick to official images (provided by their respective projects) as much as possible." msgstr "" -#: ../../../docs/container-images.md:7 +#: ../../../docs/container-images.md:24 msgid "Homeserver" msgstr "" @@ -86,15 +86,15 @@ msgid "Storing your data and managing your presence in the [Matrix](http://matri msgstr "" #: ../../../docs/container-images.md -msgid "[conduwuit](configuring-playbook-conduwuit.md)" +msgid "[continuwuity](configuring-playbook-continuwuity.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[girlbossceo/conduwuit](https://ghcr.io/girlbossceo/conduwuit)" +msgid "[continuwuation/continuwuity](https://forgejo.ellis.link/continuwuation/continuwuity)" msgstr "" #: ../../../docs/container-images.md -msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. conduwuit is a fork of Conduit." +msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. continuwuity is a continuation of conduwuit." msgstr "" #: ../../../docs/container-images.md @@ -109,11 +109,11 @@ msgstr "" msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Dendrite is a second-generation Matrix homeserver written in Go, an alternative to Synapse." msgstr "" -#: ../../../docs/container-images.md:16 +#: ../../../docs/container-images.md:33 msgid "Clients" msgstr "" -#: ../../../docs/container-images.md:18 +#: ../../../docs/container-images.md:35 msgid "Web clients for Matrix that you can host on your own domains." msgstr "" @@ -153,6 +153,14 @@ msgstr "" msgid "Simple, elegant and secure web client" msgstr "" +#: ../../../docs/container-images.md +msgid "[Sable](configuring-playbook-client-sable.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[7w1/sable](https://ghcr.io/7w1/sable)" +msgstr "" + #: ../../../docs/container-images.md msgid "[SchildiChat Web](configuring-playbook-client-schildichat-web.md)" msgstr "" @@ -165,11 +173,11 @@ msgstr "" msgid "Based on Element Web, with a more traditional instant messaging experience" msgstr "" -#: ../../../docs/container-images.md:27 +#: ../../../docs/container-images.md:45 msgid "Server Components" msgstr "" -#: ../../../docs/container-images.md:29 +#: ../../../docs/container-images.md:47 msgid "Services that run on the server to make the various parts of your installation work." msgstr "" @@ -206,7 +214,7 @@ msgid "[Traefik](https://hub.docker.com/_/traefik/)" msgstr "" #: ../../../docs/container-images.md -msgid "Web server, listening on ports 80, 443 and 8448 — standing in front of all the other services. Using your own webserver [is possible](configuring-playbook-own-webserver.md)" +msgid "Web server, listening on ports 80, 443 and 8448 — standing in front of all the other services. [Using your own webserver](configuring-playbook-own-webserver.md) is also possible." msgstr "" #: ../../../docs/container-images.md @@ -218,7 +226,7 @@ msgid "[certbot/certbot](https://hub.docker.com/r/certbot/certbot/)" msgstr "" #: ../../../docs/container-images.md -msgid "The [certbot](https://certbot.eff.org/) tool for obtaining SSL certificates from [Let's Encrypt](https://letsencrypt.org/)" +msgid "[Certbot](https://certbot.eff.org/) tool for obtaining SSL certificates from [Let's Encrypt](https://letsencrypt.org/)" msgstr "" #: ../../../docs/container-images.md @@ -234,34 +242,46 @@ msgid "Mail server, through which all Matrix services send outgoing email (can b msgstr "" #: ../../../docs/container-images.md -msgid "[ma1sd](configuring-playbook-ma1sd.md)" +msgid "[ddclient](configuring-playbook-dynamic-dns.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[ma1uta/ma1sd](https://hub.docker.com/r/ma1uta/ma1sd/)" +msgid "[linuxserver/ddclient](https://hub.docker.com/r/linuxserver/ddclient)" msgstr "" #: ../../../docs/container-images.md -msgid "Matrix Identity Server" +msgid "Update dynamic DNS entries for accounts on Dynamic DNS Network Service Provider" msgstr "" #: ../../../docs/container-images.md -msgid "[ddclient](configuring-playbook-dynamic-dns.md)" +msgid "[LiveKit Server](configuring-playbook-livekit-server.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[linuxserver/ddclient](https://hub.docker.com/r/linuxserver/ddclient)" +msgid "[livekit/livekit-server](https://hub.docker.com/r/livekit/livekit-server/)" msgstr "" #: ../../../docs/container-images.md -msgid "Update dynamic DNS entries for accounts on Dynamic DNS Network Service Provider" +msgid "WebRTC server for audio/video calls" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[Livekit JWT Service](configuring-playbook-livekit-jwt-service.md)" msgstr "" -#: ../../../docs/container-images.md:41 +#: ../../../docs/container-images.md +msgid "[element-hq/lk-jwt-service](https://ghcr.io/element-hq/lk-jwt-service)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "JWT service for integrating [Element Call](./configuring-playbook-element-call.md) with [LiveKit Server](./configuring-playbook-livekit-server.md)" +msgstr "" + +#: ../../../docs/container-images.md:60 msgid "Authentication" msgstr "" -#: ../../../docs/container-images.md:43 +#: ../../../docs/container-images.md:62 msgid "Extend and modify how users are authenticated on your homeserver." msgstr "" @@ -302,7 +322,7 @@ msgid "[activism.international/matrix_ldap_registration_proxy](https://gitlab.co msgstr "" #: ../../../docs/container-images.md -msgid "A proxy that handles Matrix registration requests and forwards them to LDAP." +msgid "Proxy that handles Matrix registration requests and forwards them to LDAP" msgstr "" #: ../../../docs/container-images.md @@ -314,11 +334,11 @@ msgid "[zeratax/matrix-registration](https://hub.docker.com/r/devture/zeratax-ma msgstr "" #: ../../../docs/container-images.md -msgid "A simple python application to have a token based Matrix registration" +msgid "Simple python application to have a token based Matrix registration" msgstr "" #: ../../../docs/container-images.md -msgid "[Matrix User Verification Service](configuring-playbook-user-verification-service.md) (UVS)" +msgid "[Matrix User Verification Service](configuring-playbook-user-verification-service.md)" msgstr "" #: ../../../docs/container-images.md @@ -334,14 +354,14 @@ msgid "[synapse-simple-antispam](configuring-playbook-synapse-simple-antispam.md msgstr "" #: ../../../docs/container-images.md -msgid "A spam checker module" +msgid "Spam checker module" msgstr "" -#: ../../../docs/container-images.md:55 +#: ../../../docs/container-images.md:74 msgid "File Storage" msgstr "" -#: ../../../docs/container-images.md:57 +#: ../../../docs/container-images.md:76 msgid "Use alternative file storage to the default `media_store` folder." msgstr "" @@ -370,17 +390,29 @@ msgid "[t2bot/matrix-media-repo](https://ghcr.io/t2bot/matrix-media-repo)" msgstr "" #: ../../../docs/container-images.md -msgid "matrix-media-repo is a highly customizable multi-domain media repository for Matrix. Intended for medium to large deployments, this media repo de-duplicates media while being fully compliant with the specification." +msgid "Highly customizable multi-domain media repository for Matrix. Intended for medium to large deployments, this media repo de-duplicates media while being fully compliant with the specification." msgstr "" -#: ../../../docs/container-images.md:65 +#: ../../../docs/container-images.md:84 msgid "Bridges" msgstr "" -#: ../../../docs/container-images.md:67 +#: ../../../docs/container-images.md:86 msgid "Bridges can be used to connect your Matrix installation with third-party communication networks." msgstr "" +#: ../../../docs/container-images.md +msgid "[mautrix-bluesky](configuring-playbook-bridge-mautrix-bluesky.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[mautrix/bluesky](https://mau.dev/mautrix/bluesky/container_registry)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Bridge to [Bluesky](https://bsky.social/about)" +msgstr "" + #: ../../../docs/container-images.md msgid "[mautrix-discord](configuring-playbook-bridge-mautrix-discord.md)" msgstr "" @@ -549,14 +581,6 @@ msgstr "" msgid "Bridge to [Discord](https://discordapp.com/)" msgstr "" -#: ../../../docs/container-images.md -msgid "[matrix-appservice-slack](configuring-playbook-bridge-appservice-slack.md)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[matrixdotorg/matrix-appservice-slack](https://hub.docker.com/r/matrixdotorg/matrix-appservice-slack)" -msgstr "" - #: ../../../docs/container-images.md msgid "[matrix-hookshot](configuring-playbook-bridge-hookshot.md)" msgstr "" @@ -606,71 +630,27 @@ msgid "Bouncer-style bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_C msgstr "" #: ../../../docs/container-images.md -msgid "[go-skype-bridge](configuring-playbook-bridge-go-skype-bridge.md)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[nodefyme/go-skype-bridge](https://hub.docker.com/r/nodefyme/go-skype-bridge)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "Bridge to [Skype](https://www.skype.com)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[mx-puppet-slack](configuring-playbook-bridge-mx-puppet-slack.md)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[mx-puppet/slack/mx-puppet-slack](https://gitlab.com/mx-puppet/slack/mx-puppet-slack/container_registry)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "Bridge to [Slack](https://slack.com)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[mx-puppet-instagram](configuring-playbook-bridge-mx-puppet-instagram.md)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[sorunome/mx-puppet-instagram](https://hub.docker.com/r/sorunome/mx-puppet-instagram)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "Bridge for Instagram-DMs ([Instagram](https://www.instagram.com/))" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[mx-puppet-twitter](configuring-playbook-bridge-mx-puppet-twitter.md)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[sorunome/mx-puppet-twitter](https://hub.docker.com/r/sorunome/mx-puppet-twitter)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "Bridge for Twitter-DMs ([Twitter](https://twitter.com/))" +msgid "[mx-puppet-groupme](configuring-playbook-bridge-mx-puppet-groupme.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[mx-puppet-discord](configuring-playbook-bridge-mx-puppet-discord.md)" +msgid "[xangelix/mx-puppet-groupme](https://hub.docker.com/r/xangelix/mx-puppet-groupme)" msgstr "" #: ../../../docs/container-images.md -msgid "[mx-puppet/discord/mx-puppet-discord](https://gitlab.com/mx-puppet/discord/mx-puppet-discord/container_registry)" +msgid "Bridge to [GroupMe](https://groupme.com/)" msgstr "" #: ../../../docs/container-images.md -msgid "[mx-puppet-groupme](configuring-playbook-bridge-mx-puppet-groupme.md)" +msgid "[matrix-steam-bridge](configuring-playbook-bridge-steam.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[xangelix/mx-puppet-groupme](https://hub.docker.com/r/xangelix/mx-puppet-groupme)" +msgid "[jasonlaguidice/matrix-steam-bridge](https://github.com/jasonlaguidice/matrix-steam-bridge/pkgs/container/matrix-steam-bridge)" msgstr "" #: ../../../docs/container-images.md -msgid "Bridge to [GroupMe](https://groupme.com/)" +msgid "Bridge to [Steam](https://steampowered.com/)" msgstr "" #: ../../../docs/container-images.md @@ -697,11 +677,11 @@ msgstr "" msgid "Email to Matrix bridge" msgstr "" -#: ../../../docs/container-images.md:99 +#: ../../../docs/container-images.md:114 msgid "Bots" msgstr "" -#: ../../../docs/container-images.md:101 +#: ../../../docs/container-images.md:116 msgid "Bots provide various additional functionality to your installation." msgstr "" @@ -714,7 +694,7 @@ msgid "[etke.cc/baibot](https://ghcr.io/etkecc/baibot)" msgstr "" #: ../../../docs/container-images.md -msgid "A bot that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you" +msgid "Bot that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you" msgstr "" #: ../../../docs/container-images.md @@ -750,7 +730,7 @@ msgid "[dock.mau.dev/maubot/maubot](https://mau.dev/maubot/maubot/container_regi msgstr "" #: ../../../docs/container-images.md -msgid "A plugin-based Matrix bot system" +msgid "Plugin-based Matrix bot system" msgstr "" #: ../../../docs/container-images.md @@ -762,7 +742,7 @@ msgid "[etke.cc/honoroit](https://github.com/etkecc/honoroit/container_registry) msgstr "" #: ../../../docs/container-images.md -msgid "A helpdesk bot" +msgid "Helpdesk bot" msgstr "" #: ../../../docs/container-images.md @@ -774,7 +754,7 @@ msgid "[matrixdotorg/mjolnir](https://hub.docker.com/r/matrixdotorg/mjolnir)" msgstr "" #: ../../../docs/container-images.md -msgid "A moderation tool for Matrix" +msgid "Moderation tool for Matrix" msgstr "" #: ../../../docs/container-images.md @@ -786,7 +766,7 @@ msgid "[gnuxie/draupnir](https://hub.docker.com/r/gnuxie/draupnir)" msgstr "" #: ../../../docs/container-images.md -msgid "A moderation tool for Matrix (Fork of Mjolnir)" +msgid "Moderation tool for Matrix (Fork of Mjolnir)" msgstr "" #: ../../../docs/container-images.md @@ -801,11 +781,11 @@ msgstr "" msgid "Web forms (HTTP POST) to Matrix" msgstr "" -#: ../../../docs/container-images.md:114 +#: ../../../docs/container-images.md:129 msgid "Administration" msgstr "" -#: ../../../docs/container-images.md:116 +#: ../../../docs/container-images.md:131 msgid "Services that help you in administrating and monitoring your Matrix installation." msgstr "" @@ -834,15 +814,15 @@ msgid "OAuth 2.0 and OpenID Provider server" msgstr "" #: ../../../docs/container-images.md -msgid "[synapse-admin](configuring-playbook-synapse-admin.md)" +msgid "[ketesa](configuring-playbook-ketesa.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[etke.cc/synapse-admin](https://ghcr.io/etkecc/synapse-admin)" +msgid "[etkecc/ketesa](https://ghcr.io/etkecc/ketesa)" msgstr "" #: ../../../docs/container-images.md -msgid "A web UI tool for administrating users and rooms on your Matrix server" +msgid "Fully-featured web UI for administrating your Matrix homeserver — users, rooms, media, sessions, and more" msgstr "" #: ../../../docs/container-images.md @@ -874,7 +854,7 @@ msgid "Graphing tool that works well with the above two images. Our playbook als msgstr "" #: ../../../docs/container-images.md -msgid "[Metrics and Graphs](configuring-playbook-prometheus-nginxlog.md)" +msgid "[Metrics and Graphs](configuring-playbook-prometheus-grafana.md#enable-metrics-and-graphs-for-nginx-logs-optional)" msgstr "" #: ../../../docs/container-images.md @@ -894,51 +874,43 @@ msgid "Backups" msgstr "" #: ../../../docs/container-images.md -msgid "[rageshake](configuring-playbook-rageshake.md)" +msgid "[postgres-backup-local](configuring-playbook-postgres-backup.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[matrix-org/rageshake](https://ghcr.io/matrix-org/rageshake)" +msgid "[prodrigestivill/postgres-backup-local](https://hub.docker.com/r/prodrigestivill/postgres-backup-local)" msgstr "" #: ../../../docs/container-images.md -msgid "Bug report server" +msgid "Create automatic database backups" msgstr "" #: ../../../docs/container-images.md -msgid "[synapse-usage-exporter](configuring-playbook-synapse-usage-exporter.md)" +msgid "[rageshake](configuring-playbook-rageshake.md)" msgstr "" #: ../../../docs/container-images.md -msgid "Export the usage statistics of a Synapse homeserver to be scraped by Prometheus." -msgstr "" - -#: ../../../docs/container-images.md:131 -msgid "Misc" -msgstr "" - -#: ../../../docs/container-images.md:133 -msgid "Various services that don't fit any other categories." +msgid "[matrix-org/rageshake](https://ghcr.io/matrix-org/rageshake)" msgstr "" #: ../../../docs/container-images.md -msgid "[sliding-sync](configuring-playbook-sliding-sync-proxy.md)" +msgid "Bug report server" msgstr "" #: ../../../docs/container-images.md -msgid "[matrix-org/sliding-sync](https://ghcr.io/matrix-org/sliding-sync)" +msgid "[synapse-usage-exporter](configuring-playbook-synapse-usage-exporter.md)" msgstr "" #: ../../../docs/container-images.md -msgid "Sliding Sync support for clients which require it (like old Element X versions, before it got switched to Simplified Sliding Sync)" +msgid "Export the usage statistics of a Synapse homeserver to be scraped by Prometheus." msgstr "" -#: ../../../docs/container-images.md -msgid "[synapse_auto_accept_invite](configuring-playbook-synapse-auto-accept-invite.md)" +#: ../../../docs/container-images.md:147 +msgid "Misc" msgstr "" -#: ../../../docs/container-images.md -msgid "A Synapse module to automatically accept invites." +#: ../../../docs/container-images.md:149 +msgid "Various services that don't fit any other categories." msgstr "" #: ../../../docs/container-images.md @@ -946,11 +918,11 @@ msgid "[synapse_auto_compressor](configuring-playbook-synapse-auto-compressor.md msgstr "" #: ../../../docs/container-images.md -msgid "[etke.cc/rust-synapse-compress-state](https://gitlab.com/etke.cc/rust-synapse-compress-state/container_registry)" +msgid "[mb-saces/rust-synapse-tools](https://gitlab.com/mb-saces/rust-synapse-tools/container_registry)" msgstr "" #: ../../../docs/container-images.md -msgid "A cli tool that automatically compresses `state_groups` database table in background." +msgid "Cli tool that automatically compresses Synapse's `state_groups` database table in background" msgstr "" #: ../../../docs/container-images.md @@ -974,7 +946,7 @@ msgid "[etherpad/etherpad](https://hub.docker.com/r/etherpad/etherpad/)" msgstr "" #: ../../../docs/container-images.md -msgid "An open source collaborative text editor" +msgid "Open source collaborative text editor" msgstr "" #: ../../../docs/container-images.md @@ -986,7 +958,7 @@ msgid "[jitsi/web](https://hub.docker.com/r/jitsi/web)" msgstr "" #: ../../../docs/container-images.md -msgid "the [Jitsi](https://jitsi.org/) web UI" +msgid "[Jitsi](https://jitsi.org/) web UI" msgstr "" #: ../../../docs/container-images.md @@ -994,7 +966,7 @@ msgid "[jitsi/jicofo](https://hub.docker.com/r/jitsi/jicofo)" msgstr "" #: ../../../docs/container-images.md -msgid "the [Jitsi](https://jitsi.org/) Focus component" +msgid "[Jitsi](https://jitsi.org/) Focus component" msgstr "" #: ../../../docs/container-images.md @@ -1002,7 +974,7 @@ msgid "[jitsi/prosody](https://hub.docker.com/r/jitsi/prosody)" msgstr "" #: ../../../docs/container-images.md -msgid "the [Jitsi](https://jitsi.org/) Prosody XMPP server component" +msgid "[Jitsi](https://jitsi.org/) Prosody XMPP server component" msgstr "" #: ../../../docs/container-images.md @@ -1010,7 +982,7 @@ msgid "[jitsi/jvb](https://hub.docker.com/r/jitsi/jvb)" msgstr "" #: ../../../docs/container-images.md -msgid "the [Jitsi](https://jitsi.org/) Video Bridge component" +msgid "[Jitsi](https://jitsi.org/) Video Bridge component" msgstr "" #: ../../../docs/container-images.md @@ -1022,7 +994,7 @@ msgid "[cactuscomments/cactus-appservice](https://hub.docker.com/r/cactuscomment msgstr "" #: ../../../docs/container-images.md -msgid "A federated comment system built on Matrix" +msgid "Federated comment system built on Matrix" msgstr "" #: ../../../docs/container-images.md @@ -1038,7 +1010,7 @@ msgid "[matrixdotorg/pantalaimon](https://hub.docker.com/r/matrixdotorg/pantalai msgstr "" #: ../../../docs/container-images.md -msgid "An E2EE aware proxy daemon" +msgid "E2EE aware proxy daemon" msgstr "" #: ../../../docs/container-images.md @@ -1065,24 +1037,36 @@ msgstr "" msgid "Self-hosted, UnifiedPush-compatible push notifications server" msgstr "" -#: ../../../docs/container-images.md:152 +#: ../../../docs/container-images.md +msgid "[Element Call](configuring-playbook-element-call.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[element-hq/element-call](https://ghcr.io/element-hq/element-call)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "A native Matrix video conferencing application" +msgstr "" + +#: ../../../docs/container-images.md:167 msgid "Container images of deprecated / unmaintained services" msgstr "" -#: ../../../docs/container-images.md:154 +#: ../../../docs/container-images.md:169 msgid "The list of the deprecated or unmaintained services is available [here](configuring-playbook.md#deprecated--unmaintained--removed-services)." msgstr "" #: ../../../docs/container-images.md -msgid "[matrix-appservice-webhooks](configuring-playbook-bridge-appservice-webhooks.md)" +msgid "[conduwuit](configuring-playbook-conduwuit.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[turt2live/matrix-appservice-webhooks](https://hub.docker.com/r/turt2live/matrix-appservice-webhooks)" +msgid "[girlbossceo/conduwuit](https://ghcr.io/girlbossceo/conduwuit)" msgstr "" #: ../../../docs/container-images.md -msgid "Bridge for slack compatible webhooks ([ConcourseCI](https://concourse-ci.org/), [Slack](https://slack.com/) etc. pp.)" +msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. conduwuit was a fork of Conduit." msgstr "" #: ../../../docs/container-images.md @@ -1094,7 +1078,7 @@ msgid "[turt2live/matrix-dimension](https://hub.docker.com/r/turt2live/matrix-di msgstr "" #: ../../../docs/container-images.md -msgid "An open source integration manager for Matrix clients" +msgid "Open source integration manager for Matrix clients" msgstr "" #: ../../../docs/container-images.md @@ -1118,7 +1102,39 @@ msgid "[matrixdotorg/go-neb](https://hub.docker.com/r/matrixdotorg/go-neb)" msgstr "" #: ../../../docs/container-images.md -msgid "A multi functional bot written in Go" +msgid "Multi functional bot written in Go" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[ma1sd](configuring-playbook-ma1sd.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[ma1uta/ma1sd](https://hub.docker.com/r/ma1uta/ma1sd/)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Matrix Identity Server" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[matrix-appservice-slack](configuring-playbook-bridge-appservice-slack.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[matrixdotorg/matrix-appservice-slack](https://hub.docker.com/r/matrixdotorg/matrix-appservice-slack)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[matrix-appservice-webhooks](configuring-playbook-bridge-appservice-webhooks.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[turt2live/matrix-appservice-webhooks](https://hub.docker.com/r/turt2live/matrix-appservice-webhooks)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Bridge for slack compatible webhooks ([ConcourseCI](https://concourse-ci.org/), [Slack](https://slack.com/) etc. pp.)" msgstr "" #: ../../../docs/container-images.md @@ -1146,25 +1162,77 @@ msgid "Bridge to [Facebook](https://facebook.com/)" msgstr "" #: ../../../docs/container-images.md -msgid "[mautrix-hangouts](configuring-playbook-bridge-mautrix-hangouts.md)" +msgid "[mautrix-instagram](configuring-playbook-bridge-mautrix-instagram.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[mautrix/hangouts](https://mau.dev/mautrix/hangouts/container_registry)" +msgid "[mautrix/instagram](https://mau.dev/mautrix/instagram/container_registry)" msgstr "" #: ../../../docs/container-images.md -msgid "Bridge to [Google Hangouts](https://en.wikipedia.org/wiki/Google_Hangouts)" +msgid "Bridge to [Instagram](https://instagram.com/)" msgstr "" #: ../../../docs/container-images.md -msgid "[mautrix-instagram](configuring-playbook-bridge-mautrix-instagram.md)" +msgid "[mx-puppet-discord](configuring-playbook-bridge-mx-puppet-discord.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[mautrix/instagram](https://mau.dev/mautrix/instagram/container_registry)" +msgid "[mx-puppet/discord/mx-puppet-discord](https://gitlab.com/mx-puppet/discord/mx-puppet-discord/container_registry)" msgstr "" #: ../../../docs/container-images.md -msgid "Bridge to [Instagram](https://instagram.com/)" +msgid "[mx-puppet-instagram](configuring-playbook-bridge-mx-puppet-instagram.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[sorunome/mx-puppet-instagram](https://hub.docker.com/r/sorunome/mx-puppet-instagram)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Bridge for Instagram-DMs ([Instagram](https://www.instagram.com/))" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[mx-puppet-slack](configuring-playbook-bridge-mx-puppet-slack.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[mx-puppet/slack/mx-puppet-slack](https://gitlab.com/mx-puppet/slack/mx-puppet-slack/container_registry)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Bridge to [Slack](https://slack.com)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[mx-puppet-twitter](configuring-playbook-bridge-mx-puppet-twitter.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[sorunome/mx-puppet-twitter](https://hub.docker.com/r/sorunome/mx-puppet-twitter)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Bridge for Twitter-DMs ([Twitter](https://twitter.com/))" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[sliding-sync](configuring-playbook-sliding-sync-proxy.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[matrix-org/sliding-sync](https://ghcr.io/matrix-org/sliding-sync)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Sliding Sync support for clients which require it (like old Element X versions, before it got switched to Simplified Sliding Sync)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[synapse_auto_accept_invite](configuring-playbook-synapse-auto-accept-invite.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Synapse module to automatically accept invites" msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/registering-users.po b/i18n/locales/bg/LC_MESSAGES/docs/registering-users.po index 6beb19bb6..dc8db7563 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/registering-users.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/registering-users.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,228 +19,225 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/registering-users.md:1 +#: ../../../docs/registering-users.md:11 msgid "Registering users" msgstr "" -#: ../../../docs/registering-users.md:3 +#: ../../../docs/registering-users.md:13 msgid "This documentation page tells you how to create user accounts on your Matrix server." msgstr "" -#: ../../../docs/registering-users.md:5 +#: ../../../docs/registering-users.md:15 msgid "Table of contents:" msgstr "" -#: ../../../docs/registering-users.md:7 +#: ../../../docs/registering-users.md:16 msgid "[Registering users](#registering-users)" msgstr "" -#: ../../../docs/registering-users.md:8 +#: ../../../docs/registering-users.md:17 msgid "[Registering users manually](#registering-users-manually)" msgstr "" -#: ../../../docs/registering-users.md:9 +#: ../../../docs/registering-users.md:18 msgid "[Managing users via a Web UI](#managing-users-via-a-web-ui)" msgstr "" -#: ../../../docs/registering-users.md:10 +#: ../../../docs/registering-users.md:19 msgid "[Letting certain users register on your private server](#letting-certain-users-register-on-your-private-server)" msgstr "" -#: ../../../docs/registering-users.md:11 +#: ../../../docs/registering-users.md:20 msgid "[Enabling public user registration](#enabling-public-user-registration)" msgstr "" -#: ../../../docs/registering-users.md:12 +#: ../../../docs/registering-users.md:21 msgid "[Adding/Removing Administrator privileges to an existing user](#addingremoving-administrator-privileges-to-an-existing-user)" msgstr "" -#: ../../../docs/registering-users.md:14 +#: ../../../docs/registering-users.md:23 msgid "Registering users manually" msgstr "" -#: ../../../docs/registering-users.md:16 ../../../docs/registering-users.md:121 +#: ../../../docs/registering-users.md:25 ../../../docs/registering-users.md:127 msgid "**Notes**:" msgstr "" -#: ../../../docs/registering-users.md:17 +#: ../../../docs/registering-users.md:26 msgid "Make sure to adjust `USERNAME_HERE` and `PASSWORD_HERE`" msgstr "" -#: ../../../docs/registering-users.md:18 +#: ../../../docs/registering-users.md:27 msgid "For `USERNAME_HERE`, use a plain username like `alice`, not a full ID (`@alice:example.com`)" msgstr "" -#: ../../../docs/registering-users.md:19 +#: ../../../docs/registering-users.md:28 msgid "Use `admin=yes` or `admin=no` depending on whether you wish to make the user an administrator of the Matrix server" msgstr "" -#: ../../../docs/registering-users.md:21 +#: ../../../docs/registering-users.md:30 msgid "After registering a user (using one of the methods below), **you can log in with that user** via the [Element Web](configuring-playbook-client-element-web.md) service that this playbook has installed for you at a URL like this: `https://element.example.com/`." msgstr "" -#: ../../../docs/registering-users.md:23 +#: ../../../docs/registering-users.md:32 msgid "Registering users via the Ansible playbook" msgstr "" -#: ../../../docs/registering-users.md:25 +#: ../../../docs/registering-users.md:34 msgid "It's best to register users via the Ansible playbook, because it works regardless of homeserver implementation (Synapse, Dendrite, etc) or usage of [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) (MAS)." msgstr "" -#: ../../../docs/registering-users.md:27 +#: ../../../docs/registering-users.md:36 msgid "To register a user via this Ansible playbook:" msgstr "" -#: ../../../docs/registering-users.md:35 +#: ../../../docs/registering-users.md:44 msgid "**or** by invoking `ansible-playbook` manually:" msgstr "" -#: ../../../docs/registering-users.md:43 +#: ../../../docs/registering-users.md:52 msgid "Feel free to register as many users (for friends, family, etc.) as you want. Still, perhaps you should grant full administrative access to your user account only (with `admin=yes`), and others should be created with `admin=no`." msgstr "" -#: ../../../docs/registering-users.md:45 +#: ../../../docs/registering-users.md:54 msgid "[!WARNING] If you're registering users against Matrix Authentication Service, do note that it [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user. Upon a user's first login, they will be asked to confirm their email address. This requires that email sending is [configured](./configuring-playbook-email.md). You can also consult the [Working around email deliverability issues](./configuring-playbook-matrix-authentication-service.md#working-around-email-deliverability-issues) section for more information." msgstr "" -#: ../../../docs/registering-users.md:48 +#: ../../../docs/registering-users.md:57 msgid "Registering users manually for Synapse" msgstr "" -#: ../../../docs/registering-users.md:50 +#: ../../../docs/registering-users.md:59 msgid "If you're using the [Synapse](configuring-playbook-synapse.md) homeserver implementation (which is the default), you can register users via the command-line after **SSH**-ing to your server (requires that [all services have been started](installing.md#install-matrix-server-and-services)):" msgstr "" -#: ../../../docs/registering-users.md:58 +#: ../../../docs/registering-users.md:67 msgid "Registering users manually for Dendrite" msgstr "" -#: ../../../docs/registering-users.md:60 +#: ../../../docs/registering-users.md:69 msgid "If you're using the [Dendrite](./configuring-playbook-dendrite.md) homeserver implementation, you can register users via the command-line after **SSH**-ing to your server (requires that [all services have been started](installing.md#install-matrix-server-and-services)):" msgstr "" -#: ../../../docs/registering-users.md:68 +#: ../../../docs/registering-users.md:77 msgid "Registering users manually for Matrix Authentication Service" msgstr "" -#: ../../../docs/registering-users.md:70 +#: ../../../docs/registering-users.md:79 msgid "If you're using the [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) and your existing homeserver (most likely [Synapse](./configuring-playbook-synapse.md)) is delegating authentication to it, you can register users via the command-line after **SSH**-ing to your server (requires that [all services have been started](installing.md#install-matrix-server-and-services)):" msgstr "" -#: ../../../docs/registering-users.md:78 +#: ../../../docs/registering-users.md:87 msgid "This `register-user` script actually invokes the `mas-cli manage register-user` command under the hood. If you'd like more control over the registration process, consider invoking the `mas-cli` command directly:" msgstr "" -#: ../../../docs/registering-users.md:84 +#: ../../../docs/registering-users.md:93 msgid "[!WARNING] Matrix Authentication Service [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user. Upon a user's first login, they will be asked to confirm their email address. This requires that email sending is [configured](./configuring-playbook-email.md). You can also consult the [Working around email deliverability issues](./configuring-playbook-matrix-authentication-service.md#working-around-email-deliverability-issues) section for more information." msgstr "" -#: ../../../docs/registering-users.md:87 +#: ../../../docs/registering-users.md:96 msgid "Managing users via a Web UI" msgstr "" -#: ../../../docs/registering-users.md:89 -msgid "To manage users more easily (via a web user-interace), you can install [Synapse Admin](configuring-playbook-synapse-admin.md)." -msgstr "" - -#: ../../../docs/registering-users.md:91 -msgid "[!WARNING] If you're using [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md), note that user management via synapse-admin is not fully working yet. See the [Expectations](configuring-playbook-matrix-authentication-service.md#expectations) section for more information." +#: ../../../docs/registering-users.md:98 +msgid "To manage users and your homeserver more easily (via a web interface), you can install [Ketesa](configuring-playbook-ketesa.md) — a fully-featured admin UI covering users, rooms, media, sessions, and MAS management." msgstr "" -#: ../../../docs/registering-users.md:94 +#: ../../../docs/registering-users.md:100 msgid "Letting certain users register on your private server" msgstr "" -#: ../../../docs/registering-users.md:96 +#: ../../../docs/registering-users.md:102 msgid "If you'd rather **keep your server private** (public registration closed, as is the default), and **let certain people create accounts by themselves** (instead of creating user accounts manually like this), consider installing and making use of [matrix-registration](configuring-playbook-matrix-registration.md)." msgstr "" -#: ../../../docs/registering-users.md:98 +#: ../../../docs/registering-users.md:104 msgid "Enabling public user registration" msgstr "" -#: ../../../docs/registering-users.md:100 +#: ../../../docs/registering-users.md:106 msgid "To **open up user registration publicly** (usually **not recommended**), add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/registering-users.md:102 +#: ../../../docs/registering-users.md:108 msgid "For Synapse:" msgstr "" -#: ../../../docs/registering-users.md:108 +#: ../../../docs/registering-users.md:114 msgid "For Dendrite:" msgstr "" -#: ../../../docs/registering-users.md:114 +#: ../../../docs/registering-users.md:120 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/registering-users.md:123 +#: ../../../docs/registering-users.md:129 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/registering-users.md:125 +#: ../../../docs/registering-users.md:131 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/registering-users.md:127 +#: ../../../docs/registering-users.md:133 msgid "If you're opening up registrations publicly like this, you might also wish to [configure CAPTCHA protection](configuring-captcha.md)." msgstr "" -#: ../../../docs/registering-users.md:129 +#: ../../../docs/registering-users.md:135 msgid "Adding/Removing Administrator privileges to an existing user" msgstr "" -#: ../../../docs/registering-users.md:131 +#: ../../../docs/registering-users.md:137 msgid "Adding/Removing Administrator privileges to an existing user in Synapse" msgstr "" -#: ../../../docs/registering-users.md:133 +#: ../../../docs/registering-users.md:139 msgid "To change the admin privileges for a user in Synapse's local database, you need to run an SQL query like this against the `synapse` database:" msgstr "" -#: ../../../docs/registering-users.md:139 +#: ../../../docs/registering-users.md:145 msgid "where:" msgstr "" -#: ../../../docs/registering-users.md:141 +#: ../../../docs/registering-users.md:147 msgid "`ADMIN_VALUE` being either `0` (regular user) or `1` (admin)" msgstr "" -#: ../../../docs/registering-users.md:142 +#: ../../../docs/registering-users.md:148 msgid "`USER` and `example.com` pointing to a valid user on your server" msgstr "" -#: ../../../docs/registering-users.md:144 +#: ../../../docs/registering-users.md:150 msgid "If you're using the integrated Postgres server and not an [external Postgres server](configuring-playbook-external-postgres.md), you can launch a Postgres into the `synapse` database by:" msgstr "" -#: ../../../docs/registering-users.md:146 +#: ../../../docs/registering-users.md:152 msgid "running `/matrix/postgres/bin/cli` — to launch [`psql`](https://www.postgresql.org/docs/current/app-psql.html)" msgstr "" -#: ../../../docs/registering-users.md:147 +#: ../../../docs/registering-users.md:153 msgid "running `\\c synapse` — to change to the `synapse` database" msgstr "" -#: ../../../docs/registering-users.md:149 +#: ../../../docs/registering-users.md:155 msgid "You can then proceed to run the query above." msgstr "" -#: ../../../docs/registering-users.md:151 +#: ../../../docs/registering-users.md:157 msgid "**Note**: directly modifying the raw data of Synapse (or any other software) could cause the software to break. You've been warned!" msgstr "" -#: ../../../docs/registering-users.md:153 +#: ../../../docs/registering-users.md:159 msgid "Adding/Removing Administrator privileges to an existing user in Matrix Authentication Service" msgstr "" -#: ../../../docs/registering-users.md:155 -msgid "Promoting/demoting a user in Matrix Authentication Service cannot currently (2024-10-19) be done via the [`mas-cli` Management tool](./configuring-playbook-matrix-authentication-service.md#management)." +#: ../../../docs/registering-users.md:161 +msgid "Promoting/demoting a user in Matrix Authentication Service can be done using the [`mas-cli`](./configuring-playbook-matrix-authentication-service.md#management) management tool's [`manage promote-admin`](https://element-hq.github.io/matrix-authentication-service/reference/cli/manage.html#manage-promote-admin) and [`manage demote-admin`](https://element-hq.github.io/matrix-authentication-service/reference/cli/manage.html#manage-demote-admin) commands. For example: `/matrix/matrix-authentication-service/bin/mas-cli manage promote-admin some.username`." msgstr "" -#: ../../../docs/registering-users.md:157 -msgid "You can do it via the [MAS Admin API](https://element-hq.github.io/matrix-authentication-service/api/index.html)'s `POST /api/admin/v1/users/{id}/set-admin` endpoint." +#: ../../../docs/registering-users.md:163 +#, python-brace-format +msgid "You can also do it via the [MAS Admin API](https://element-hq.github.io/matrix-authentication-service/api/index.html)'s `POST /api/admin/v1/users/{id}/set-admin` endpoint." msgstr "" diff --git a/i18n/locales/bg/LC_MESSAGES/docs/self-building.po b/i18n/locales/bg/LC_MESSAGES/docs/self-building.po index 89bf5c0f5..987b82885 100644 --- a/i18n/locales/bg/LC_MESSAGES/docs/self-building.po +++ b/i18n/locales/bg/LC_MESSAGES/docs/self-building.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-16 12:05+0900\n" +"POT-Creation-Date: 2026-04-03 12:09+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: bg\n" @@ -19,160 +19,136 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/self-building.md:1 +#: ../../../docs/self-building.md:15 msgid "Self-building" msgstr "" -#: ../../../docs/self-building.md:3 +#: ../../../docs/self-building.md:17 msgid "**Caution: self-building does not have to be used on its own. See the [Alternative Architectures](alternative-architectures.md) page.**" msgstr "" -#: ../../../docs/self-building.md:5 +#: ../../../docs/self-building.md:19 msgid "The playbook supports self-building of various components, which don't have a container image for your architecture (see the [container images we use](container-images.md)). For `amd64`, self-building is not required." msgstr "" -#: ../../../docs/self-building.md:7 +#: ../../../docs/self-building.md:21 msgid "For other architectures (e.g. `arm32`, `arm64`), ready-made container images are used when available. If there's no ready-made image for a specific component and said component supports self-building, an image will be built on the host. Building images like this takes more time and resources (some build tools need to get installed by the playbook to assist building)." msgstr "" -#: ../../../docs/self-building.md:9 +#: ../../../docs/self-building.md:23 msgid "To make use of self-building, you don't need to do anything. If a component has an image for the specified architecture, the playbook will use it directly. If not, it will build the image on the server itself." msgstr "" -#: ../../../docs/self-building.md:11 +#: ../../../docs/self-building.md:25 msgid "Note that **not all components support self-building yet**." msgstr "" -#: ../../../docs/self-building.md:13 +#: ../../../docs/self-building.md:27 msgid "Possibly outdated list of roles where self-building the Docker image is currently possible:" msgstr "" -#: ../../../docs/self-building.md:14 +#: ../../../docs/self-building.md:28 msgid "`matrix-synapse`" msgstr "" -#: ../../../docs/self-building.md:15 -msgid "`matrix-synapse-admin`" +#: ../../../docs/self-building.md:29 +msgid "`matrix-ketesa`" msgstr "" -#: ../../../docs/self-building.md:16 +#: ../../../docs/self-building.md:30 msgid "`matrix-client-element`" msgstr "" -#: ../../../docs/self-building.md:17 -msgid "`matrix-client-hydrogen`" -msgstr "" - -#: ../../../docs/self-building.md:18 -msgid "`matrix-client-cinny`" +#: ../../../docs/self-building.md:31 +msgid "`hydrogen`" msgstr "" -#: ../../../docs/self-building.md:19 -msgid "`matrix-registration`" +#: ../../../docs/self-building.md:32 +msgid "`cinny`" msgstr "" -#: ../../../docs/self-building.md:20 -msgid "`matrix-coturn`" +#: ../../../docs/self-building.md:33 +msgid "`sable`" msgstr "" -#: ../../../docs/self-building.md:21 -msgid "`matrix-corporal`" +#: ../../../docs/self-building.md:34 +msgid "`matrix-registration`" msgstr "" -#: ../../../docs/self-building.md:22 -msgid "`matrix-dimension`" +#: ../../../docs/self-building.md:35 +msgid "`coturn`" msgstr "" -#: ../../../docs/self-building.md:23 -msgid "`matrix-ma1sd`" +#: ../../../docs/self-building.md:36 +msgid "`matrix-corporal`" msgstr "" -#: ../../../docs/self-building.md:24 +#: ../../../docs/self-building.md:37 msgid "`exim-relay`" msgstr "" -#: ../../../docs/self-building.md:25 +#: ../../../docs/self-building.md:38 msgid "`matrix-bridge-hookshot`" msgstr "" -#: ../../../docs/self-building.md:26 +#: ../../../docs/self-building.md:39 msgid "`matrix-bridge-appservice-irc`" msgstr "" -#: ../../../docs/self-building.md:27 -msgid "`matrix-bridge-appservice-slack`" -msgstr "" - -#: ../../../docs/self-building.md:28 -msgid "`matrix-bridge-appservice-webhooks`" -msgstr "" - -#: ../../../docs/self-building.md:29 +#: ../../../docs/self-building.md:40 msgid "`matrix-bridge-beeper-linkedin`" msgstr "" -#: ../../../docs/self-building.md:30 -msgid "`matrix-bridge-mautrix-facebook`" -msgstr "" - -#: ../../../docs/self-building.md:31 -msgid "`matrix-bridge-mautrix-hangouts`" -msgstr "" - -#: ../../../docs/self-building.md:32 +#: ../../../docs/self-building.md:41 msgid "`matrix-bridge-mautrix-googlechat`" msgstr "" -#: ../../../docs/self-building.md:33 +#: ../../../docs/self-building.md:42 msgid "`matrix-bridge-mautrix-telegram`" msgstr "" -#: ../../../docs/self-building.md:34 +#: ../../../docs/self-building.md:43 msgid "`matrix-bridge-mautrix-signal`" msgstr "" -#: ../../../docs/self-building.md:35 +#: ../../../docs/self-building.md:44 msgid "`matrix-bridge-mautrix-gmessages`" msgstr "" -#: ../../../docs/self-building.md:36 +#: ../../../docs/self-building.md:45 msgid "`matrix-bridge-mautrix-whatsapp`" msgstr "" -#: ../../../docs/self-building.md:37 +#: ../../../docs/self-building.md:46 msgid "`matrix-bridge-mx-puppet-steam`" msgstr "" -#: ../../../docs/self-building.md:38 +#: ../../../docs/self-building.md:47 msgid "`matrix-bot-mjolnir`" msgstr "" -#: ../../../docs/self-building.md:39 +#: ../../../docs/self-building.md:48 msgid "`matrix-bot-honoroit`" msgstr "" -#: ../../../docs/self-building.md:40 +#: ../../../docs/self-building.md:49 msgid "`matrix-bot-matrix-reminder-bot`" msgstr "" -#: ../../../docs/self-building.md:41 +#: ../../../docs/self-building.md:50 msgid "`matrix-bot-maubot`" msgstr "" -#: ../../../docs/self-building.md:42 -msgid "`matrix-email2matrix`" -msgstr "" - -#: ../../../docs/self-building.md:43 +#: ../../../docs/self-building.md:51 msgid "`matrix-pantalaimon`" msgstr "" -#: ../../../docs/self-building.md:45 +#: ../../../docs/self-building.md:53 msgid "Adding self-building support to other roles is welcome. Feel free to contribute!" msgstr "" -#: ../../../docs/self-building.md:47 +#: ../../../docs/self-building.md:55 msgid "If you'd like **to force self-building** even if an image is available for your architecture, look into the `matrix_*_self_build` variables provided by individual roles." msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/CHANGELOG.po b/i18n/locales/jp/LC_MESSAGES/CHANGELOG.po index 331c474d9..9b0296d1a 100644 --- a/i18n/locales/jp/LC_MESSAGES/CHANGELOG.po +++ b/i18n/locales/jp/LC_MESSAGES/CHANGELOG.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,7052 +18,8207 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" #: ../../../CHANGELOG.md:1 +msgid "2026-04-03" +msgstr "" + +#: ../../../CHANGELOG.md:3 +msgid "(BC Break) Synapse Admin is now Ketesa" +msgstr "" + +#: ../../../CHANGELOG.md:5 +msgid "Synapse Admin has been rebranded to **[Ketesa](https://github.com/etkecc/ketesa)** — a landmark release that introduces a new identity, a full UI redesign, mobile-first layout, and deep Matrix Authentication Service (MAS) integration." +msgstr "" + +#: ../../../CHANGELOG.md:7 +msgid "Ketesa is a zero-configuration drop-in replacement for Synapse Admin: no server-side changes required, just update the role variables." +msgstr "" + +#: ../../../CHANGELOG.md:9 +msgid "The `matrix-synapse-admin` role has been **renamed** to `matrix-ketesa`. All `matrix_synapse_admin_*` variables must be **renamed** to `matrix_ketesa_*` in your `vars.yml`." +msgstr "" + +#: ../../../CHANGELOG.md:11 +msgid "Additionally, the **Docker image** changed from `ghcr.io/etkecc/synapse-admin` to `ghcr.io/etkecc/ketesa`. The default path prefix remains `/synapse-admin` for backward compatibility — updating to `/ketesa` is recommended but not required." +msgstr "" + +#: ../../../CHANGELOG.md:13 +msgid "The playbook will automatically detect leftover `matrix_synapse_admin_*` variables and fail with a helpful message listing what needs to be renamed." +msgstr "" + +#: ../../../CHANGELOG.md:15 +msgid "See the [Ketesa documentation](docs/configuring-playbook-ketesa.md) for details." +msgstr "" + +#: ../../../CHANGELOG.md:17 +msgid "2026-04-02" +msgstr "" + +#: ../../../CHANGELOG.md:19 +msgid "(BC Break) Draupnir for all Self Service Provisioning is now disabled by default" +msgstr "" + +#: ../../../CHANGELOG.md:21 +msgid "💡 If you don't use [Draupnir for all](./docs/configuring-playbook-appservice-draupnir-for-all.md), then this breaking change does not concern you.." +msgstr "" + +#: ../../../CHANGELOG.md:23 +msgid "[Draupnir for all](./docs/configuring-playbook-appservice-draupnir-for-all.md) now ships with `allowSelfServiceProvisioning: false` as default upstream and in this playbook." +msgstr "" + +#: ../../../CHANGELOG.md:25 +msgid "This means users can no longer provision Draupnir instances by inviting the appservice bot unless you explicitly opt in." +msgstr "" + +#: ../../../CHANGELOG.md:27 +msgid "Manual provisioning by administrators is now the recommended approach. You do not want to enable Self Service Provisioning unless you have additional custom safeguards like those used by asgard.chat in place." +msgstr "" + +#: ../../../CHANGELOG.md:29 +msgid "If you want to enable Self Service Provisioning, add the following to your `vars.yml`:" +msgstr "" + +#: ../../../CHANGELOG.md:36 +msgid "2026-03-23" +msgstr "" + +#: ../../../CHANGELOG.md:38 +msgid "Migration validation system introduced" +msgstr "" + +#: ../../../CHANGELOG.md:40 +msgid "Previously, when updating your setup, you had to remember to read the [CHANGELOG](CHANGELOG.md) file or risk breakage." +msgstr "" + +#: ../../../CHANGELOG.md:42 +msgid "Now, the playbook includes a migration validation system that ensures you're aware of breaking changes before they affect your deployment. You're now forced to acknowledge each breaking change, unless you wish to live dangerously (see below)." +msgstr "" + +#: ../../../CHANGELOG.md:45 +msgid "A new `matrix_playbook_migration_validated_version` variable has been introduced." +msgstr "" + +#: ../../../CHANGELOG.md:47 +msgid "**New users** who started from the [example `vars.yml`](examples/vars.yml) file already have this variable set and do not need to do anything." +msgstr "" + +#: ../../../CHANGELOG.md:49 +msgid "**Existing users** will need to add the following to their `vars.yml` file after reviewing all changelog entries up to now:" +msgstr "" + +#: ../../../CHANGELOG.md:55 +msgid "Going forward, whenever a breaking change is introduced the playbook will:" +msgstr "" + +#: ../../../CHANGELOG.md:57 +msgid "bump its expected version value (`matrix_playbook_migration_expected_version`), causing a discrepancy with what you validated (`matrix_playbook_migration_validated_version`)" +msgstr "" + +#: ../../../CHANGELOG.md:59 +msgid "fail when you run it with a helpful message listing what changed and linking to the relevant changelog entries" +msgstr "" + +#: ../../../CHANGELOG.md:61 +msgid "After reviewing and adapting your setup, you simply update the variable to the new version." +msgstr "" + +#: ../../../CHANGELOG.md:63 +msgid "If you'd like to live dangerously and skip these checks (not recommended), you can set this once and be done with it:" +msgstr "" + +#: ../../../CHANGELOG.md:69 +msgid "2026-03-19" +msgstr "" + +#: ../../../CHANGELOG.md:71 +msgid "Matrix Authentication Service now prefers UNIX sockets for playbook-managed Postgres" +msgstr "" + +#: ../../../CHANGELOG.md:73 +msgid "When [Matrix Authentication Service](docs/configuring-playbook-matrix-authentication-service.md) (MAS) uses the playbook-managed Postgres service, it now connects to it via a [UNIX socket](https://en.wikipedia.org/wiki/Unix_domain_socket) by default instead of TCP." +msgstr "" + +#: ../../../CHANGELOG.md:75 +msgid "This follows the same approach [applied to Synapse](#synapse-now-prefers-unix-sockets-for-playbook-managed-postgres-and-valkey) and reduces unnecessary container-network wiring, keeping local IPC off the network stack." +msgstr "" + +#: ../../../CHANGELOG.md:77 +msgid "If you use an external Postgres server for MAS, this does not change your setup." +msgstr "" + +#: ../../../CHANGELOG.md:79 ../../../CHANGELOG.md:95 +msgid "If you'd like to keep the previous TCP-based behavior, add the following configuration to your `vars.yml`:" +msgstr "" + +#: ../../../CHANGELOG.md:85 +msgid "2026-03-17" +msgstr "" + +#: ../../../CHANGELOG.md:87 +msgid "Synapse now prefers UNIX sockets for playbook-managed Postgres and Valkey" +msgstr "" + +#: ../../../CHANGELOG.md:89 +msgid "When Synapse uses the playbook-managed Postgres and Valkey services, it now connects to them via [UNIX sockets](https://en.wikipedia.org/wiki/Unix_domain_socket) by default instead of TCP." +msgstr "" + +#: ../../../CHANGELOG.md:91 +msgid "This reduces unnecessary container-network wiring and keeps local IPC off the network stack, which is a bit simpler and slightly more secure." +msgstr "" + +#: ../../../CHANGELOG.md:93 +msgid "If you use an external Postgres server or external Redis/Valkey for Synapse, this does not change your setup." +msgstr "" + +#: ../../../CHANGELOG.md:102 +msgid "2026-03-01" +msgstr "" + +#: ../../../CHANGELOG.md:104 +msgid "(Potential BC Break) Synapse S3 media prefix is now applied consistently" +msgstr "" + +#: ../../../CHANGELOG.md:106 +msgid "The `matrix_synapse_ext_synapse_s3_storage_provider_config_prefix` variable is now wired consistently for both:" +msgstr "" + +#: ../../../CHANGELOG.md:108 +msgid "the Synapse `s3_storage_provider` module configuration" +msgstr "" + +#: ../../../CHANGELOG.md:109 +msgid "the `matrix-synapse-s3-storage-provider-migrate` migration script (`s3_media_upload --prefix`)" +msgstr "" + +#: ../../../CHANGELOG.md:111 +msgid "Previously, this variable could be set, but was not effectively applied by either of these paths." +msgstr "" + +#: ../../../CHANGELOG.md:113 +msgid "**Affects**: users of [synapse-s3-storage-provider](docs/configuring-playbook-synapse-s3-storage-provider.md) who have configured a non-empty `matrix_synapse_ext_synapse_s3_storage_provider_config_prefix` value." +msgstr "" + +#: ../../../CHANGELOG.md:115 +msgid "If your bucket data was uploaded without the prefix before this fix, enabling proper prefix usage can make existing objects appear missing until data is migrated/copied to the prefixed key namespace." +msgstr "" + +#: ../../../CHANGELOG.md:117 +msgid "2026-02-26" +msgstr "" + +#: ../../../CHANGELOG.md:119 +msgid "Internal refactor: merged the Synapse reverse-proxy companion role into `matrix-synapse`" +msgstr "" + +#: ../../../CHANGELOG.md:121 +msgid "The standalone `matrix-synapse-reverse-proxy-companion` role has been merged into the [matrix-synapse](roles/custom/matrix-synapse/) role." +msgstr "" + +#: ../../../CHANGELOG.md:123 +msgid "This is not a user-facing change and does not change variable names (`matrix_synapse_reverse_proxy_companion_*` remain the same). The split looked clean on paper, but in practice both parts are tightly coupled through worker routing, tags (`setup-synapse`/`install-synapse`), and lifecycle ordering, so keeping them separate added coordination overhead with little practical benefit." +msgstr "" + +#: ../../../CHANGELOG.md:125 +msgid "Compatibility note: existing companion-specific tags (`setup-synapse-reverse-proxy-companion` and `install-synapse-reverse-proxy-companion`) are still available." +msgstr "" + +#: ../../../CHANGELOG.md:127 +msgid "With this change, Synapse and its reverse-proxy companion are managed in one role (`matrix-synapse`) while still keeping companion logic in dedicated task/template subdirectories for maintainability." +msgstr "" + +#: ../../../CHANGELOG.md:129 +msgid "2026-02-21" +msgstr "" + +#: ../../../CHANGELOG.md:131 +msgid "(BC Break) coturn is no longer auto-enabled by default" +msgstr "" + +#: ../../../CHANGELOG.md:133 +msgid "By default, the [coturn](./docs/configuring-playbook-turn.md) TURN server component is no longer enabled for every deployment." +msgstr "" + +#: ../../../CHANGELOG.md:135 +msgid "This reduces resources and attach surface for deployments which:" +msgstr "" + +#: ../../../CHANGELOG.md:137 +msgid "either don't need calls at all" +msgstr "" + +#: ../../../CHANGELOG.md:138 +msgid "or use the modern [Matrix RTC](docs/configuring-playbook-matrix-rtc.md)/[Element Call](docs/configuring-playbook-element-call.md) stack." +msgstr "" + +#: ../../../CHANGELOG.md:140 +msgid "Coturn is still auto-enabled when [Jitsi](./docs/configuring-playbook-jitsi.md) is enabled (`jitsi_enabled: true`), because Jitsi still depends on TURN for legacy Matrix integration." +msgstr "" + +#: ../../../CHANGELOG.md:142 +msgid "Additionally, Coturn (when enabled) now defaults to using automatic IP detection of your server's external IP address, instead of assuming your Ansible inventory (`ansible_host`) points to a public address and using it for configuring `coturn_turn_external_ip_address`." +msgstr "" + +#: ../../../CHANGELOG.md:144 +msgid "To restore the old behavior (needed for legacy call setups), add the following configuration to your `vars.yml`:" +msgstr "" + +#: ../../../CHANGELOG.md:153 +msgid "LiveKit TURN TLS is now automatically fronted by playbook-managed Traefik" +msgstr "" + +#: ../../../CHANGELOG.md:155 +msgid "For deployments that use the playbook-managed Traefik reverse-proxy, LiveKit TURN over TCP is now SSL-terminated at Traefik and passed as plain TCP to LiveKit (`turn.external_tls = true`) by default." +msgstr "" + +#: ../../../CHANGELOG.md:157 +msgid "To disable this behavior, set `livekit_server_config_turn_external_tls: false` and the playbook will revert to the old behavior - using traefik-certs-dumper to extract SSL certificates out of Traefik and pass them to LiveKit for explicit SSL termination there." +msgstr "" + +#: ../../../CHANGELOG.md:159 +msgid "If you are using `other-traefik-container` or [another reverse-proxy](./configuring-playbook-own-webserver.md), this change does **not** switch behavior automatically. That mode remains using certificate files in the container (Traefik certificates dumper flow) unless you explicitly set the TURN-Traefik mode variables to opt in." +msgstr "" + +#: ../../../CHANGELOG.md:161 +msgid "2026-02-17" +msgstr "" + +#: ../../../CHANGELOG.md:163 +msgid "(BC Break) prometheus-nginxlog-exporter role has been relocated and variable names need adjustments" +msgstr "" + +#: ../../../CHANGELOG.md:165 +msgid "The role for prometheus-nginxlog-exporter has been relocated to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." +msgstr "" + +#: ../../../CHANGELOG.md:167 +msgid "Along with the relocation, the `matrix_prometheus_nginxlog_exporter_` prefix on its variable names has been renamed to `prometheus_nginxlog_exporter_`, so you need to adjust your `vars.yml` configuration." +msgstr "" + +#: ../../../CHANGELOG.md:169 ../../../CHANGELOG.md:231 +#: ../../../CHANGELOG.md:241 ../../../CHANGELOG.md:302 +#: ../../../CHANGELOG.md:324 ../../../CHANGELOG.md:859 +msgid "As always, the playbook would let you know about this and point out any variables you may have missed." +msgstr "" + +#: ../../../CHANGELOG.md:171 +msgid "synapse-auto-invite-accept has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:173 +msgid "[synapse-auto-invite-accept](./docs/configuring-playbook-synapse-auto-accept-invite.md) has been removed from the playbook, as the same functionality [has been integrated](https://github.com/element-hq/synapse/pull/17147) to Synapse since [v1.109.0](https://github.com/element-hq/synapse/releases/tag/v1.109.0)." +msgstr "" + +#: ../../../CHANGELOG.md:175 +msgid "See [this section](./docs/configuring-playbook-synapse-auto-accept-invite.md#native-alternative) for details about how to enable the function on Synapse." +msgstr "" + +#: ../../../CHANGELOG.md:177 +msgid "If you're using any `matrix_synapse_ext_synapse_auto_accept_invite_*` variables, the playbook will let you know which one you'll need to remove from `vars.yml`." +msgstr "" + +#: ../../../CHANGELOG.md:179 +msgid "2026-02-16" +msgstr "" + +#: ../../../CHANGELOG.md:181 +msgid "matrix-appservice-slack has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:183 +msgid "[matrix-appservice-slack](./docs/configuring-playbook-bridge-appservice-slack.md) has been removed from the playbook, as it has been discontinued because the public Matrix.org Slack bridge has been decommissioned on January 14th, 2026." +msgstr "" + +#: ../../../CHANGELOG.md:185 +msgid "The playbook will let you know if you're using any `matrix_appservice_slack_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-bridge-appservice-slack.md#uninstalling-the-component-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:187 +msgid "**Note**: Bridging to [Slack](https://slack.com) can also happen via the [mautrix-slack](./docs/configuring-playbook-bridge-mautrix-slack.md) bridge supported by the playbook." +msgstr "" + +#: ../../../CHANGELOG.md:189 +msgid "2026-02-13" +msgstr "" + +#: ../../../CHANGELOG.md:191 +msgid "Conditional service restart for `install-*` commands" +msgstr "" + +#: ../../../CHANGELOG.md:193 +msgid "When running `install-all` or `install-service` (whether via `just` or raw `ansible-playbook`), only services whose configuration or container image actually changed during the playbook run will now be restarted. Unchanged services are left running (or get started if they were stopped). This reduces unnecessary downtime — particularly for services like Traefik (the reverse proxy), which previously caused brief connectivity interruptions on every playbook run even when nothing changed." +msgstr "" + +#: ../../../CHANGELOG.md:195 +msgid "When running with `setup-*` tags (e.g. `setup-all`, `setup-synapse`), all services continue to be unconditionally restarted as before." +msgstr "" + +#: ../../../CHANGELOG.md:197 +msgid "Currently, only Traefik tracks its own changes and benefits from conditional restart. All other services default to being restarted (the previous behavior). This is just the beginning — as more roles gain change-tracking support, playbook performance will improve and downtime will decrease dramatically, especially for `install-all` runs where most services haven't changed." +msgstr "" + +#: ../../../CHANGELOG.md:199 +msgid "Some benchmarks for `just install-service traefik` when Traefik settings did not change:" +msgstr "" + +#: ../../../CHANGELOG.md:201 +msgid "**Before**:" +msgstr "" + +#: ../../../CHANGELOG.md:202 +msgid "total time: ~56 seconds 🐌" +msgstr "" + +#: ../../../CHANGELOG.md:203 +msgid "Traefik restarted: yes (unnecessarily) ❌" +msgstr "" + +#: ../../../CHANGELOG.md:204 +msgid "dependent services restarted: yes, all of them ❌" +msgstr "" + +#: ../../../CHANGELOG.md:205 +msgid "**After**:" +msgstr "" + +#: ../../../CHANGELOG.md:206 +msgid "total time: ~27 seconds ⚡" +msgstr "" + +#: ../../../CHANGELOG.md:207 +msgid "Traefik restarted: no ✅" +msgstr "" + +#: ../../../CHANGELOG.md:208 +msgid "dependent services restarted: no ✅" +msgstr "" + +#: ../../../CHANGELOG.md:210 +msgid "This behavior can be overridden via `--extra-vars='devture_systemd_service_manager_conditional_restart_enabled=false'` to force unconditional restarts. See [Conditional service restart](docs/just.md#conditional-service-restart) for details." +msgstr "" + +#: ../../../CHANGELOG.md:213 +msgid "2026-02-12" +msgstr "" + +#: ../../../CHANGELOG.md:215 +msgid "Dimension integration manager has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:217 +msgid "The [Dimension integration manager](./docs/configuring-playbook-dimension.md) has been removed from the playbook, as it has been unmaintained." +msgstr "" + +#: ../../../CHANGELOG.md:219 +msgid "The playbook will let you know if you're using any `matrix_dimension_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-dimension.md#uninstalling-the-component-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:221 +msgid "(BC Break) Hydrogen role has been relocated and variable names need adjustments" +msgstr "" + +#: ../../../CHANGELOG.md:223 +msgid "The role for Hydrogen has been relocated to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." +msgstr "" + +#: ../../../CHANGELOG.md:225 +msgid "Along with the relocation, the `matrix_client_hydrogen_` prefix was dropped from its variable names, so you need to adjust your `vars.yml` configuration." +msgstr "" + +#: ../../../CHANGELOG.md:227 ../../../CHANGELOG.md:320 +msgid "You need to do the following replacement:" +msgstr "" + +#: ../../../CHANGELOG.md:229 +msgid "`matrix_client_hydrogen_` -> `hydrogen_`" +msgstr "" + +#: ../../../CHANGELOG.md:233 +msgid "2026-02-11" +msgstr "" + +#: ../../../CHANGELOG.md:235 +msgid "(BC Break) coturn role has been relocated and variable names need adjustments" +msgstr "" + +#: ../../../CHANGELOG.md:237 +msgid "The role for coturn has been relocated to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." +msgstr "" + +#: ../../../CHANGELOG.md:239 +msgid "Along with the relocation, the `matrix_coturn_` prefix on its variable names has been renamed to `coturn_`, so you need to adjust your `vars.yml` configuration." +msgstr "" + +#: ../../../CHANGELOG.md:243 +msgid "conduwuit has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:245 +msgid "[conduwuit](./docs/configuring-playbook-conduwuit.md) has been removed from the playbook, as it has been abandoned." +msgstr "" + +#: ../../../CHANGELOG.md:247 +msgid "The playbook will let you know if you're using any `matrix_conduwuit_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the service manually](./docs/configuring-playbook-conduwuit.md#uninstalling-the-service-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:249 +msgid "Since [Continuwuity](configuring-playbook-continuwuity.md) is a drop-in replacement for conduwuit, migration is possible. Please refer to [this section](./configuring-playbook-continuwuity.md#migrating-from-conduwuit) for details." +msgstr "" + +#: ../../../CHANGELOG.md:251 +msgid "2026-02-09" +msgstr "" + +#: ../../../CHANGELOG.md:253 +msgid "(BC Break) matrix-media-repo datastore IDs are now required in `vars.yml`" +msgstr "" + +#: ../../../CHANGELOG.md:255 +msgid "**Affects**: users with [matrix-media-repo](docs/configuring-playbook-matrix-media-repo.md) enabled (`matrix_media_repo_enabled: true`)" +msgstr "" + +#: ../../../CHANGELOG.md:257 +msgid "The `matrix_media_repo_datastore_file_id` and `matrix_media_repo_datastore_s3_id` variables are no longer auto-configured with values. They must now be explicitly defined in your `vars.yml` file. The playbook will fail with a helpful error if they are not set (when needed)." +msgstr "" + +#: ../../../CHANGELOG.md:259 +msgid "These were never meant to be auto-configured. They were derived from `matrix_homeserver_generic_secret_key`, which is intended for secrets that are OK to change subsequently (and Ansible would assist in propagating these changes). matrix-media-repo datastore IDs are not secrets — they are static identifiers linking media to storage backends, and **must not change** after first use." +msgstr "" + +#: ../../../CHANGELOG.md:261 +msgid "**For existing installations**, retrieve your current values from the server:" +msgstr "" + +#: ../../../CHANGELOG.md:267 +msgid "Then add to your `vars.yml`:" +msgstr "" + +#: ../../../CHANGELOG.md:276 +msgid "**Why do this?**: This change allows us to **remove the [passlib](https://passlib.readthedocs.io/en/stable/index.html) Python library** from the [prerequisites](docs/prerequisites.md), as it was the last component that depended on it." +msgstr "" + +#: ../../../CHANGELOG.md:278 +msgid "2026-02-08" +msgstr "" + +#: ../../../CHANGELOG.md:280 +msgid "Zulip bridge has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:282 +msgid "Zulip bridge has been removed from the playbook, as it doesn't work, and the maintainer seems to have abandoned it. See [this issue](https://github.com/GearKite/MatrixZulipBridge/issues/23) for more context." +msgstr "" + +#: ../../../CHANGELOG.md:284 +msgid "Switched to faster secret derivation for service passwords" +msgstr "" + +#: ../../../CHANGELOG.md:286 +msgid "We've switched the method used for deriving service passwords (database passwords, appservice tokens, etc.) from the `matrix_homeserver_generic_secret_key` variable." +msgstr "" + +#: ../../../CHANGELOG.md:288 +msgid "The old method used `password_hash('sha512', rounds=655555)` (655,555 rounds of SHA-512 hashing), which was designed for protecting low-entropy human passwords against brute-force attacks. For deriving secrets from an already high-entropy secret key, this many rounds provide no additional security - the secret key's entropy is what protects the derived passwords, not the computational cost of hashing." +msgstr "" + +#: ../../../CHANGELOG.md:290 +msgid "The new method uses a single-round `hash('sha512')` with a unique salt per service. This is equally secure for this use case (SHA-512 remains preimage-resistant; brute-forcing a high-entropy key is infeasible regardless of rounds), while being dramatically faster." +msgstr "" + +#: ../../../CHANGELOG.md:292 +msgid "On a fast mini PC, evaluating `postgres_managed_databases` (which references multiple database passwords) dropped from **~10.7 seconds to ~0.6 seconds**. The Postgres role evaluates this variable multiple times during a run, so the cumulative savings are significant. All other roles that reference derived passwords also benefit." +msgstr "" + +#: ../../../CHANGELOG.md:294 +msgid "**What this means for users**: all derived service passwords (database passwords, appservice tokens, etc.) will change on the next playbook run. The main/superuser database password (`postgres_connection_password`) is not affected, as it is hardcoded in inventory variables rather than derived via hashing. All services will receive their new passwords as part of the same run, so this should be a seamless, non-user-impacting change." +msgstr "" + +#: ../../../CHANGELOG.md:296 +msgid "(BC Break) Dynamic DNS role has been relocated and variable names need adjustments" +msgstr "" + +#: ../../../CHANGELOG.md:298 +msgid "The role for Dynamic DNS has been relocated to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." +msgstr "" + +#: ../../../CHANGELOG.md:300 +msgid "Along with the relocation, the `matrix_dynamic_dns_` prefix on its variable names has been renamed to `ddclient_`, so you need to adjust your `vars.yml` configuration." +msgstr "" + +#: ../../../CHANGELOG.md:304 +msgid "ma1sd has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:306 +msgid "[ma1sd](./docs/configuring-playbook-ma1sd.md) has been removed from the playbook, as it has been unmaintained for a long time." +msgstr "" + +#: ../../../CHANGELOG.md:308 +msgid "The playbook will let you know if you're using any `matrix_ma1sd_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-ma1sd.md#uninstalling-the-component-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:310 +msgid "Please note that some of the functions can be achieved with other components. For example, if you wish to implement LDAP integration, you might as well check out [the LDAP provider module for Synapse](./docs/configuring-playbook-ldap-auth.md) instead." +msgstr "" + +#: ../../../CHANGELOG.md:312 +msgid "2026-02-07" +msgstr "" + +#: ../../../CHANGELOG.md:314 +msgid "(BC Break) Cinny role has been relocated and variable names need adjustments" +msgstr "" + +#: ../../../CHANGELOG.md:316 +msgid "The role for Cinny has been relocated to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." +msgstr "" + +#: ../../../CHANGELOG.md:318 +msgid "Along with the relocation, the `matrix_client_cinny_` prefix was dropped from its variable names, so you need to adjust your `vars.yml` configuration." +msgstr "" + +#: ../../../CHANGELOG.md:322 +msgid "`matrix_client_cinny_` -> `cinny_`" +msgstr "" + +#: ../../../CHANGELOG.md:326 +msgid "The Sliding Sync proxy has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:328 +msgid "The [Sliding Sync proxy](./docs/configuring-playbook-sliding-sync-proxy.md) has been removed from the playbook, as it's been replaced with a different method (called Simplified Sliding Sync) integrated to newer homeservers by default (**Conduit** homeserver from version `0.6.0` or **Synapse** from version `1.114`)." +msgstr "" + +#: ../../../CHANGELOG.md:330 +msgid "The playbook will let you know if you're using any `matrix_sliding_sync_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the proxy manually](./docs/configuring-playbook-sliding-sync-proxy.md#uninstalling-the-proxy-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:332 +msgid "2026-02-04" +msgstr "" + +#: ../../../CHANGELOG.md:334 +msgid "baibot now supports OpenAI's built-in tools (Web Search and Code Interpreter)" +msgstr "" + +#: ../../../CHANGELOG.md:336 +#, python-format +msgid "**TLDR**: if you're using the [OpenAI provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openai) with [baibot](docs/configuring-playbook-bot-baibot.md), you can now enable [built-in tools](https://github.com/etkecc/baibot/blob/61d18b2/docs/features.md#%EF%B8%8F-built-in-tools-openai-only) (`web_search` and `code_interpreter`) to extend the model's capabilities." +msgstr "" + +#: ../../../CHANGELOG.md:338 +msgid "These tools are **disabled by default** and can be enabled via Ansible variables for static agent configurations:" +msgstr "" + +#: ../../../CHANGELOG.md:345 +msgid "Users who define agents dynamically at runtime will need to [update their agents](https://github.com/etkecc/baibot/blob/61d18b2/docs/agents.md#updating-agents) to enable these tools. See the [baibot v1.14.0 changelog](https://github.com/etkecc/baibot/blob/61d18b2/CHANGELOG.md) for details." +msgstr "" + +#: ../../../CHANGELOG.md:347 +msgid "Whoami-based sync worker routing for improved sticky sessions for Synapse" +msgstr "" + +#: ../../../CHANGELOG.md:349 +msgid "Deployments using [Synapse workers](./docs/configuring-playbook-synapse.md#load-balancing-with-workers) now benefit from improved sync worker routing via a new whoami-based mechanism (making use of the [whoami Matrix Client-Server API](https://spec.matrix.org/v1.17/client-server-api/#get_matrixclientv3accountwhoami))." +msgstr "" + +#: ../../../CHANGELOG.md:351 +msgid "Previously, sticky routing for sync workers relied on parsing usernames from access tokens, which only worked with native Synapse tokens (`syt__...`). This approach failed for [Matrix Authentication Service](docs/configuring-playbook-matrix-authentication-service.md) (MAS) deployments, where tokens are opaque and don't contain username information. This resulted in device-level stickiness (same token → same worker) rather than user-level stickiness (same user → same worker regardless of device), leading to suboptimal cache utilization on sync workers." +msgstr "" + +#: ../../../CHANGELOG.md:353 +msgid "The new implementation calls Synapse's `/whoami` endpoint to resolve access tokens to usernames, enabling proper user-level sticky routing regardless of the authentication system in use (native Synapse auth, MAS, etc.). Results are cached to minimize overhead." +msgstr "" + +#: ../../../CHANGELOG.md:355 +msgid "This change:" +msgstr "" + +#: ../../../CHANGELOG.md:356 +msgid "**Automatically enables** when sync workers are configured (no action required)" +msgstr "" + +#: ../../../CHANGELOG.md:357 +msgid "**Works universally** with any authentication system" +msgstr "" + +#: ../../../CHANGELOG.md:358 +msgid "**Replaces the old implementation** entirely to keep the codebase simple" +msgstr "" + +#: ../../../CHANGELOG.md:359 +msgid "**Adds minimal overhead** (one cached internal subrequest per sync request) for non-MAS deployments" +msgstr "" + +#: ../../../CHANGELOG.md:361 +msgid "For debugging, you can enable verbose logging and/or response headers showing routing decisions:" +msgstr "" + +#: ../../../CHANGELOG.md:372 +msgid "2025-12-09" +msgstr "" + +#: ../../../CHANGELOG.md:374 +msgid "Traefik Cert Dumper upgrade" +msgstr "" + +#: ../../../CHANGELOG.md:376 +msgid "The variable `traefik_certs_dumper_ssl_dir_path` was renamed to `traefik_certs_dumper_ssl_path`. Users who use [their own webserver with Traefik](docs/configuring-playbook-own-webserver.md) may need to adjust their configuration." +msgstr "" + +#: ../../../CHANGELOG.md:378 +msgid "The variable `traefik_certs_dumper_dumped_certificates_dir_path` was renamed to `traefik_certs_dumper_dumped_certificates_path`. Users who use [SRV Server Delegation](docs/howto-srv-server-delegation.md) may need to adjust their configuration." +msgstr "" + +#: ../../../CHANGELOG.md:380 +msgid "2025-11-23" +msgstr "" + +#: ../../../CHANGELOG.md:382 +msgid "Matrix.to support" +msgstr "" + +#: ../../../CHANGELOG.md:384 +msgid "The playbook now supports [Matrix.to](https://github.com/matrix-org/matrix.to) — a simple URL redirection service which powers [matrix.to](https://matrix.to)." +msgstr "" + +#: ../../../CHANGELOG.md:386 +msgid "To learn more, see our [Setting up Matrix.to](docs/configuring-playbook-matrixto.md) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:388 +msgid "2025-11-09" +msgstr "" + +#: ../../../CHANGELOG.md:390 +msgid "matrix-appservice-webhooks has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:392 +msgid "[matrix-appservice-webhooks](./docs/configuring-playbook-bridge-appservice-webhooks.md) has been removed from the playbook, as it has been deprecated since more than several years." +msgstr "" + +#: ../../../CHANGELOG.md:394 +msgid "The playbook will let you know if you're using any `matrix_appservice_webhooks_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the bridge manually](./docs/configuring-playbook-bridge-appservice-webhooks.md#uninstalling-the-bridge-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:396 +msgid "mautrix-facebook and mautrix-instagram have been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:398 +msgid "[mautrix-facebook](./docs/configuring-playbook-bridge-mautrix-facebook.md) and [mautrix-instagram](./docs/configuring-playbook-bridge-mautrix-instagram.md) have been removed from the playbook, as they have been deprecated in favor of the [mautrix-meta](https://github.com/mautrix/meta) Messenger/Instagram bridge, integrated to the playbook at [2024-02-19](#2024-02-19)." +msgstr "" + +#: ../../../CHANGELOG.md:400 ../../../CHANGELOG.md:432 +msgid "The playbook will let you know if you're using any variables for those bridges:" +msgstr "" + +#: ../../../CHANGELOG.md:402 +msgid "`matrix_mautrix_facebook_*`" +msgstr "" + +#: ../../../CHANGELOG.md:403 +msgid "`matrix_mautrix_instagram_*`" +msgstr "" + +#: ../../../CHANGELOG.md:405 ../../../CHANGELOG.md:439 +msgid "You'll need to remove them from `vars.yml` and potentially uninstall them manually. Consult pages below for details:" +msgstr "" + +#: ../../../CHANGELOG.md:407 +msgid "[Instruction for mautrix-facebook](./docs/configuring-playbook-bridge-mautrix-facebook.md#uninstalling-the-bridge-manually)" +msgstr "" + +#: ../../../CHANGELOG.md:408 +msgid "[Instruction for mautrix-instagram](./docs/configuring-playbook-bridge-mautrix-instagram.md#uninstalling-the-bridge-manually)" +msgstr "" + +#: ../../../CHANGELOG.md:410 +msgid "2025-11-08" +msgstr "" + +#: ../../../CHANGELOG.md:412 +msgid "MatrixZulipBridge support" +msgstr "" + +#: ../../../CHANGELOG.md:414 +msgid "Thanks to [Suguru Hirahara](https://github.com/luixxiul), the playbook now supports the [GearKite/MatrixZulipBridge](https://github.com/GearKite/MatrixZulipBridg) bridge for bridging Matrix to [Zulip](https://zulip.com/)." +msgstr "" + +#: ../../../CHANGELOG.md:416 +msgid "To learn more, see our [Setting up Zulip bridging](docs/configuring-playbook-bridge-zulip.md) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:418 +msgid "2025-11-07" +msgstr "" + +#: ../../../CHANGELOG.md:420 +msgid "The matrix-chatgpt-bot has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:422 +msgid "The [matrix-bot-chatgpt](./docs/configuring-playbook-bot-chatgpt.md) has been removed from the playbook, as it has been deprecated since September 2024." +msgstr "" + +#: ../../../CHANGELOG.md:424 +msgid "The playbook will let you know if you're using any `matrix_bot_chatgpt_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the bot manually](./docs/configuring-playbook-bot-chatgpt.md#uninstalling-matrix-chatgpt-bot-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:426 +msgid "2025-11-05" +msgstr "" + +#: ../../../CHANGELOG.md:428 +msgid "The MX Puppet bridges for Discord, Instagram, Slack, and Twitter have been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:430 +msgid "The MX Puppet bridges for Discord, Instagram, Slack, and Twitter have been removed from the playbook, as they have been unmaintained for more than several years and do not support important features like authenticated media. See [this issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3867) for the context." +msgstr "" + +#: ../../../CHANGELOG.md:434 +msgid "`matrix_mx_puppet_discord_*`" +msgstr "" + +#: ../../../CHANGELOG.md:435 +msgid "`matrix_mx_puppet_instagram_*`" +msgstr "" + +#: ../../../CHANGELOG.md:436 +msgid "`matrix_mx_puppet_slack_*`" +msgstr "" + +#: ../../../CHANGELOG.md:437 +msgid "`matrix_mx_puppet_twitter_*`" +msgstr "" + +#: ../../../CHANGELOG.md:441 +msgid "[Instruction for MX Puppet Discord bridge](./docs/configuring-playbook-bridge-mx-puppet-discord.md#uninstalling-the-bridge-manually)" +msgstr "" + +#: ../../../CHANGELOG.md:442 +msgid "[Instruction for MX Puppet Instagram bridge](./docs/configuring-playbook-bridge-mx-puppet-instagram.md#uninstalling-the-bridge-manually)" +msgstr "" + +#: ../../../CHANGELOG.md:443 +msgid "[Instruction for MX Puppet Slack bridge](./docs/configuring-playbook-bridge-mx-puppet-slack.md#uninstalling-the-bridge-manually)" +msgstr "" + +#: ../../../CHANGELOG.md:444 +msgid "[Instruction for MX Puppet Twitter bridge](./docs/configuring-playbook-bridge-mx-puppet-twitter.md#uninstalling-the-bridge-manually)" +msgstr "" + +#: ../../../CHANGELOG.md:446 +msgid "2025-11-04" +msgstr "" + +#: ../../../CHANGELOG.md:448 +msgid "The Go Skype bridge has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:450 +msgid "The [go-skype-bridge](./docs/configuring-playbook-bridge-go-skype-bridge.md) has been removed from the playbook, as Skype has been discontinued since the May 2025." +msgstr "" + +#: ../../../CHANGELOG.md:452 +msgid "The playbook will let you know if you're using any `matrix_go_skype_bridge_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the bridge manually](./docs/configuring-playbook-bridge-go-skype-bridge.md#uninstalling-the-bridge-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:454 +msgid "2025-10-02" +msgstr "" + +#: ../../../CHANGELOG.md:456 +msgid "Element Admin support" +msgstr "" + +#: ../../../CHANGELOG.md:458 +msgid "The playbook now supports [Element Admin](./docs/configuring-playbook-element-admin.md) - a new web-based administration panel for Synapse and [Matrix Authentication Service](./docs/configuring-playbook-matrix-authentication-service.md)." +msgstr "" + +#: ../../../CHANGELOG.md:460 +msgid "Deployments based on Matrix Authentication Service may find it useful to run both Synapse Admin and Element Admin at the same time." +msgstr "" + +#: ../../../CHANGELOG.md:462 +msgid "Deployments that don't rely on Matrix Authentication Service are unlikely to find anything useful in Element Admin right now (it's too basic in its current form)." +msgstr "" + +#: ../../../CHANGELOG.md:465 +msgid "2025-04-26" +msgstr "" + +#: ../../../CHANGELOG.md:467 +msgid "Continuwuity support" +msgstr "" + +#: ../../../CHANGELOG.md:469 +msgid "Thanks to [Virkkunen](https://github.com/Virkkunen), we now have optional experimental [Continuwuity](./docs/configuring-playbook-continuwuity.md) homeserver support." +msgstr "" + +#: ../../../CHANGELOG.md:471 +msgid "Continuwuity is a fork of [conduwuit](./docs/configuring-playbook-conduwuit.md), which the playbook also supports. It appears that conduwuit has been abandoned and various forks (like Continuwuity, [Tuwunel](https://github.com/matrix-construct/tuwunel) and possibly others) are continuing in its path." +msgstr "" + +#: ../../../CHANGELOG.md:473 ../../../CHANGELOG.md:686 +msgid "Existing installations do **not** need to be updated. **Synapse is still the default homeserver implementation** installed by the playbook." +msgstr "" + +#: ../../../CHANGELOG.md:475 +msgid "People that used to run conduwuit, may wish to:" +msgstr "" + +#: ../../../CHANGELOG.md:477 +msgid "either [migrate from conduwuit to Continuwuity](./docs/configuring-playbook-continuwuity.md#migrating-from-conduwuit)" +msgstr "" + +#: ../../../CHANGELOG.md:478 +msgid "or wait for some of the other forks to progress and for support for them to get added to the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:480 +msgid "**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse/Conduit/Dendrite to Continuwuity) without data loss." +msgstr "" + +#: ../../../CHANGELOG.md:483 +msgid "2025-04-09" +msgstr "" + +#: ../../../CHANGELOG.md:485 +msgid "Element Call frontend installation is now optional" +msgstr "" + +#: ../../../CHANGELOG.md:487 +msgid "Because all Element clients (Element Web and Element X mobile) now embed and use their own Element Call frontend application (and not the one hosted via the playbook), it makes little sense for the playbook to self-host the Element Call frontend for you. Setting up the frontend requires an additional hostname (DNS setup) and it won't be used by Element clients anyway, so **we now recommend not installing the Element Call frontend**." +msgstr "" + +#: ../../../CHANGELOG.md:489 +msgid "💡 A reason you may wish to continue installing the Element Call frontend (despite Matrix clients not making use of it), is if you need to use it standalone - directly via a browser (without a Matrix client)." +msgstr "" + +#: ../../../CHANGELOG.md:491 +msgid "The playbook now lets you [Decide between Element Call vs just the Matrix RTC stack](./docs/configuring-playbook-element-call.md#decide-between-element-call-vs-just-the-matrix-rtc-stack)." +msgstr "" + +#: ../../../CHANGELOG.md:493 +msgid "If you've already installed Element Call (via `matrix_element_call_enabled: true`), you can switch to installing just the [Matrix RTC (Real-Time Communication) stack](./docs/configuring-playbook-matrix-rtc.md) (all supporting services **without the Element Call frontend**) by:" +msgstr "" + +#: ../../../CHANGELOG.md:495 +msgid "Adjusting your `vars.yml` configuration like this:" +msgstr "" + +#: ../../../CHANGELOG.md:502 +msgid "[Re-running the playbook](./docs/installing.md) with the `setup-all` Ansible tag (e.g. `just setup-all`)" +msgstr "" + +#: ../../../CHANGELOG.md:504 +msgid "Getting rid of the `call.element.example.com` DNS record" +msgstr "" + +#: ../../../CHANGELOG.md:507 +msgid "2025-03-15" +msgstr "" + +#: ../../../CHANGELOG.md:509 +msgid "Element Call support" +msgstr "" + +#: ../../../CHANGELOG.md:511 +msgid "The playbook now supports [Element Call](https://github.com/element-hq/element-call) as an optional feature. Thanks to [wjbeckett](https://github.com/wjbeckett) for getting us started via [PR#3562](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3562)." +msgstr "" + +#: ../../../CHANGELOG.md:513 +msgid "Element Call is a native Matrix video conferencing application developed by [Element](https://element.io/) that has the goal of replacing [Jitsi](./docs/configuring-playbook-jitsi.md) and the old WebRTC stack used in previous Element versions." +msgstr "" + +#: ../../../CHANGELOG.md:515 +msgid "💡 For now, Element Call is only supported with the [Synapse](docs/configuring-playbook-synapse.md) homeserver (with [federation](docs/configuring-playbook-federation.md) enabled) and [Element Web](docs/configuring-playbook-client-element-web.md) and Element X mobile clients. See the [Prerequisites](docs/configuring-playbook-element-call.md#prerequisites) section of the [Element Call documentation](docs/configuring-playbook-element-call.md) for more details." +msgstr "" + +#: ../../../CHANGELOG.md:517 +msgid "To get started, see the [Configuring Element Call](docs/configuring-playbook-element-call.md) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:520 +msgid "2025-03-08" +msgstr "" + +#: ../../../CHANGELOG.md:522 +msgid "6️⃣ IPv6 support enablement recommended by default" +msgstr "" + +#: ../../../CHANGELOG.md:524 +msgid "Our [default example configuration](./examples/vars.yml) and [Configuring DNS](./docs/configuring-dns.md) guides now recommend enabling [IPv6](https://en.wikipedia.org/wiki/IPv6) support. We recommend that everyone enables IPv6 support for their Matrix server, even if they don't have IPv6 connectivity yet." +msgstr "" + +#: ../../../CHANGELOG.md:526 +msgid "Our new [Configuring IPv6](./docs/configuring-ipv6.md) documentation page has more details about the playbook's IPv6 support." +msgstr "" + +#: ../../../CHANGELOG.md:528 +msgid "**Existing playbook users** will **need to do some manual work** to enable IPv6 support. This consists of:" +msgstr "" + +#: ../../../CHANGELOG.md:530 +msgid "enabling IPv6 support for the Docker container networks:" +msgstr "" + +#: ../../../CHANGELOG.md:531 +msgid "add `devture_systemd_docker_base_ipv6_enabled: true` to their `vars.yml` configuration file" +msgstr "" + +#: ../../../CHANGELOG.md:532 +msgid "stop all services (`just stop-all`)" +msgstr "" + +#: ../../../CHANGELOG.md:533 +msgid "delete all container networks on the server: `docker network rm $(docker network ls -q)`" +msgstr "" + +#: ../../../CHANGELOG.md:534 +msgid "re-run the playbook fully: `just install-all`" +msgstr "" + +#: ../../../CHANGELOG.md:536 +msgid "[configuring IPv6 (`AAAA`) DNS records](./docs/configuring-ipv6.md#configuring-dns-records-for-ipv6)" +msgstr "" + +#: ../../../CHANGELOG.md:538 +msgid "2025-02-26" +msgstr "" + +#: ../../../CHANGELOG.md:540 +msgid "🪦 Bye-bye, Email2Matrix" +msgstr "" + +#: ../../../CHANGELOG.md:542 +msgid "The [Email2Matrix](./docs/configuring-playbook-email2matrix.md) service has been superseded by the [Postmoogle](./docs/configuring-playbook-bridge-postmoogle.md) bridge for a long time now and was completely removed from the playbook today." +msgstr "" + +#: ../../../CHANGELOG.md:544 +msgid "If you still have the Email2Matrix component installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually as described in the [Uninstalling Email2Matrix manually](./docs/configuring-playbook-email2matrix.md#uninstalling-email2matrix-manually) section of the documentation. The playbook will warn you if there are any `matrix_email2matrix_*` variables still remaining in your configuration." +msgstr "" + +#: ../../../CHANGELOG.md:547 +msgid "2025-02-23" +msgstr "" + +#: ../../../CHANGELOG.md:549 +msgid "The playbook defaults to exposing the Coturn STUN port (3478) over UDP once again" +msgstr "" + +#: ../../../CHANGELOG.md:551 +msgid "Recently, we made the playbook [default to exposing the Coturn STUN port (3478) only over TCP](#the-playbook-now-defaults-to-exposing-the-coturn-stun-port-3478-only-over-tcp) to reduce the severity of DDoS amplification/reflection attacks." +msgstr "" + +#: ../../../CHANGELOG.md:553 +msgid "It seems like old Element clients on mobile devices only support talking to the STUN port over UDP, not TCP. To accommodate such ancient clients, we're now **reversing this change** and **defaulting to exposing the Coturn STUN port (3478) over UDP once again**." +msgstr "" + +#: ../../../CHANGELOG.md:556 +msgid "In light of this new information, you have 2 options:" +msgstr "" + +#: ../../../CHANGELOG.md:558 +msgid "**If you already adapted to the previous change and would like to adapt to this change one again**:" +msgstr "" + +#: ../../../CHANGELOG.md:560 +msgid "make sure the `3478/udp` port is whitelisted in your external firewall (if you have one) once again." +msgstr "" + +#: ../../../CHANGELOG.md:562 +msgid "**If you don't care about old Element clients and wish to reduce the severity of DDoS amplification/reflection attacks**:" +msgstr "" + +#: ../../../CHANGELOG.md:564 +msgid "Consider closing the STUN/UDP port with the following configuration:" +msgstr "" + +#: ../../../CHANGELOG.md:570 +msgid "Consider keeping `3478/udp` blocked in your external firewall (if you have one)" +msgstr "" + +#: ../../../CHANGELOG.md:572 +msgid "2025-02-21" +msgstr "" + +#: ../../../CHANGELOG.md:574 +msgid "Docker daemon options are no longer adjusted when IPv6 is enabled" +msgstr "" + +#: ../../../CHANGELOG.md:576 +msgid "We landed [initial IPv6 support](#initial-work-on-ipv6-support) in the past via a `devture_systemd_docker_base_ipv6_enabled` variable that one had to toggle to `true`." +msgstr "" + +#: ../../../CHANGELOG.md:578 +msgid "This variable did **2 different things at once**:" +msgstr "" + +#: ../../../CHANGELOG.md:580 +msgid "ensured that container networks were created with IPv6 being enabled" +msgstr "" + +#: ../../../CHANGELOG.md:581 +msgid "adjusted the Docker daemon's configuration to set `experimental: true` and `ip6tables: true` (a necessary prerequisite for creating IPv6-enabled networks)" +msgstr "" + +#: ../../../CHANGELOG.md:583 +msgid "Since Docker 27.0.1's [changes to how it handles IPv6](https://docs.docker.com/engine/release-notes/27/#ipv6), **adjusting the Docker daemon's configuration is no longer necessary**, because:" +msgstr "" + +#: ../../../CHANGELOG.md:584 +msgid "`ip6tables` defaults to `true` for everyone" +msgstr "" + +#: ../../../CHANGELOG.md:585 +msgid "`ip6tables` is out of the experimental phase, so `experimental` is no longer necessary" +msgstr "" + +#: ../../../CHANGELOG.md:587 +msgid "In light of this, we're introducing a new variable (`devture_systemd_docker_base_ipv6_daemon_options_changing_enabled`) for controlling if IPv6 should be force-enabled in the Docker daemon's configuration options. Since most people should be on a modern enough Docker daemon version which doesn't require such changes, this variable defaults to `false`." +msgstr "" + +#: ../../../CHANGELOG.md:590 +msgid "This change affects you like this:" +msgstr "" + +#: ../../../CHANGELOG.md:592 +msgid "✅ if you're **not explicitly enabling IPv6** (via `devture_systemd_docker_base_ipv6_enabled` in your configuration): you're unaffected" +msgstr "" + +#: ../../../CHANGELOG.md:593 +msgid "❓ if you're **explicitly enabling IPv6** (via `devture_systemd_docker_base_ipv6_enabled` in your configuration):" +msgstr "" + +#: ../../../CHANGELOG.md:594 +msgid "✅ .. and you're on a modern enough Docker version (which you most likely are): the playbook will no longer mess with your Docker daemon options. You're unaffected." +msgstr "" + +#: ../../../CHANGELOG.md:595 +msgid "🔧 .. and you're on an old Docker version, you **are affected** and need to use the following configuration to restore the old behavior:" +msgstr "" + +#: ../../../CHANGELOG.md:606 +msgid "Support for bridging to Bluesky via mautrix-bluesky" +msgstr "" + +#: ../../../CHANGELOG.md:608 +msgid "Thanks to [Zepmann](https://github.com/Zepmann), the playbook now supports bridging to [Bluesky](https://bsky.app/) via [mautrix-bluesky](https://github.com/mautrix/bluesky)." +msgstr "" + +#: ../../../CHANGELOG.md:610 +msgid "To learn more, see our [Setting up mautrix-bluesky](./docs/configuring-playbook-bridge-mautrix-bluesky.md) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:613 +msgid "2025-02-19" +msgstr "" + +#: ../../../CHANGELOG.md:615 +msgid "The playbook now defaults to exposing the Coturn STUN port (3478) only over TCP" +msgstr "" + +#: ../../../CHANGELOG.md:617 +msgid "We've previously done some work to **decrease the severity** of DDoS amplification attacks done through the [Coturn](./docs/configuring-playbook-turn.md)'s STUN port (2.8x -> 1.6x) as reported in [coturn: Lower DDoS amplification/reflection factor from 2.8 to 1.6 #2592](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2592)." +msgstr "" + +#: ../../../CHANGELOG.md:619 +msgid "To **completely eliminate the problem** of DDoS amplification attacks done through the [Coturn](./docs/configuring-playbook-turn.md) STUN port even further (read more about this in [this article](https://stormwall.network/resources/blog/protect-against-ddos-based-on-stun-exploit)), the playbook now **disables exposure of the Coturn STUN port (`3478`) over UDP**. This is a bit heavy-handed, but is probably the only way to completely eliminate the problem." +msgstr "" + +#: ../../../CHANGELOG.md:621 +msgid "The playbook now **only exposes the Coturn STUN port (`3478`) over TCP by default**." +msgstr "" + +#: ../../../CHANGELOG.md:623 +msgid "💡 Users may wish to further remove the (now unnecessary) firewall rule allowing access to `3478/udp`." +msgstr "" + +#: ../../../CHANGELOG.md:625 +msgid "If you'd like the Coturn STUN port to be exposed over UDP like before, you can revert to the previous behavior by using the following configuration in your `vars.yml` file:" +msgstr "" + +#: ../../../CHANGELOG.md:631 +msgid "[!WARNING] People running Coturn directly on the `host` network (using `coturn_container_network: host`) will still have the STUN port exposed over UDP, as port exposure is done directly via Coturn and not via Docker. In such cases, the playbook cannot prevent `3478/udp` port exposure and you'd need to do it in another way (separate firewall rule, etc)." +msgstr "" + +#: ../../../CHANGELOG.md:635 +msgid "2025-02-17" +msgstr "" + +#: ../../../CHANGELOG.md:637 +msgid "FluffyChat Web support" +msgstr "" + +#: ../../../CHANGELOG.md:639 +msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook now supports [FluffyChat Web](https://github.com/krille-chan/fluffychat) as an additional Matrix client you can self-host." +msgstr "" + +#: ../../../CHANGELOG.md:641 +msgid "To learn more, see our [Setting up FluffyChat Web](docs/configuring-playbook-client-fluffychat-web.md) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:644 +msgid "2025-02-03" +msgstr "" + +#: ../../../CHANGELOG.md:646 +msgid "The mautrix-hangouts bridge has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:648 +msgid "The [mautrix-hangouts](./docs/configuring-playbook-bridge-mautrix-hangouts.md) bridge has been deprecated in the playbook since December 2024 and finally got completely removed from the playbook in February 2025." +msgstr "" + +#: ../../../CHANGELOG.md:650 +msgid "This is because Google Hangouts has been discontinued since the 1st of November 2022." +msgstr "" + +#: ../../../CHANGELOG.md:652 +msgid "The playbook will let you know if you're using any `matrix_mautrix_hangouts_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the bridge manually](./docs/configuring-playbook-bridge-mautrix-hangouts.md#uninstalling-the-bridge-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:655 msgid "2025-01-27" msgstr "" -#: ../../../CHANGELOG.md:3 +#: ../../../CHANGELOG.md:657 msgid "Redis and KeyDB are no longer part of the playbook" msgstr "" -#: ../../../CHANGELOG.md:5 -msgid "**TLDR**: The playbook now exclusively uses Valkey as its Redis-compatible memorystore implementation, removing support for Redis and KeyDB. Most users are unaffected by this change unless they explicitly configured Redis or KeyDB variables. Only users that were explicitly definining `redis_*` or `keydb_*` variables will need to update their configuration to use `valkey_*` variables instead." +#: ../../../CHANGELOG.md:659 +msgid "**TLDR**: The playbook now exclusively uses Valkey as its Redis-compatible memorystore implementation, removing support for Redis and KeyDB. Most users are unaffected by this change unless they explicitly configured Redis or KeyDB variables. Only users that were explicitly defining `redis_*` or `keydb_*` variables will need to update their configuration to use `valkey_*` variables instead." msgstr "" -#: ../../../CHANGELOG.md:7 +#: ../../../CHANGELOG.md:661 msgid "The playbook has gone through several iterations of memorystore implementations:" msgstr "" -#: ../../../CHANGELOG.md:9 +#: ../../../CHANGELOG.md:663 msgid "It initially used Redis, auto-installing it when needed by features/services" msgstr "" -#: ../../../CHANGELOG.md:10 +#: ../../../CHANGELOG.md:664 msgid "[Switched to KeyDB](#backward-compatibility-break-the-playbook-now-defaults-to-keydb-instead-of-redis) as the default, while keeping Redis support for those who wished to remain on Redis" msgstr "" -#: ../../../CHANGELOG.md:11 +#: ../../../CHANGELOG.md:665 msgid "[Switched to Valkey](#backward-compatibility-break-the-playbook-now-defaults-to-valkey-instead-of-keydb) due to [KeyDB issues](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3544), while keeping Redis and KeyDB support, for those who wished to remain on them" msgstr "" -#: ../../../CHANGELOG.md:13 +#: ../../../CHANGELOG.md:667 msgid "To reduce configuration complexity and maintenance overhead, we are now:" msgstr "" -#: ../../../CHANGELOG.md:15 +#: ../../../CHANGELOG.md:669 msgid "removing Redis and KeyDB support entirely" msgstr "" -#: ../../../CHANGELOG.md:16 +#: ../../../CHANGELOG.md:670 msgid "using Valkey as the sole Redis-compatible memorystore implementation" msgstr "" -#: ../../../CHANGELOG.md:18 +#: ../../../CHANGELOG.md:672 msgid "To update your configuration:" msgstr "" -#: ../../../CHANGELOG.md:20 +#: ../../../CHANGELOG.md:674 msgid "**Most users** don't need to do anything" msgstr "" -#: ../../../CHANGELOG.md:21 +#: ../../../CHANGELOG.md:675 msgid "**Users that were explicitly sticking to Redis/KeyDB** need to update their `vars.yml` to use `valkey_*` variables instead" msgstr "" -#: ../../../CHANGELOG.md:24 +#: ../../../CHANGELOG.md:678 msgid "2025-01-19" msgstr "" -#: ../../../CHANGELOG.md:26 +#: ../../../CHANGELOG.md:680 msgid "conduwuit support" msgstr "" -#: ../../../CHANGELOG.md:28 +#: ../../../CHANGELOG.md:682 msgid "Thanks to [Virkkunen](https://github.com/Virkkunen), we now have optional experimental [conduwuit](https://conduwuit.puppyirl.gay/) homeserver support for new installations." msgstr "" -#: ../../../CHANGELOG.md:30 +#: ../../../CHANGELOG.md:684 msgid "conduwuit is a fork of [Conduit](./docs/configuring-playbook-conduit.md), which the playbook also supports. See [Differences from upstream Conduit](https://conduwuit.puppyirl.gay/differences.html)." msgstr "" -#: ../../../CHANGELOG.md:32 -msgid "Existing installations do **not** need to be updated. **Synapse is still the default homeserver implementation** installed by the playbook." -msgstr "" - -#: ../../../CHANGELOG.md:34 +#: ../../../CHANGELOG.md:688 msgid "To try out conduwuit, we recommend that you **use a new server**. Refer to our [Configuring conduwuit](./docs/configuring-playbook-conduwuit.md) guide for details." msgstr "" -#: ../../../CHANGELOG.md:36 +#: ../../../CHANGELOG.md:690 msgid "**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse/Conduit/Dendrite to conduwuit) without data loss." msgstr "" -#: ../../../CHANGELOG.md:39 +#: ../../../CHANGELOG.md:693 msgid "2025-01-14" msgstr "" -#: ../../../CHANGELOG.md:41 +#: ../../../CHANGELOG.md:695 msgid "(Backward Compatibility Break) Synapse v1.122.0 requires Postgres v13" msgstr "" -#: ../../../CHANGELOG.md:43 +#: ../../../CHANGELOG.md:697 msgid "The Synapse homeserver [requires Postgres v13 or newer](https://github.com/element-hq/synapse/issues/18034)." msgstr "" -#: ../../../CHANGELOG.md:45 +#: ../../../CHANGELOG.md:699 msgid "If you've been maintaining your setup for a while and you haven't been doing [Postgres upgrades](docs/maintenance-postgres.md#upgrading-postgresql), you may be on an old version of Postgres. The easiest way to check is to see the contents of the `/matrix/postgres/data/PG_VERSION` file." msgstr "" -#: ../../../CHANGELOG.md:47 +#: ../../../CHANGELOG.md:701 msgid "If you're on a Postgres version older than v13, you need to [upgrade your Postgres setup](docs/maintenance-postgres.md#upgrading-postgresql) or Synapse will produce an error on startup." msgstr "" -#: ../../../CHANGELOG.md:49 +#: ../../../CHANGELOG.md:703 msgid "If you're using an external Postgres server (not installed by this playbook), you'll need to figure out how to upgrade it yourself." msgstr "" -#: ../../../CHANGELOG.md:51 +#: ../../../CHANGELOG.md:705 msgid "If you're not ready to upgrade your Postgres setup yet, you can temporarily remain on an old Synapse version by adding the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:59 +#: ../../../CHANGELOG.md:713 msgid "2024-11-26" msgstr "" -#: ../../../CHANGELOG.md:61 +#: ../../../CHANGELOG.md:715 msgid "(Backward Compatibility Break) Synapse now defaults to enabling authenticated media" msgstr "" -#: ../../../CHANGELOG.md:63 +#: ../../../CHANGELOG.md:717 msgid "**TLDR**: with this update, your Synapse homeserver will start requiring authentication for newly-uploaded media files. While the majority of the ecosystem (clients, bots, etc.) should support this, certain software may lack support for it (and you may wish to turn it off, if it's causing issues)." msgstr "" -#: ../../../CHANGELOG.md:65 +#: ../../../CHANGELOG.md:719 msgid "The default configuration for the Synapse homeserver now [enforces Authenticated media by default](https://element-hq.github.io/synapse/v1.120/upgrade.html#authenticated-media-is-now-enforced-by-default)." msgstr "" -#: ../../../CHANGELOG.md:67 +#: ../../../CHANGELOG.md:721 msgid "Servers like `matrix.org` have already [sunset unauthenticated media](https://matrix.org/blog/2024/06/26/sunsetting-unauthenticated-media/) months ago." msgstr "" -#: ../../../CHANGELOG.md:69 +#: ../../../CHANGELOG.md:723 msgid "Now that **various clients, bots, bridges and extra services have caught up with authenticated media support**, Synapse developers seem confident that it's time to enable authenticated media by default." msgstr "" -#: ../../../CHANGELOG.md:71 +#: ../../../CHANGELOG.md:725 msgid "We're changing the playbook configuration for authenticated media to keep up with upstream defaults changing." msgstr "" -#: ../../../CHANGELOG.md:73 +#: ../../../CHANGELOG.md:727 msgid "Old and unmaintained bridges (like all mx-puppet bridges, etc.) do not support authenticated media. Other software may be similarly affected. If you experience issues with some Matrix-related software, you may wish to disable authenticated media and contact the software maintainers to let them know." msgstr "" -#: ../../../CHANGELOG.md:75 +#: ../../../CHANGELOG.md:729 msgid "You can disable authenticated media at any time by setting `matrix_synapse_enable_authenticated_media: false` in your `vars.yml` configuration file and re-running the playbook." msgstr "" -#: ../../../CHANGELOG.md:78 +#: ../../../CHANGELOG.md:732 msgid "2024-11-23" msgstr "" -#: ../../../CHANGELOG.md:80 +#: ../../../CHANGELOG.md:734 msgid "(Backward Compatibility Break) The playbook now defaults to Valkey, instead of KeyDB" msgstr "" -#: ../../../CHANGELOG.md:82 +#: ../../../CHANGELOG.md:736 msgid "**TLDR**: if the playbook installed KeyDB (or Redis) as a dependency for you before, it will now replace it with [Valkey](https://valkey.io/) (a drop-in alternative). We [previously switched from Redis to KeyDB](#backward-compatibility-break-the-playbook-now-defaults-to-keydb-instead-of-redis), but Valkey is a better alternative, so we're switching again." msgstr "" -#: ../../../CHANGELOG.md:84 +#: ../../../CHANGELOG.md:738 msgid "The playbook used to install Redis or KeyDB if services have a need for a Redis-compatible implementation ([enabling worker support for Synapse](docs/configuring-playbook-synapse.md#load-balancing-with-workers), [enabling Hookshot encryption](docs/configuring-playbook-bridge-hookshot.md#end-to-bridge-encryption), etc.)." msgstr "" -#: ../../../CHANGELOG.md:86 +#: ../../../CHANGELOG.md:740 msgid "Earlier this year, we switched from Redis to KeyDB — see [(Backward Compatibility Break) The playbook now defaults to KeyDB, instead of Redis](#backward-compatibility-break-the-playbook-now-defaults-to-keydb-instead-of-redis)." msgstr "" -#: ../../../CHANGELOG.md:88 +#: ../../../CHANGELOG.md:742 msgid "Because Valkey seems to be a better successor to Redis (than KeyDB) and likely doesn't suffer from [issues like this one](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3544), we now replace KeyDB with Valkey." msgstr "" -#: ../../../CHANGELOG.md:90 +#: ../../../CHANGELOG.md:744 msgid "Valkey (like KeyDB and Redis in the past) is an implicitly enabled dependency — you don't need custom configuration in `vars.yml` to enable it." msgstr "" -#: ../../../CHANGELOG.md:92 +#: ../../../CHANGELOG.md:746 msgid "Next time your run the playbook (via the `setup-all` tag), **KeyDB will be automatically uninstalled and replaced with Valkey**. Some Synapse downtime may occur while the switch happens." msgstr "" -#: ../../../CHANGELOG.md:94 +#: ../../../CHANGELOG.md:748 msgid "Users on `arm32` should be aware that there's **neither a prebuilt `arm32` container image for Valkey**, nor the Valkey role supports self-building yet. Users on this architecture likely don't run Synapse with workers, etc., so they're likely in no need of Valkey (or Redis/KeyDB). If Redis is necessary in an `arm32` deployment, disabling Valkey and making the playbook fall back to Redis is possible (see below)." msgstr "" -#: ../../../CHANGELOG.md:96 ../../../CHANGELOG.md:436 +#: ../../../CHANGELOG.md:750 ../../../CHANGELOG.md:1090 msgid "**The playbook still supports Redis** and you can keep using Redis (for now) if you'd like, by adding this additional configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:107 +#: ../../../CHANGELOG.md:761 msgid "**The playbook still supports KeyDB** and you can keep using KeyDB (for now) if you'd like, by adding this additional configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:117 +#: ../../../CHANGELOG.md:771 msgid "At some point in time in the future, we'll remove both KeyDB and Redis from the playbook, so we recommend that you migrate to Valkey earlier anyway." msgstr "" -#: ../../../CHANGELOG.md:120 +#: ../../../CHANGELOG.md:774 msgid "2024-11-14" msgstr "" -#: ../../../CHANGELOG.md:122 +#: ../../../CHANGELOG.md:776 msgid "HTTP-compression support for Traefik-based setups" msgstr "" -#: ../../../CHANGELOG.md:124 +#: ../../../CHANGELOG.md:778 msgid "The playbook now **automatically enables HTTP-compression support** for major services powered by the playbook, like [Cinny](./docs/configuring-playbook-client-cinny.md), [Element Web](./docs/configuring-playbook-client-element-web.md), [Hydrogen](./docs/configuring-playbook-client-hydrogen.md), as well as for Matrix Client-Server and Federation APIs (`matrix.example.com`)." msgstr "" -#: ../../../CHANGELOG.md:126 +#: ../../../CHANGELOG.md:780 msgid "Other services installed by the playbook are currently not compression-enabled, but may become so over time. This change is rolled out on a per-service basis (as opposed to doing it globally, at the Traefik entrypoint level) to allow certain services or route endpoints which do not behave well when compressed (e.g. [issue 3749](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3749)) to be excluded from compression." msgstr "" -#: ../../../CHANGELOG.md:128 +#: ../../../CHANGELOG.md:782 msgid "A long time ago, various services were operating with `gzip`-compression enabled at the nginx level. Since the switch to Traefik (see [Goodbye, `matrix-nginx-proxy` 🪦](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/57c5271d9d6265a34a9d9cceb93365f685074f96/CHANGELOG.md#goodbye-matrix-nginx-proxy-)), all services (with the exception of Matrix APIs for Synapse worker-enabled setups which are powered by `nginx` via `synapse-reverse-proxy-companion`) have been operating without HTTP-compression support." msgstr "" -#: ../../../CHANGELOG.md:130 +#: ../../../CHANGELOG.md:784 msgid "HTTP-compression is now done via Traefik's [compress](https://doc.traefik.io/traefik/middlewares/http/compress/) middleware. We use the default configuration for this middleware, which enables `zstd`, `br` and `gzip` support (in this order). This middleware's configuration can be configured via variables in the Traefik role (see `traefik_config_http_middlewares_compression_middleware_options`)." msgstr "" -#: ../../../CHANGELOG.md:132 +#: ../../../CHANGELOG.md:786 msgid "If you're using your own Traefik reverse-proxy server ([Traefik managed by you](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-you)) instead of the playbook's integrated Traefik service, you can benefit from the same by:" msgstr "" -#: ../../../CHANGELOG.md:134 +#: ../../../CHANGELOG.md:788 msgid "defining a [compress](https://doc.traefik.io/traefik/middlewares/http/compress/) middleware (via the [file](https://doc.traefik.io/traefik/providers/file/) or [Docker](https://doc.traefik.io/traefik/providers/docker/) providers)" msgstr "" -#: ../../../CHANGELOG.md:135 +#: ../../../CHANGELOG.md:789 msgid "setting `matrix_playbook_reverse_proxy_traefik_middleware_compression_enabled` to `true`" msgstr "" -#: ../../../CHANGELOG.md:136 +#: ../../../CHANGELOG.md:790 msgid "specifying the middleware's name in `matrix_playbook_reverse_proxy_traefik_middleware_compression_name` (e.g. `matrix_playbook_reverse_proxy_traefik_middleware_compression_name: my-compression-middleware@file`)" msgstr "" -#: ../../../CHANGELOG.md:138 +#: ../../../CHANGELOG.md:792 msgid "Timeout adjustments for Traefik-based setups" msgstr "" -#: ../../../CHANGELOG.md:140 +#: ../../../CHANGELOG.md:794 msgid "The playbook now supports configuring various [transport.respondingTimeouts](https://doc.traefik.io/traefik/routing/entrypoints/#respondingtimeouts) timeout values (`readTimeout`, `writeTimeout`, `idleTimeout`) for the `web`, `web-secure` and `matrix-federation` entrypoints." msgstr "" -#: ../../../CHANGELOG.md:142 +#: ../../../CHANGELOG.md:796 msgid "If you're using your own Traefik reverse-proxy server ([Traefik managed by you](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-you)) instead of the playbook's integrated Traefik service, you may wish to do similar configuration changes to your setup manually." msgstr "" -#: ../../../CHANGELOG.md:144 +#: ../../../CHANGELOG.md:798 msgid "The most interesting of these is the `readTimeout` configuration value (the maximum duration for reading the entire request, including the body), which used to default to `60s`. For large and slowly progressing file uploads, `60s` would often not be enough for the transfer to finish and uploads would end up being interrupted. The playbook now raises the `readTimeout` value to 5 minutes (`300s`) to improve this use-case." msgstr "" -#: ../../../CHANGELOG.md:146 +#: ../../../CHANGELOG.md:800 msgid "The `traefik_config_entrypoint_web_transport_respondingTimeouts_*` variables (for the `web` entrypoint) cascade to affecting the timeout values for the `web-secure` and `matrix-federation` entrypoints, so you can easily adjust all timeout values using them." msgstr "" -#: ../../../CHANGELOG.md:148 +#: ../../../CHANGELOG.md:802 msgid "Example of the default timeout values used by the playbook:" msgstr "" -#: ../../../CHANGELOG.md:159 +#: ../../../CHANGELOG.md:813 msgid "Alternatively, you may adjust the timeout values for specific entrypoints (like `web-secure` and `matrix-federation`) using dedicated variables (like `traefik_config_entrypoint_web_secure_transport_respondingTimeouts_readTimeout` and `matrix_playbook_public_matrix_federation_api_traefik_entrypoint_config_transport_respondingTimeouts_readTimeout`)." msgstr "" -#: ../../../CHANGELOG.md:162 +#: ../../../CHANGELOG.md:816 msgid "2024-11-08" msgstr "" -#: ../../../CHANGELOG.md:164 +#: ../../../CHANGELOG.md:818 msgid "Support for synapse-admin auto-configuration via /.well-known/matrix/client" msgstr "" -#: ../../../CHANGELOG.md:166 +#: ../../../CHANGELOG.md:820 msgid "You can administrate your Synapse-powered homeserver using synapse-admin hosted externally (e.g. [admin.etke.cc](https://admin.etke.cc/)) and the synapse-admin instance would still auto-configure itself correctly for your server by [reading its `/.well-known/matrix/client` file](https://github.com/etkecc/synapse-admin/pull/126)." msgstr "" -#: ../../../CHANGELOG.md:168 +#: ../../../CHANGELOG.md:822 msgid "The playbook now configures the `/.well-known/matrix/client` file for this by default, injecting into it a `cc.etke.synapse-admin` section that contains the full synapse-admin configuration. This is done even if you don't enable the synapse-admin service in your configuration. The reason for always doing it is to allow users to skip the (small) overhead of self-hosting the non-core synapse-admin service, yet still be able to use it from elsewhere when needed." msgstr "" -#: ../../../CHANGELOG.md:170 +#: ../../../CHANGELOG.md:824 msgid "If you don't ever plan on using synapse-admin from other servers (besides your own due to [self-hosting synapse-admin](./docs/configuring-playbook-synapse-admin.md)), you **can disable this** `/.well-known/matrix/client` configuration via `matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin_enabled: false`" msgstr "" -#: ../../../CHANGELOG.md:173 +#: ../../../CHANGELOG.md:827 msgid "2024-10-28" msgstr "" -#: ../../../CHANGELOG.md:175 +#: ../../../CHANGELOG.md:829 msgid "(BC Break) Postmoogle's variable names need adjustments" msgstr "" -#: ../../../CHANGELOG.md:177 +#: ../../../CHANGELOG.md:831 msgid "Due to the recategorization of [Postmoogle](./docs/configuring-playbook-bridge-postmoogle.md) from the bot to the bridge, its variables were renamed (`matrix_bot_postmoogle_` -> `matrix_postmoogle_`). You need to adjust your `vars.yml` configuration accordingly." msgstr "" -#: ../../../CHANGELOG.md:179 +#: ../../../CHANGELOG.md:833 msgid "2024-10-19" msgstr "" -#: ../../../CHANGELOG.md:181 +#: ../../../CHANGELOG.md:835 msgid "Support for Matrix Authentication Service" msgstr "" -#: ../../../CHANGELOG.md:183 +#: ../../../CHANGELOG.md:837 msgid "The playbook now supports installing and configuring [Matrix Authentication Service](./docs/configuring-playbook-matrix-authentication-service.md) (MAS)." msgstr "" -#: ../../../CHANGELOG.md:185 +#: ../../../CHANGELOG.md:839 msgid "Huge thanks to [Quentin Gliech](https://github.com/sandhose) from the [Element](https://element.io/) / [Matrix Authentication Service](https://github.com/element-hq/matrix-authentication-service) team for answering our numerous questions about MAS." msgstr "" -#: ../../../CHANGELOG.md:187 +#: ../../../CHANGELOG.md:841 msgid "This is an **experimental service** and there are **still certain issues with it** (see [Expectations](./docs/configuring-playbook-matrix-authentication-service.md#expectations)). Matrix server administrators should only consider switching if they identify with one or more [reasons to use Matrix Authentication Service](./docs/configuring-playbook-matrix-authentication-service.md#reasons-to-use-matrix-authentication-service). As MAS adoption improves and more services are adjusted to support it, we expect that using MAS will become the norm." msgstr "" -#: ../../../CHANGELOG.md:189 +#: ../../../CHANGELOG.md:843 msgid "Our [Setting up Matrix Authentication Service](./docs/configuring-playbook-matrix-authentication-service.md) documentation page has more details about this new service, what you might expect from the switch and how you can migrate your existing (Synapse) homeserver setup to MAS." msgstr "" -#: ../../../CHANGELOG.md:192 +#: ../../../CHANGELOG.md:846 msgid "2024-09-27" msgstr "" -#: ../../../CHANGELOG.md:194 +#: ../../../CHANGELOG.md:848 msgid "(BC Break) Postgres & Traefik roles have been relocated and variable names need adjustments" msgstr "" -#: ../../../CHANGELOG.md:196 +#: ../../../CHANGELOG.md:850 msgid "Various roles have been relocated from the [devture](https://github.com/devture) organization to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." msgstr "" -#: ../../../CHANGELOG.md:198 +#: ../../../CHANGELOG.md:852 msgid "Along with the relocation, the `devture_` prefix was dropped from their variable names, so you need to adjust your `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:200 +#: ../../../CHANGELOG.md:854 msgid "You need to do the following replacements:" msgstr "" -#: ../../../CHANGELOG.md:202 +#: ../../../CHANGELOG.md:856 msgid "`devture_postgres_` -> `postgres_`" msgstr "" -#: ../../../CHANGELOG.md:203 +#: ../../../CHANGELOG.md:857 msgid "`devture_traefik_` -> `traefik_`" msgstr "" -#: ../../../CHANGELOG.md:205 -msgid "As always, the playbook would let you know about this and point out any variables you may have missed." -msgstr "" - -#: ../../../CHANGELOG.md:208 +#: ../../../CHANGELOG.md:862 msgid "2024-09-12" msgstr "" -#: ../../../CHANGELOG.md:210 +#: ../../../CHANGELOG.md:864 msgid "Support for baibot" msgstr "" -#: ../../../CHANGELOG.md:212 +#: ../../../CHANGELOG.md:866 msgid "The playbook now supports installing [baibot](./docs/configuring-playbook-bot-baibot.md) (pronounced bye-bot) — a [Matrix](https://matrix.org/) bot developed by [etke.cc](https://etke.cc/) that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you. 🤖" msgstr "" -#: ../../../CHANGELOG.md:214 +#: ../../../CHANGELOG.md:868 msgid "It supports [OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/) models, as well as many other [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md)." msgstr "" -#: ../../../CHANGELOG.md:216 +#: ../../../CHANGELOG.md:870 msgid "It's designed as a more private and [✨ featureful](https://github.com/etkecc/baibot/?tab=readme-ov-file#-features) alternative to the now-unmaintained [matrix-chatgpt-bot](./docs/configuring-playbook-bot-chatgpt.md)." msgstr "" -#: ../../../CHANGELOG.md:218 +#: ../../../CHANGELOG.md:872 msgid "To get started, see the [Setting up baibot](./docs/configuring-playbook-bot-baibot.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:220 +#: ../../../CHANGELOG.md:874 msgid "Switching synapse-admin to etke.cc's fork" msgstr "" -#: ../../../CHANGELOG.md:222 +#: ../../../CHANGELOG.md:876 msgid "The playbook now installs [etke.cc](https://etke.cc/)'s [fork](https://github.com/etkecc/synapse-admin) of [synapse-admin](https://github.com/Awesome-Technologies/synapse-admin) (originally developed by [Awesome-Technologies](https://github.com/Awesome-Technologies)). This fork is a drop-in replacement for the original software." msgstr "" -#: ../../../CHANGELOG.md:224 +#: ../../../CHANGELOG.md:878 msgid "The creation of the fork has been provoked by users frequently encountering issues with the original synapse-admin software, such as unintentionally deleting their one-and-only admin user account (fixed [here](https://github.com/etkecc/synapse-admin/pull/1) and also contributed upstream [here](https://github.com/Awesome-Technologies/synapse-admin/pull/608) — to no avail for now). Since its inception, [a bunch of other quality-of-life improvements](https://github.com/etkecc/synapse-admin?tab=readme-ov-file#changes) have been made to the fork." msgstr "" -#: ../../../CHANGELOG.md:226 +#: ../../../CHANGELOG.md:880 msgid "If upstream synapse-admin picks up the pace and improves, the etke.cc fork may disappear and the playbook may switch to the original software again. Until that time comes, we believe that etke.cc's fork is the better software to use right now." msgstr "" -#: ../../../CHANGELOG.md:228 +#: ../../../CHANGELOG.md:882 msgid "If you'd like to switch back to the original synapse-admin software, you can do so by adding the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:241 +#: ../../../CHANGELOG.md:895 msgid "2024-08-17" msgstr "" -#: ../../../CHANGELOG.md:243 +#: ../../../CHANGELOG.md:897 msgid "New appservice-double-puppet service for better double-puppeting" msgstr "" -#: ../../../CHANGELOG.md:245 +#: ../../../CHANGELOG.md:899 msgid "Mautrix bridges are undergoing large changes as announced in the [August 2024 releases & progress](https://mau.fi/blog/2024-08-mautrix-release/) blog post." msgstr "" -#: ../../../CHANGELOG.md:247 +#: ../../../CHANGELOG.md:901 msgid "The playbook has already upgraded to the rewritten mautrix-slack ([v0.1.0](https://github.com/mautrix/slack/releases/tag/v0.1.0)) and mautrix-signal ([v0.7.0](https://github.com/mautrix/signal/releases/tag/v0.7.0)) bridges." msgstr "" -#: ../../../CHANGELOG.md:249 +#: ../../../CHANGELOG.md:903 msgid "The newly rewritten bridges do not support double-puppeting via [Shared Secret Auth](./docs/configuring-playbook-shared-secret-auth.md) anymore, which has prompted us to switch to the new & better [appservice method](https://docs.mau.fi/bridges/general/double-puppeting.html#appservice-method-new) for double-puppeting. The playbook automates this double-puppeting setup for you if you enable the new [Appservice Double Puppet](./docs/configuring-playbook-appservice-double-puppet.md) service." msgstr "" -#: ../../../CHANGELOG.md:251 +#: ../../../CHANGELOG.md:905 msgid "All non-deprecated mautrix bridges in the playbook have been reworked to support double-puppeting via an Appservice. Most bridges still support double-puppeting via [Shared Secret Auth](./docs/configuring-playbook-shared-secret-auth.md), so the playbook supports it too. If only Shared Secret Auth is enabled, double-puppeting will be configured using that method (for the bridges that support it). That said, **Shared Secret Auth double-puppeting is being phased out and we recommend replacing it with the new Appservice method**." msgstr "" -#: ../../../CHANGELOG.md:253 +#: ../../../CHANGELOG.md:907 msgid "We recommend **enabling double-puppeting via the new Appservice method** by adding the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:259 +#: ../../../CHANGELOG.md:913 msgid "You can still **keep** [Shared Secret Auth](./docs/configuring-playbook-shared-secret-auth.md) enabled. Non-mautrix bridges and other services (e.g. [matrix-corporal](./docs/configuring-playbook-matrix-corporal.md)) may still require it." msgstr "" -#: ../../../CHANGELOG.md:261 +#: ../../../CHANGELOG.md:915 msgid "When both double-puppeting methods are enabled, the playbook will automatically choose the new and better Appservice method for bridges that support it." msgstr "" -#: ../../../CHANGELOG.md:264 +#: ../../../CHANGELOG.md:918 msgid "2024-08-15" msgstr "" -#: ../../../CHANGELOG.md:266 +#: ../../../CHANGELOG.md:920 msgid "matrix-media-repo now configured for Authenticated Media" msgstr "" -#: ../../../CHANGELOG.md:268 +#: ../../../CHANGELOG.md:922 msgid "Thanks to [Michael Hollister](https://github.com/Michael-Hollister) from [FUTO](https://www.futo.org/), our matrix-media-repo implementation now automatically [sets up signing keys](https://docs.t2bot.io/matrix-media-repo/v1.3.5/installation/signing-key/) for Authenticated Media (as per [MSC3916](https://github.com/matrix-org/matrix-spec-proposals/pull/3916))." msgstr "" -#: ../../../CHANGELOG.md:270 +#: ../../../CHANGELOG.md:924 msgid "If you had never heard of Authenticated Media before, the [Sunsetting unauthenticated media](https://matrix.org/blog/2024/06/26/sunsetting-unauthenticated-media/) article on [matrix.org](https://matrix.org/) is a good introduction." msgstr "" -#: ../../../CHANGELOG.md:272 +#: ../../../CHANGELOG.md:926 msgid "This feature is enabled for matrix-media-repo installations by default and will append an additional (matrix-media-repo-generated signing key) to your homeserver's (Synapse or Dendrite) signing key. See the [Signing keys](./docs/configuring-playbook-matrix-media-repo.md#signing-keys) and [Key backup and revoking](./docs/configuring-playbook-matrix-media-repo.md#key-backup-and-revoking) sections of the matrix-media-repo documentation for more details." msgstr "" -#: ../../../CHANGELOG.md:274 +#: ../../../CHANGELOG.md:928 msgid "If you'd like to avoid this new feature, you can disable it by setting `matrix_media_repo_generate_signing_key: false` in your `vars.yml` configuration file." msgstr "" -#: ../../../CHANGELOG.md:277 +#: ../../../CHANGELOG.md:931 msgid "2024-08-08" msgstr "" -#: ../../../CHANGELOG.md:279 +#: ../../../CHANGELOG.md:933 msgid "(Backward Compatibility Break) matrix-corporal has been upgraded to v3" msgstr "" -#: ../../../CHANGELOG.md:281 +#: ../../../CHANGELOG.md:935 msgid "The playbook now installs [matrix-corporal](https://github.com/devture/matrix-corporal) v3.0.0, which brings support for **power-level management** (thanks to [this PR](https://github.com/devture/matrix-corporal/pull/32))." msgstr "" -#: ../../../CHANGELOG.md:283 +#: ../../../CHANGELOG.md:937 msgid "This upgrade necessitates configuration policy changes as described in [matrix-corporal's changelog entry](https://github.com/devture/matrix-corporal/blob/5287cb81c82cd3b951c2a099b4697c3e0b384559/CHANGELOG.md#version-300-2024-08-08)." msgstr "" -#: ../../../CHANGELOG.md:285 +#: ../../../CHANGELOG.md:939 msgid "If you'd like to remain on the old (v2) version of matrix-corporal, you can do so by adding the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:291 +#: ../../../CHANGELOG.md:945 msgid "2024-07-25" msgstr "" -#: ../../../CHANGELOG.md:293 +#: ../../../CHANGELOG.md:947 msgid "synapse-usage-exporter support" msgstr "" -#: ../../../CHANGELOG.md:295 +#: ../../../CHANGELOG.md:949 msgid "Thanks to [Michael Hollister](https://github.com/Michael-Hollister) from [FUTO](https://www.futo.org/), the creators of the [Circles app](https://circu.li/), the playbook can now set up [synapse-usage-exporter](https://github.com/loelkes/synapse-usage-exporter) — a small [Flask](https://flask.palletsprojects.com)-based webservice which can capture usage statistics from Synapse (via HTTP `PUT`) and then make them available for Prometheus to scrape." msgstr "" -#: ../../../CHANGELOG.md:297 +#: ../../../CHANGELOG.md:951 msgid "To learn more see our [Enabling synapse-usage-exporter for Synapse usage statistics](docs/configuring-playbook-synapse-usage-exporter.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:300 +#: ../../../CHANGELOG.md:954 msgid "2024-07-06" msgstr "" -#: ../../../CHANGELOG.md:302 +#: ../../../CHANGELOG.md:956 msgid "matrix-alertmanager-receiver support" msgstr "" -#: ../../../CHANGELOG.md:304 +#: ../../../CHANGELOG.md:958 msgid "For those wishing to more easily integrate [Prometheus](https://prometheus.io/)' alerting service ([Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/)) with Matrix, the playbook can now set up [matrix-alertmanager-receiver](https://github.com/metio/matrix-alertmanager-receiver)." msgstr "" -#: ../../../CHANGELOG.md:306 +#: ../../../CHANGELOG.md:960 msgid "See [Setting up Prometheus Alertmanager integration via matrix-alertmanager-receiver](./docs/configuring-playbook-alertmanager-receiver.md) for more details." msgstr "" -#: ../../../CHANGELOG.md:308 +#: ../../../CHANGELOG.md:962 msgid "Traefik v3 and HTTP/3 are here now" msgstr "" -#: ../../../CHANGELOG.md:310 +#: ../../../CHANGELOG.md:964 msgid "**TLDR**: Traefik was migrated from v2 to v3. Minor changes were done to the playbook. Mostly everything else worked out of the box. Most people will not have to do any tweaks to their configuration. In addition, [HTTP/3](https://en.wikipedia.org/wiki/HTTP/3) support is now auto-enabled for the `web-secure` (port 443) and `matrix-federation` (port `8448`) entrypoints. If you have a firewall in front of your server and you wish to benefit from `HTTP3`, you will need to open the `443` and `8448` UDP ports in it." msgstr "" -#: ../../../CHANGELOG.md:312 +#: ../../../CHANGELOG.md:966 msgid "Traefik v3" msgstr "" -#: ../../../CHANGELOG.md:314 +#: ../../../CHANGELOG.md:968 msgid "The reverse-proxy that the playbook uses by default (Traefik) has recently been upgraded to v3 (see [this blog post](https://traefik.io/blog/announcing-traefik-proxy-v3-rc/) to learn about its new features). Version 3 includes some small breaking configuration changes requiring a [migration](https://doc.traefik.io/traefik/migration/v2-to-v3/)." msgstr "" -#: ../../../CHANGELOG.md:316 +#: ../../../CHANGELOG.md:970 msgid "We have **updated the playbook to Traefik v3** (make sure to run `just roles` / `make roles` to get it)." msgstr "" -#: ../../../CHANGELOG.md:318 +#: ../../../CHANGELOG.md:972 msgid "There were **only minor playbook changes required** to adapt to Traefik v3, and only to the Ansible role for [matrix-media-repo](./docs/configuring-playbook-matrix-media-repo.md) where we changed a few [`PathPrefix` instances to `PathRegexp`](https://doc.traefik.io/traefik/routing/routers/#path-pathprefix-and-pathregexp), because these instances were using a regular expression instead of a fixed path. For fixed-path values, `PathPrefix` is still the preferred matcher function to use." msgstr "" -#: ../../../CHANGELOG.md:320 +#: ../../../CHANGELOG.md:974 msgid "**Most people using the playbook should not have to do any changes**." msgstr "" -#: ../../../CHANGELOG.md:322 +#: ../../../CHANGELOG.md:976 msgid "If you're using the playbook's Traefik instance to reverse-proxy to some other services of your own (not managed by the playbook), you may wish to review their Traefik labels and make sure they're in line with the [Traefik v2 to v3 migration guide](https://doc.traefik.io/traefik/migration/v2-to-v3/)." msgstr "" -#: ../../../CHANGELOG.md:324 +#: ../../../CHANGELOG.md:978 msgid "If you've tweaked any of this playbook's `_path_prefix` variables and made them use a regular expression, you will now need to make additional adjustments. The playbook makes extensive use of `PathPrefix()` matchers in Traefik rules and `PathPrefix` does not support regular expressions anymore. To work around it, you may now need to override a whole `_traefik_rule` variable and switch it from [`PathPrefix` to `PathRegexp`](https://doc.traefik.io/traefik/routing/routers/#path-pathprefix-and-pathregexp)." msgstr "" -#: ../../../CHANGELOG.md:326 +#: ../../../CHANGELOG.md:980 msgid "If you're not using [matrix-media-repo](./docs/configuring-playbook-matrix-media-repo.md) (the only role we had to tweak to adapt it to Traefik v3), you **may potentially downgrade to Traefik v2** (if necessary) by adding `traefik_verison: v2.11.4` to your configuration. People using `matrix-media-repo` cannot downgrade this way, because `matrix-media-repo` has been adjusted to use `PathRegexp` — a [routing matcher](https://doc.traefik.io/traefik/v2.11/routing/routers/#rule) that Traefik v2 does not understand." msgstr "" -#: ../../../CHANGELOG.md:328 +#: ../../../CHANGELOG.md:982 msgid "HTTP/3 is enabled by default" msgstr "" -#: ../../../CHANGELOG.md:330 +#: ../../../CHANGELOG.md:984 msgid "In Traefik v3, [HTTP/3](https://en.wikipedia.org/wiki/HTTP/3) support is no longer considered experimental now. Due to this, **the playbook auto-enables HTTP3** for the `web-secure` (port 443) and `matrix-federation` (port `8448`) entrypoints." msgstr "" -#: ../../../CHANGELOG.md:332 +#: ../../../CHANGELOG.md:986 msgid "HTTP3 uses the UDP protocol and **the playbook (together with Docker) will make sure that the appropriate ports** (`443` over UDP & `8448` over UDP) **are exposed and whitelisted in your server's firewall**. However, **if you have another firewall in front of your server** (as is the case for many cloud providers), **you will need to manually open these UDP ports**." msgstr "" -#: ../../../CHANGELOG.md:334 +#: ../../../CHANGELOG.md:988 msgid "If you do not open the UDP ports correctly or there is some other issue, clients (browsers, mostly) will fall-back to [HTTP/2](https://en.wikipedia.org/wiki/HTTP/2) or even [HTTP/1.1](https://en.wikipedia.org/wiki/HTTP)." msgstr "" -#: ../../../CHANGELOG.md:336 +#: ../../../CHANGELOG.md:990 msgid "Still, if HTTP/3 cannot function correctly in your setup, it's best to disable advertising support for it (and misleading clients into trying to use HTTP/3)." msgstr "" -#: ../../../CHANGELOG.md:338 +#: ../../../CHANGELOG.md:992 msgid "To **disable HTTP/3**, you can use the following configuration:" msgstr "" -#: ../../../CHANGELOG.md:352 +#: ../../../CHANGELOG.md:1006 msgid "If you are using [your own webserver](./docs/configuring-playbook-own-webserver.md) (in front of Traefik), port binding on UDP port `8448` by default due to HTTP/3 is either unnecessary or [may get in the way](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3402). If it does, you can disable it:" msgstr "" -#: ../../../CHANGELOG.md:365 +#: ../../../CHANGELOG.md:1019 msgid "2024-07-01" msgstr "" -#: ../../../CHANGELOG.md:367 +#: ../../../CHANGELOG.md:1021 msgid "synapse-admin is now restricted to your homeserver's URL by default" msgstr "" -#: ../../../CHANGELOG.md:369 +#: ../../../CHANGELOG.md:1023 msgid "A new feature introduced in synapse-admin [v0.10.0](https://github.com/Awesome-Technologies/synapse-admin/releases/tag/0.10.0) (released and supported by the playbook since a a few months ago) provides the ability to [restrict its usage to a specific homeserver](https://github.com/Awesome-Technologies/synapse-admin/blob/e21e44362c879ac41f47c580b04210842b6ff3d7/README.md#restricting-available-homeserver) (or multiple homeservers)." msgstr "" -#: ../../../CHANGELOG.md:371 +#: ../../../CHANGELOG.md:1025 msgid "The playbook has just started making use of this feature. **From now on, your synapse-admin instance will be restricted to the homeserver you're managing via the playbook**. When configured like this, the *Homeserver URL* field in synapse-admin's web UI changes from a text field to a dropdown having a single value (the URL of your homeserver). This makes usage simpler for most people, as they won't need to manually enter a *Homeserver URL* anymore." msgstr "" -#: ../../../CHANGELOG.md:373 +#: ../../../CHANGELOG.md:1027 msgid "If you'd like **to go back to the old unrestricted behavior**, use the following configuration:" msgstr "" -#: ../../../CHANGELOG.md:381 +#: ../../../CHANGELOG.md:1035 msgid "2024-06-25" msgstr "" -#: ../../../CHANGELOG.md:383 +#: ../../../CHANGELOG.md:1037 msgid "The URL-prefix for Hookshot generic webhooks has changed" msgstr "" -#: ../../../CHANGELOG.md:385 +#: ../../../CHANGELOG.md:1039 msgid "Until now, generic Hookshot webhook URLs looked like this: `https://matrix.example.com/hookshot/webhooks/:hookId`." msgstr "" -#: ../../../CHANGELOG.md:387 +#: ../../../CHANGELOG.md:1041 msgid "The `/hookshot/webhooks` common prefix gets stripped by Traefik automatically, so Hookshot only sees the part that comes after (`/:hookId`)." msgstr "" -#: ../../../CHANGELOG.md:389 +#: ../../../CHANGELOG.md:1043 msgid "[A few years ago](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1681), Hookshot started to prefer to handle webhooks at a `/webhook/:hookId` path (instead of directly at `/:hookId`)." msgstr "" -#: ../../../CHANGELOG.md:391 +#: ../../../CHANGELOG.md:1045 msgid "To avoid future problems, we've [reconfigured](https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/4704a60718946fd469aeee7fc3ae8127c633bb6b) our Hookshot configuration to use webhook URLs that include `/webhook` in the URL suffix (e.g. `/hookshot/webhooks/webhook/:hookId`, instead of `/hookshot/webhooks/:hookId`). This means that when we strip the common prefi (`/hookshot/webhooks`), we'll end up sending `/webhook/:hookId` to Hookshot, just like recommended." msgstr "" -#: ../../../CHANGELOG.md:393 +#: ../../../CHANGELOG.md:1047 msgid "When generating new webhooks, you should start seeing the new URLs being used." msgstr "" -#: ../../../CHANGELOG.md:395 +#: ../../../CHANGELOG.md:1049 msgid "**For now**, **both** old URLs (`/hookshot/webhooks/:hookId`) and new URLs (`/hookshot/webhooks/webhook/:hookId`) **continue to work**, so your webhooks will not break just yet." msgstr "" -#: ../../../CHANGELOG.md:397 +#: ../../../CHANGELOG.md:1051 msgid "However, **we recommend that you update all your old webhook URLs** (configured in other systems) to include the new `/webhook` path component, so that future Hookshot changes (whenever they come) will not break your webhooks. You don't need to do anything on the Hookshot side — you merely need to reconfigure the remote systems that use your webhook URLs." msgstr "" -#: ../../../CHANGELOG.md:400 +#: ../../../CHANGELOG.md:1054 msgid "2024-06-22" msgstr "" -#: ../../../CHANGELOG.md:402 +#: ../../../CHANGELOG.md:1056 msgid "The maubot user is now managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:404 +#: ../../../CHANGELOG.md:1058 msgid "To make things easier and to be consistent with other roles, the [maubot](./docs/configuring-playbook-bot-maubot.md) user (`bot.maubot` by default) is [now](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3376) automatically created be the playbook." msgstr "" -#: ../../../CHANGELOG.md:406 +#: ../../../CHANGELOG.md:1060 msgid "If you have an existing maubot installation, you will need to specify `matrix_bot_maubot_initial_password` in your `vars.yml` file to make the playbook not complain about it being undefined. Since the bot is already registered in your installation, there's nothing for the playbook to do anyway. In case you don't remember the password you've registered your maubot user account with, you can specify any value for this variable." msgstr "" -#: ../../../CHANGELOG.md:408 +#: ../../../CHANGELOG.md:1062 msgid "If you've registered another username for the bot (other than the recommended default of `bot.maubot`), consider adjusting the `matrix_bot_maubot_login` variable (e.g. `matrix_bot_maubot_login: my.maubot.username`)." msgstr "" -#: ../../../CHANGELOG.md:411 +#: ../../../CHANGELOG.md:1065 msgid "2024-06-03" msgstr "" -#: ../../../CHANGELOG.md:413 +#: ../../../CHANGELOG.md:1067 msgid "WeChat bridging support" msgstr "" -#: ../../../CHANGELOG.md:415 +#: ../../../CHANGELOG.md:1069 msgid "Thanks to [Tobias Diez](https://github.com/tobiasdiez)'s [efforts](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3241), the playbook now supports bridging to [WeChat](https://www.wechat.com/) via the [matrix-wechat](https://github.com/duo/matrix-wechat) bridge." msgstr "" -#: ../../../CHANGELOG.md:417 +#: ../../../CHANGELOG.md:1071 msgid "See our [Setting up WeChat bridging](docs/configuring-playbook-bridge-wechat.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:420 +#: ../../../CHANGELOG.md:1074 msgid "2024-03-26" msgstr "" -#: ../../../CHANGELOG.md:422 +#: ../../../CHANGELOG.md:1076 msgid "(Backward Compatibility Break) The playbook now defaults to KeyDB, instead of Redis" msgstr "" -#: ../../../CHANGELOG.md:424 +#: ../../../CHANGELOG.md:1078 msgid "**TLDR**: if the playbook used installed Redis as a dependency for you before, it will now replace it with [KeyDB](https://docs.keydb.dev/) (a drop-in alternative) due to [Redis having changed its license](https://redis.com/blog/redis-adopts-dual-source-available-licensing/)." msgstr "" -#: ../../../CHANGELOG.md:426 +#: ../../../CHANGELOG.md:1080 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook now uses [KeyDB](https://docs.keydb.dev/) (a drop-in alternative for Redis), instead of [Redis](https://redis.io/)." msgstr "" -#: ../../../CHANGELOG.md:428 +#: ../../../CHANGELOG.md:1082 msgid "The playbook used to install Redis (and now installs KeyDB in its place) if services have a need for it ([enabling worker support for Synapse](docs/configuring-playbook-synapse.md#load-balancing-with-workers), [enabling Hookshot encryption](docs/configuring-playbook-bridge-hookshot.md#end-to-bridge-encryption), etc.) or if you explicitly enabled the service (`redis_enabled: true` or `keydb_enabled: true`)." msgstr "" -#: ../../../CHANGELOG.md:430 +#: ../../../CHANGELOG.md:1084 msgid "This change is provoked by the fact that [Redis is now \"source available\"](https://redis.com/blog/redis-adopts-dual-source-available-licensing/). According to the Limitations of [the new license](https://redis.com/legal/rsalv2-agreement/) (as best as we understand them, given that we're not lawyers), using Redis in the playbook (even in a commercial FOSS service like [etke.cc](https://etke.cc/)) does not violate the new Redis license. That said, we'd rather neither risk it, nor endorse shady licenses and products that pretend to be free-software. Another high-quality alternative to Redis seems to be [Dragonfly](https://www.dragonflydb.io/), but the [Dragonfly license](https://github.com/dragonflydb/dragonfly?tab=License-1-ov-file#readme) is no better than Redis's." msgstr "" -#: ../../../CHANGELOG.md:432 +#: ../../../CHANGELOG.md:1086 msgid "Next time your run the playbook (via the `setup-all` tag), **Redis will be automatically uninstalled and replaced with KeyDB**. Some Synapse downtime may occur while the switch happens." msgstr "" -#: ../../../CHANGELOG.md:434 +#: ../../../CHANGELOG.md:1088 msgid "Users on `arm32` should be aware that there's **neither a prebuilt `arm32` container image for KeyDB**, nor the KeyDB role supports self-building yet. Users on this architecture likely don't run Synapse with workers, etc., so they're likely in no need of KeyDB (or Redis). If Redis is necessary in an `arm32` deployment, disabling KeyDB and making the playbook fall back to Redis is possible (see below)." msgstr "" -#: ../../../CHANGELOG.md:445 +#: ../../../CHANGELOG.md:1099 msgid "2024-03-24" msgstr "" -#: ../../../CHANGELOG.md:447 +#: ../../../CHANGELOG.md:1101 msgid "Initial work on IPv6 support" msgstr "" -#: ../../../CHANGELOG.md:449 +#: ../../../CHANGELOG.md:1103 msgid "Thanks to [Tilo Spannagel](https://github.com/tilosp), the playbook can now enable IPv6 for container networks for various components (roles) via [the `devture_systemd_docker_base_ipv6_enabled` variable](https://github.com/devture/com.devture.ansible.role.systemd_docker_base/blob/c11a526bb8e318b42eb52055056377bb31154f13/defaults/main.yml#L14-L31)." msgstr "" -#: ../../../CHANGELOG.md:451 +#: ../../../CHANGELOG.md:1105 msgid "It should be noted that:" msgstr "" -#: ../../../CHANGELOG.md:453 +#: ../../../CHANGELOG.md:1107 msgid "Matrix roles (`roles/custom/matrix-*`) respect this variable, but external roles (those defined in `requirements.yml` and installed via `just roles`) do not respect it yet. Additional work is necessary" msgstr "" -#: ../../../CHANGELOG.md:454 +#: ../../../CHANGELOG.md:1108 msgid "changing the variable subsequently may not change existing container networks. Refer to [these instructions](https://github.com/devture/com.devture.ansible.role.systemd_docker_base/blob/c11a526bb8e318b42eb52055056377bb31154f13/defaults/main.yml#L26-L30)" msgstr "" -#: ../../../CHANGELOG.md:455 +#: ../../../CHANGELOG.md:1109 msgid "this is all very new and untested" msgstr "" -#: ../../../CHANGELOG.md:457 +#: ../../../CHANGELOG.md:1111 msgid "Pantalaimon support" msgstr "" -#: ../../../CHANGELOG.md:459 +#: ../../../CHANGELOG.md:1113 msgid "Thanks to [Julian Foad](https://matrix.to/#/@julian:foad.me.uk), the playbook can now install the [Pantalaimon](https://github.com/matrix-org/pantalaimon) E2EE aware proxy daemon for you. It's already possible to integrate it with [Draupnir](docs/configuring-playbook-bot-draupnir.md) to allow it to work in E2EE rooms — see our Draupnir docs for details." msgstr "" -#: ../../../CHANGELOG.md:461 +#: ../../../CHANGELOG.md:1115 msgid "See our [Setting up Pantalaimon](docs/configuring-playbook-pantalaimon.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:464 +#: ../../../CHANGELOG.md:1118 msgid "2024-03-05" msgstr "" -#: ../../../CHANGELOG.md:466 +#: ../../../CHANGELOG.md:1120 msgid "Support for Draupnir-for-all" msgstr "" -#: ../../../CHANGELOG.md:468 +#: ../../../CHANGELOG.md:1122 msgid "Thanks to [FSG-Cat](https://github.com/FSG-Cat), the playbook can now install [Draupnir for all](./docs/configuring-playbook-appservice-draupnir-for-all.md) (aka multi-instance Draupnir running in appservice mode)." msgstr "" -#: ../../../CHANGELOG.md:470 +#: ../../../CHANGELOG.md:1124 msgid "This is an alternative to [running Draupnir in bot mode](./docs/configuring-playbook-bot-draupnir.md), which is still supported by the playbook." msgstr "" -#: ../../../CHANGELOG.md:472 +#: ../../../CHANGELOG.md:1126 msgid "The documentation page for [Draupnir for all](./docs/configuring-playbook-appservice-draupnir-for-all.md) contains more information on how to install it." msgstr "" -#: ../../../CHANGELOG.md:475 +#: ../../../CHANGELOG.md:1129 msgid "2024-02-19" msgstr "" -#: ../../../CHANGELOG.md:477 +#: ../../../CHANGELOG.md:1131 msgid "Support for bridging to Facebook/Messenger via the new mautrix-meta bridge" msgstr "" -#: ../../../CHANGELOG.md:479 +#: ../../../CHANGELOG.md:1133 msgid "The [mautrix-facebook](./docs/configuring-playbook-bridge-mautrix-facebook.md) and [mautrix-instagram](./docs/configuring-playbook-bridge-mautrix-instagram.md) bridges are being [superseded by a new bridge](https://github.com/mautrix/facebook/issues/332) — the [mautrix-meta](https://github.com/mautrix/meta) bridge." msgstr "" -#: ../../../CHANGELOG.md:481 +#: ../../../CHANGELOG.md:1135 msgid "The playbook now supports the new mautrix-meta bridge — a single bridge, which can run in different modes and bridge to Messenger (via [Facebook](https://facebook.com/), Facebook over [Tor](https://www.torproject.org/) or via [Messenger](https://messenger.com/)) and [Instagram](https://instagram.com/). The playbook makes this bridge available via 2 separate Ansible roles, allowing you to easily run 2 instances of mautrix-meta, for bridging to both services at the same time." msgstr "" -#: ../../../CHANGELOG.md:483 +#: ../../../CHANGELOG.md:1137 msgid "If you're using mautrix-facebook or mautrix-instagram right now, **you can still continue using the old bridges, but may wish to change to the new bridge implementations**. See:" msgstr "" -#: ../../../CHANGELOG.md:485 +#: ../../../CHANGELOG.md:1139 msgid "[Setting up Instagram bridging via Mautrix Meta](docs/configuring-playbook-bridge-mautrix-meta-instagram.md)" msgstr "" -#: ../../../CHANGELOG.md:487 +#: ../../../CHANGELOG.md:1141 msgid "[Setting up Messenger bridging via Mautrix Meta](docs/configuring-playbook-bridge-mautrix-meta-messenger.md)" msgstr "" -#: ../../../CHANGELOG.md:489 +#: ../../../CHANGELOG.md:1143 msgid "The documentation pages contain more information on how to migrate." msgstr "" -#: ../../../CHANGELOG.md:492 +#: ../../../CHANGELOG.md:1146 msgid "2024-02-14" msgstr "" -#: ../../../CHANGELOG.md:494 +#: ../../../CHANGELOG.md:1148 msgid "Much larger Synapse caches and cache auto-tuning enabled by default" msgstr "" -#: ../../../CHANGELOG.md:496 +#: ../../../CHANGELOG.md:1150 msgid "Thanks to [FSG-Cat](https://github.com/FSG-Cat), the playbook now uses much larger caches and enables Synapse's [cache auto-tuning functionality](https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#caches-and-associated-values). This work and the default values used by the playbook are inspired by [Tom Foster](https://github.com/tcpipuk)'s [Synapse homeserver guide](https://tcpipuk.github.io/synapse/deployment/synapse.html)." msgstr "" -#: ../../../CHANGELOG.md:498 +#: ../../../CHANGELOG.md:1152 msgid "The playbook has always used a very conservative cache factor (`matrix_synapse_caches_global_factor`) value of `0.5`, which may be OK for small and underactive deployments, but is not ideal for larger servers. Paradoxically, a small global cache factor value [does not necessarily decrease RAM usage as a whole](https://github.com/matrix-org/synapse/issues/3939)." msgstr "" -#: ../../../CHANGELOG.md:500 +#: ../../../CHANGELOG.md:1154 msgid "The playbook now uses **a 20x larger cache factor** (currently `10`), adjusts a few other cache-related variables, and **enables cache auto-tuning** via the following variables:" msgstr "" -#: ../../../CHANGELOG.md:502 +#: ../../../CHANGELOG.md:1156 msgid "`matrix_synapse_cache_autotuning_max_cache_memory_usage` — defaults to 1/8 of total RAM with a cap of 2GB; values are specified in bytes" msgstr "" -#: ../../../CHANGELOG.md:503 +#: ../../../CHANGELOG.md:1157 msgid "`matrix_synapse_cache_autotuning_target_cache_memory_usage` — defaults to 1/16 of total RAM with a cap of 1GB; values are specified in bytes" msgstr "" -#: ../../../CHANGELOG.md:504 +#: ../../../CHANGELOG.md:1158 msgid "`matrix_synapse_cache_autotuning_min_cache_ttl` — defaults to `30s`" msgstr "" -#: ../../../CHANGELOG.md:506 +#: ../../../CHANGELOG.md:1160 msgid "These values should be good defaults for most servers, but may change over time as we experiment further." msgstr "" -#: ../../../CHANGELOG.md:508 +#: ../../../CHANGELOG.md:1162 msgid "Refer to our new [Tuning caches and cache autotuning](docs/maintenance-synapse.md#tuning-caches-and-cache-autotuning) documentation section for more details." msgstr "" -#: ../../../CHANGELOG.md:511 +#: ../../../CHANGELOG.md:1165 msgid "2024-01-31" msgstr "" -#: ../../../CHANGELOG.md:513 +#: ../../../CHANGELOG.md:1167 msgid "(Backward-compatibility break) Minor changes necessary for some people serving a static website at the base domain" msgstr "" -#: ../../../CHANGELOG.md:515 +#: ../../../CHANGELOG.md:1169 msgid "This only affects people who are [Serving a static website at the base domain](./docs/configuring-playbook-base-domain-serving.md#serving-a-static-website-at-the-base-domain), but not managing its `index.html` through the playbook." msgstr "" -#: ../../../CHANGELOG.md:517 +#: ../../../CHANGELOG.md:1171 msgid "That is, for people who have `matrix_static_files_file_index_html_enabled: false` in their `vars.yml` configuration, the playbook has a new default behavior. Since the playbook is not managing the `index.html` file, it will default to a more sensible way of handling the base domain — redirecting `https://example.com/` to `https://matrix.example.com/`, instead of serving a 404 page." msgstr "" -#: ../../../CHANGELOG.md:519 +#: ../../../CHANGELOG.md:1173 msgid "If you are managing your static website by yourself (by dropping files into `/matrix/static-files/public` somehow), then you probably don't wish for such redirection to happen. You can disable it by adding `matrix_static_files_container_labels_base_domain_root_path_redirection_enabled: false` to your `vars.yml` configuration file." msgstr "" -#: ../../../CHANGELOG.md:522 +#: ../../../CHANGELOG.md:1176 msgid "2024-01-20" msgstr "" -#: ../../../CHANGELOG.md:524 +#: ../../../CHANGELOG.md:1178 msgid "Support for more efficient (specialized) Synapse workers" msgstr "" -#: ../../../CHANGELOG.md:526 +#: ../../../CHANGELOG.md:1180 msgid "Thanks to [Charles Wright](https://github.com/cvwright) from [FUTO](https://www.futo.org/), the creators of the [Circles app](https://circu.li/), the playbook has [received support](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3100) for load-balancing the Synapse workload via [specialized workers](./docs/configuring-playbook-synapse.md#specialized-workers) which are supposed to work better than our old [generic workers](./docs/configuring-playbook-synapse.md#generic-workers) implementation." msgstr "" -#: ../../../CHANGELOG.md:528 +#: ../../../CHANGELOG.md:1182 msgid "For now, playbook defaults remain unchanged and the `one-of-each` [workers preset](./docs/configuring-playbook-synapse.md#worker-presets) continues being the default. However, the default may change in the future. If you'd like to remain on this preset even if/when the defaults change, consider explicitly adding `matrix_synapse_workers_preset: one-of-each` to your `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:530 +#: ../../../CHANGELOG.md:1184 msgid "Our specialized workers setup is based on recommendations found in [Tom Foster](https://github.com/tcpipuk)'s [Synapse homeserver guide](https://tcpipuk.github.io/synapse/index.html). What's special about our new setup is that we try to parse information out of the request (who the user is; which room is being operated on) and try to forward similar requests to the same worker. As an example, this means that once a worker caches some room information, subsequent requests for the same room will be routed to the same worker (which supposedly still has the room's state cached)." msgstr "" -#: ../../../CHANGELOG.md:532 +#: ../../../CHANGELOG.md:1186 msgid "To get started, refer to our [Specialized workers](./docs/configuring-playbook-synapse.md#specialized-workers) documentation section." msgstr "" -#: ../../../CHANGELOG.md:535 +#: ../../../CHANGELOG.md:1189 msgid "2024-01-17" msgstr "" -#: ../../../CHANGELOG.md:537 +#: ../../../CHANGELOG.md:1191 msgid "Switching to Element's AGPLv3-licensed Synapse release" msgstr "" -#: ../../../CHANGELOG.md:539 +#: ../../../CHANGELOG.md:1193 msgid "A few months ago, the [Element](https://element.io/) company has [announced](https://element.io/blog/element-to-adopt-agplv3/) that their work on the Synapse homeserver would no longer be available under the permissive [Apache-2.0 license](https://www.apache.org/licenses/LICENSE-2.0), but only under:" msgstr "" -#: ../../../CHANGELOG.md:541 +#: ../../../CHANGELOG.md:1195 msgid "the [AGPLv3](https://www.gnu.org/licenses/agpl-3.0.en.html) free-software license — the same license that this Ansible playbook has always used" msgstr "" -#: ../../../CHANGELOG.md:542 +#: ../../../CHANGELOG.md:1196 msgid "a proprietary license, for those wishing for Element to [sell them an exception](https://gnu.org/philosophy/selling-exceptions.html) to the AGPLv3 license" msgstr "" -#: ../../../CHANGELOG.md:544 +#: ../../../CHANGELOG.md:1198 msgid "You can also learn more in [this post](https://matrix.org/blog/2023/11/06/future-of-synapse-dendrite/) by the Matrix Foundation." msgstr "" -#: ../../../CHANGELOG.md:546 +#: ../../../CHANGELOG.md:1200 msgid "The change has [already happened](https://element.io/blog/synapse-now-lives-at-github-com-element-hq-synapse/) and the first Synapse release under the new license is here: [v1.99.0](https://github.com/element-hq/synapse/releases/tag/v1.99.0)." msgstr "" -#: ../../../CHANGELOG.md:548 +#: ../../../CHANGELOG.md:1202 msgid "There is no up-to-date alternative Synapse fork right now and this free-software (AGPLv3-licensed) playbook is definitely not against free-software licenses, so we are now switching to the Element-maintained Synapse release." msgstr "" -#: ../../../CHANGELOG.md:550 +#: ../../../CHANGELOG.md:1204 msgid "**What does this mean to you?**" msgstr "" -#: ../../../CHANGELOG.md:552 +#: ../../../CHANGELOG.md:1206 msgid "For most home users, it doesn't mean anything. Your installation will continue working as it should and you don't need to do anything." msgstr "" -#: ../../../CHANGELOG.md:554 +#: ../../../CHANGELOG.md:1208 msgid "For people building commercial products on top of Synapse, they may have to either buy a license exception from Element (from what we hear, the fee depends on the number of monthly-active users on your instance) or they may need to release all related code as free-software (which is what we've been doing at [etke.cc](https://etke.cc/) ([here](https://gitlab.com/etke.cc)) all along)." msgstr "" -#: ../../../CHANGELOG.md:556 +#: ../../../CHANGELOG.md:1210 msgid "We're no lawyers and this changelog entry does not aim to give you the best legal advice, so please research on your own!" msgstr "" -#: ../../../CHANGELOG.md:558 -msgid "If you'd like to continue using the old Apache-2.0-licensed Synapse (for a while longer anyway), the playbook makes it possible by intruducing a new Ansible variable. You can do it like this:" +#: ../../../CHANGELOG.md:1212 +msgid "If you'd like to continue using the old Apache-2.0-licensed Synapse (for a while longer anyway), the playbook makes it possible by introducing a new Ansible variable. You can do it like this:" msgstr "" -#: ../../../CHANGELOG.md:570 +#: ../../../CHANGELOG.md:1224 msgid "Notes:" msgstr "" -#: ../../../CHANGELOG.md:572 +#: ../../../CHANGELOG.md:1226 msgid "if you had already upgraded Synapse to `v1.99.0` by running this playbook, you will still be able to downgrade to `v1.98.0`, because both releases use the same database schema version (`SCHEMA_COMPAT_VERSION = 83` — see [here for v1.98.0](https://github.com/element-hq/synapse/blob/v1.98.0/synapse/storage/schema/__init__.py#L131-L134) and [here for v1.99.0](https://github.com/element-hq/synapse/blob/v1.99.0/synapse/storage/schema/__init__.py#L137-L140)). More details on Synapse's database schema are available [here](https://element-hq.github.io/synapse/develop/development/database_schema.html). It appears that there are no new database migrations introduced in `v1.99.0`, so going back to the older release is possible. This is not guaranteed to hold true for future Synapse releases, so if you're seeing this early-enough, consider pinning the version and organization before re-running the playbook and getting upgraded to the latest version" msgstr "" -#: ../../../CHANGELOG.md:574 +#: ../../../CHANGELOG.md:1228 msgid "running an outdated homeserver exposes you to security issues and incompatibilities. Only consider doing this as a short-term solution." msgstr "" -#: ../../../CHANGELOG.md:576 +#: ../../../CHANGELOG.md:1230 msgid "2024-01-16" msgstr "" -#: ../../../CHANGELOG.md:578 +#: ../../../CHANGELOG.md:1232 msgid "`Draupnir` has been relicensed to AFL-3.0" msgstr "" -#: ../../../CHANGELOG.md:580 +#: ../../../CHANGELOG.md:1234 msgid "As of [#204](https://github.com/the-draupnir-project/Draupnir/pull/204) Draupnir changed its licence to AFL-3.0 from the CSL licence. This change affects playbook users who could not run Draupnir under the old license restrictions. The new license is considerably less restrictive and is OSI approved. Draupnir version v1.86.0 and later are covered by this license change." msgstr "" -#: ../../../CHANGELOG.md:582 +#: ../../../CHANGELOG.md:1236 msgid "2024-01-15" msgstr "" -#: ../../../CHANGELOG.md:584 +#: ../../../CHANGELOG.md:1238 msgid "Goodbye, `matrix-nginx-proxy` 🪦" msgstr "" -#: ../../../CHANGELOG.md:586 +#: ../../../CHANGELOG.md:1240 msgid "**TLDR**: All traces of the `matrix-nginx-proxy` reverse-proxy component are now gone. This brought about many other internal changes (and security improvements), so setups may need minor adjustments or suffer some (temporary) breakage. People who have been on the Traefik-native setup may upgrade without much issues. Those running their own Traefik instance may need minor changes. People who have been postponing the migration away from `matrix-nginx-proxy` (for more than a year already!) will now finally need to do something about it." msgstr "" -#: ../../../CHANGELOG.md:588 +#: ../../../CHANGELOG.md:1242 msgid "Backstory on `matrix-nginx-proxy`" msgstr "" -#: ../../../CHANGELOG.md:590 +#: ../../../CHANGELOG.md:1244 msgid "We gather here today to celebrate the loss of a once-beloved component in our stack — `matrix-nginx-proxy`. It's been our [nginx](https://nginx.org/)-based reverse-proxy of choice since the [first commit](https://github.com/spantaleev/matrix-docker-ansible-deploy/tree/87f5883f2455fb115457b65f267f17de305c053c) of this playbook, 7 years ago." msgstr "" -#: ../../../CHANGELOG.md:592 +#: ../../../CHANGELOG.md:1246 msgid "For 6 years, `matrix-nginx-proxy` has been the front-most reverse-proxy in our setup (doing SSL termination, etc.). After [transitioning to Traefik last year](#traefik-is-the-default-reverse-proxy-now), `matrix-nginx-proxy` took a step back. Nevertheless, since it was so ingrained into the playbook, it still remained in use — even if only internally. Despite our warnings of its imminent death, many of you have indubitably continued to use it instead of Traefik. Its suffering continued for too long, because it served many different purposes and massive effort was required to transition them to others." msgstr "" -#: ../../../CHANGELOG.md:594 +#: ../../../CHANGELOG.md:1248 msgid "To us, `matrix-nginx-proxy` was:" msgstr "" -#: ../../../CHANGELOG.md:596 +#: ../../../CHANGELOG.md:1250 msgid "an [nginx](https://nginx.org/)-based reverse-proxy" msgstr "" -#: ../../../CHANGELOG.md:597 +#: ../../../CHANGELOG.md:1251 msgid "an Ansible role organizing the work of [certbot](https://certbot.eff.org/) — retrieving free [Let's Encrypt](https://letsencrypt.org/) SSL certificates for `matrix-nginx-proxy` and for the [coturn TURN server](./docs/configuring-playbook-turn.md)" msgstr "" -#: ../../../CHANGELOG.md:598 +#: ../../../CHANGELOG.md:1252 msgid "a central component for reverse-proxying to the [long list of services](./docs/configuring-playbook.md) supported by the playbook. As such, it became a dependency that all these services had to inject themselves into during runtime" msgstr "" -#: ../../../CHANGELOG.md:599 +#: ../../../CHANGELOG.md:1253 msgid "an intermediary through which addons (bridges, bots) communicated with the homeserver. Going through an intermediary (instead of directly talking to the homeserver) is useful when certain components (like [matrix-media-repo](./docs/configuring-playbook-matrix-media-repo.md) or [matrix-corporal](./docs/configuring-playbook-matrix-corporal.md)) are enabled, because it lets these services \"steal routes\" from the homeserver" msgstr "" -#: ../../../CHANGELOG.md:600 +#: ../../../CHANGELOG.md:1254 msgid "a webserver for serving the `/.well-known/matrix` static files (generated by the `matrix-base` role until now)" msgstr "" -#: ../../../CHANGELOG.md:601 +#: ../../../CHANGELOG.md:1255 msgid "a webserver [serving your base domain](./docs/configuring-playbook-base-domain-serving.md) (and also generating the `index.html` page for it)" msgstr "" -#: ../../../CHANGELOG.md:602 +#: ../../../CHANGELOG.md:1256 msgid "a central component providing global [HTTP Basic Auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) password-protection for all `/metrics` endpoints when metrics were exposed publicly for consumption from a remote Prometheus server" msgstr "" -#: ../../../CHANGELOG.md:604 +#: ../../../CHANGELOG.md:1258 msgid "Talk about a jack of all trades! The [UNIX philosophy](https://en.wikipedia.org/wiki/Unix_philosophy) (and Docker container philosophy) of \"do one thing and do it well\" had been severely violated for too long." msgstr "" -#: ../../../CHANGELOG.md:606 +#: ../../../CHANGELOG.md:1260 msgid "On a related note, we also had a large chain of reverse-proxies in the mix. In the worst case, it was something like this: (Traefik -> `matrix-nginx-proxy:8080` -> `matrix-nginx-proxy:12080` -> `matrix-synapse-reverse-proxy-companion:8008` -> `matrix-synapse:8008`)." msgstr "" -#: ../../../CHANGELOG.md:608 +#: ../../../CHANGELOG.md:1262 msgid "Due to complexity and the playbook's flexibility (trying to accommodate a mix of tens of components), many layers of indirection were necessary. We do like reverse-proxies, but… not quite enough to enjoy going through a chain of ~4 of them before reaching the target service." msgstr "" -#: ../../../CHANGELOG.md:610 +#: ../../../CHANGELOG.md:1264 msgid "After **a ton of work** in the last weeks (200+ commits, which changed 467 files - 8684 insertions and 8913 deletions), **we're finally saying goodbye** to `matrix-nginx-proxy`." msgstr "" -#: ../../../CHANGELOG.md:612 +#: ../../../CHANGELOG.md:1266 msgid "Going Traefik-native and cutting out all middlemen" msgstr "" -#: ../../../CHANGELOG.md:614 +#: ../../../CHANGELOG.md:1268 msgid "In our new setup, you'll see the bare minimum number of reverse-proxies." msgstr "" -#: ../../../CHANGELOG.md:616 +#: ../../../CHANGELOG.md:1270 msgid "In most cases, there's only Traefik and all services being registered directly with it. When [Synapse workers](./docs/configuring-playbook-synapse.md#load-balancing-with-workers) are enabled, `matrix-synapse-reverse-proxy-companion` remains as an extra reverse-proxy that requests go through (for load-balancing to the correct Synapse worker), but in all other cases services are exposed directly." msgstr "" -#: ../../../CHANGELOG.md:618 +#: ../../../CHANGELOG.md:1272 msgid "This reduces \"network\" hops (improving performance) and also decreases the number of components (containers). Each Ansible role in our setup is now independent and doesn't need to interact with other roles during runtime." msgstr "" -#: ../../../CHANGELOG.md:620 +#: ../../../CHANGELOG.md:1274 msgid "Traefik now has an extra job" msgstr "" -#: ../../../CHANGELOG.md:622 +#: ../../../CHANGELOG.md:1276 msgid "Previously, **Traefik had a single purpose** — being the main reverse-proxy. It was either front-most (terminating SSL, etc.) or you were [fronting Traefik with your own other reverse-proxy](./docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy). In any case — it had this central (yet decentralized) job." msgstr "" -#: ../../../CHANGELOG.md:624 +#: ../../../CHANGELOG.md:1278 msgid "Now, **Traefik has one more role** — it serves as an intermediary which allows addon services (bridges, bots, etc.) to communicate with the homeserver. As mentioned above, such an intermediary service is not strictly necessary in all kinds of setups, but more complex setups (including [matrix-media-repo](./docs/configuring-playbook-matrix-media-repo.md) or [matrix-corporal](./docs/configuring-playbook-matrix-corporal.md)) benefit from it." msgstr "" -#: ../../../CHANGELOG.md:626 +#: ../../../CHANGELOG.md:1280 msgid "To perform this new role, Traefik now has a new internal [entrypoint](https://doc.traefik.io/traefik/routing/entrypoints/) called `matrix-internal-matrix-client-api`. All homeservers (Conduit, Dendrite, Synapse and even `matrix-synapse-reverse-proxy-companion`) and homeserver-related core services ([matrix-media-repo](./docs/configuring-playbook-matrix-media-repo.md), [matrix-corporal](./docs/configuring-playbook-matrix-corporal.md) and potentially others) register their routes (using [container labels](https://docs.docker.com/config/labels-custom-metadata/)) not only on the public entrypoints (`web-secure`, `matrix-federation`), but also on this new internal entrypoint." msgstr "" -#: ../../../CHANGELOG.md:628 +#: ../../../CHANGELOG.md:1282 msgid "Doing so, services can contact Traefik on this entrypoint's dedicated port (the URL defaults to `http://matrix-traefik:8008`) and reach the homeserver Client-Server API as they expect. Internally, Traefik takes care of the routing to the correct service." msgstr "" -#: ../../../CHANGELOG.md:630 +#: ../../../CHANGELOG.md:1284 msgid "We've also considered keeping it simple and having services talk to the homeserver over the public internet (e.g. `https://matrix.example.com`) thus reusing all existing Traefik routing labels. In this scenario, performance was incredibly poor (e.g. 70 rps, instead of 1400 rps) due to TLS and networking overhead. The need for fast internal communication (via the new internal non-TLS-enabled Traefik entrypoint) is definitely there. In our benchmarks, Traefik even proved more efficient than nginx at doing this: ~1200 rps for Traefik compared to ~900 rps for nginx (out of ~1400 rps when talking to the Synapse homeserver directly)." msgstr "" -#: ../../../CHANGELOG.md:632 +#: ../../../CHANGELOG.md:1286 msgid "Traefik serving this second purpose has a few downsides:" msgstr "" -#: ../../../CHANGELOG.md:634 +#: ../../../CHANGELOG.md:1288 msgid "Traefik becomes a runtime dependency for all homeserver-dependant container services" msgstr "" -#: ../../../CHANGELOG.md:635 +#: ../../../CHANGELOG.md:1289 msgid "all homeserver-dependant services now need to be connected to the `traefik` container network, even if they don't need public internet exposure" msgstr "" -#: ../../../CHANGELOG.md:637 +#: ../../../CHANGELOG.md:1291 msgid "Despite these downsides (which the playbook manages automatically), we believe it's still a good compromise given the amount of complexity it eliminates and the performance benefits it yields. One alternative we've [considered](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3045#issuecomment-1867327001) was adding a new intermediary service (e.g. `matrix-homeserver-proxy` powered by nginx), but this both had much higher complexity (one more component in the mix; duplication of effort to produce nginx-compatible route definitions for it) and slightly worse performance (see above)." msgstr "" -#: ../../../CHANGELOG.md:639 +#: ../../../CHANGELOG.md:1293 msgid "People running the default Traefik setup do not need to do anything to make Traefik take on this extra job. Your Traefik configuration will be updated automatically." msgstr "" -#: ../../../CHANGELOG.md:641 -msgid "**People runnning their own Traefik reverse-proxy need to do [minor adjustments](#people-managing-their-own-traefik-instance-need-to-do-minor-changes)**, as described in the section below." +#: ../../../CHANGELOG.md:1295 +msgid "**People running their own Traefik reverse-proxy need to do [minor adjustments](#people-managing-their-own-traefik-instance-need-to-do-minor-changes)**, as described in the section below." msgstr "" -#: ../../../CHANGELOG.md:643 +#: ../../../CHANGELOG.md:1297 msgid "You may disable Traefik acting as an intermediary by explicitly setting `matrix_playbook_public_matrix_federation_api_traefik_entrypoint_enabled` to `false`. Services would then be configured to talk to the homeserver directly, giving you a slight performance boost and a \"simpler\" Traefik setup. However, such a configuration is less tested and will cause troubles, especially if you enable more services (like `matrix-media-repo`, etc.) in the future. As such, it's not recommended." msgstr "" -#: ../../../CHANGELOG.md:645 +#: ../../../CHANGELOG.md:1299 msgid "People managing their own Traefik instance need to do minor changes" msgstr "" -#: ../../../CHANGELOG.md:647 +#: ../../../CHANGELOG.md:1301 msgid "This section is for people [managing their own Traefik instance on the Matrix server](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-you). Those [using Traefik managed by the playbook](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-the-playbook) don't need to do any changes." msgstr "" -#: ../../../CHANGELOG.md:649 +#: ../../../CHANGELOG.md:1303 msgid "Because [Traefik has an extra job now](#traefik-now-has-an-extra-job), you need to adapt your configuration to add the additional `matrix-internal-matrix-client-api` entrypoint and potentially configure the `matrix_playbook_reverse_proxy_container_network` variable. See the [Traefik managed by you](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-you) documentation section for more details." msgstr "" -#: ../../../CHANGELOG.md:651 +#: ../../../CHANGELOG.md:1305 msgid "People fronting Traefik with another reverse proxy need to do minor changes" msgstr "" -#: ../../../CHANGELOG.md:653 +#: ../../../CHANGELOG.md:1307 msgid "We've already previously mentioned that you need to do some minor [configuration changes related to `traefik_additional_entrypoints_auto`](#backward-compatibility-configuration-changes-required-for-people-fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy)." msgstr "" -#: ../../../CHANGELOG.md:655 +#: ../../../CHANGELOG.md:1309 msgid "If you don't do these changes (switching from `traefik_additional_entrypoints_auto` to multiple other variables), your Traefik setup will not automatically receive the new `matrix-internal-matrix-client-api` Traefik entrypoint and Traefik would not be able to perform [its new duty of connecting addons with the homeserver](#traefik-now-has-an-extra-job)." msgstr "" -#: ../../../CHANGELOG.md:657 +#: ../../../CHANGELOG.md:1311 msgid "Supported reverse proxy types are now fewer" msgstr "" -#: ../../../CHANGELOG.md:659 +#: ../../../CHANGELOG.md:1313 msgid "This section is for people using a more custom reverse-proxy setup — those having `matrix_playbook_reverse_proxy_type` set to a value different than the default (`playbook-managed-traefik`)." msgstr "" -#: ../../../CHANGELOG.md:661 +#: ../../../CHANGELOG.md:1315 msgid "Previously, we allowed you to set `matrix_playbook_reverse_proxy_type` to 7 different values to accommodate various reverse-proxy setups." msgstr "" -#: ../../../CHANGELOG.md:663 +#: ../../../CHANGELOG.md:1317 msgid "The complexity of this is too high, so we only support 3 values right now:" msgstr "" -#: ../../../CHANGELOG.md:665 +#: ../../../CHANGELOG.md:1319 msgid "(the default) `playbook-managed-traefik`, when you're [using Traefik managed by the playbook](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-the-playbook)" msgstr "" -#: ../../../CHANGELOG.md:666 +#: ../../../CHANGELOG.md:1320 msgid "`other-traefik-container`, when you're [managing your own Traefik instance on the Matrix server](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-you)" msgstr "" -#: ../../../CHANGELOG.md:667 +#: ../../../CHANGELOG.md:1321 msgid "`none`, when you wish for [no reverse-proxy integration to be done at all](./docs/configuring-playbook-own-webserver.md#using-no-reverse-proxy-on-the-matrix-side-at-all)" msgstr "" -#: ../../../CHANGELOG.md:669 +#: ../../../CHANGELOG.md:1323 msgid "The `none` value is not recommended and may not work adequately, due to lack of testing and [Traefik's new responsibilities](#traefik-now-has-an-extra-job) in our setup." msgstr "" -#: ../../../CHANGELOG.md:671 +#: ../../../CHANGELOG.md:1325 msgid "**Previous values that are now gone** (and the playbook would report them as such) are: `playbook-managed-nginx`, `other-nginx-non-container`, `other-on-same-host` and `other-on-another-host`." msgstr "" -#: ../../../CHANGELOG.md:673 +#: ../../../CHANGELOG.md:1327 msgid "If you were using these values as a way to stay away from Traefik, you now have 2 options:" msgstr "" -#: ../../../CHANGELOG.md:675 +#: ../../../CHANGELOG.md:1329 msgid "(recommended) [Fronting Traefik with another reverse-proxy](./docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy)" msgstr "" -#: ../../../CHANGELOG.md:676 +#: ../../../CHANGELOG.md:1330 msgid "(not recommended) [Using no reverse-proxy on the Matrix side at all](./docs/configuring-playbook-own-webserver.md#using-no-reverse-proxy-on-the-matrix-side-at-all) and reverse-proxying to each and every service manually" msgstr "" -#: ../../../CHANGELOG.md:678 +#: ../../../CHANGELOG.md:1332 msgid "Container networking changes" msgstr "" -#: ../../../CHANGELOG.md:680 +#: ../../../CHANGELOG.md:1334 msgid "Now that `matrix-nginx-proxy` is not in the mix, it became easier to clear out some other long-overdue technical debt." msgstr "" -#: ../../../CHANGELOG.md:682 -msgid "Since the very beginning of this playbook, all playbook services were connected to a single (shared) `matrix` container network. Later on, some additional container networks appeared, but most services (database, etc.) still remained in the `matrix` container network. This meant that any random container in this network could try to talk (or attack) the Postgres database operating in the same `matrix` network." +#: ../../../CHANGELOG.md:1336 +msgid "Since the very beginning of this playbook, all playbook services were connected to a single (shared) `matrix` container network. Later on, some additional container networks appeared, but most services (database, etc.) still remained in the `matrix` container network. This meant that any random container in this network could try to talk (or attack) the Postgres database operating in the same `matrix` network." msgstr "" -#: ../../../CHANGELOG.md:684 +#: ../../../CHANGELOG.md:1338 msgid "Moving components (especially the database) into other container networks was difficult — it required changes to many other components to ensure correct connectivity." msgstr "" -#: ../../../CHANGELOG.md:686 +#: ../../../CHANGELOG.md:1340 msgid "All the hard work has been done now. We've added much more isolation between services by splitting them up into separate networks (`matrix-homeserver`, `matrix-addons`, `matrix-monitoring`, `matrix-exim-relay`, etc). Components are only joined to the networks they need and should (for the most part) not be able to access unrelated things." msgstr "" -#: ../../../CHANGELOG.md:688 +#: ../../../CHANGELOG.md:1342 msgid "Carrying out these container networking changes necessitated modifying many components, so **we're hoping not too many bugs were introduced in the process**." msgstr "" -#: ../../../CHANGELOG.md:690 +#: ../../../CHANGELOG.md:1344 msgid "We've refrained from creating too many container networks (e.g. one for each component), to avoid exhausting Docker's default network pool and contaminating the container networks list too much." msgstr "" -#: ../../../CHANGELOG.md:692 +#: ../../../CHANGELOG.md:1346 msgid "Metrics exposure changes" msgstr "" -#: ../../../CHANGELOG.md:694 +#: ../../../CHANGELOG.md:1348 msgid "This section is for people who are exposing monitoring metrics publicly, to be consumed by an external Prometheus server." msgstr "" -#: ../../../CHANGELOG.md:696 +#: ../../../CHANGELOG.md:1350 msgid "Previously, `matrix-nginx-proxy` was potentially password-protecting all `/metrics/*` endpoints with the same username and password (specified as plain-text in your `vars.yml` configuration file)." msgstr "" -#: ../../../CHANGELOG.md:698 +#: ../../../CHANGELOG.md:1352 msgid "From now on, there are new variables for doing roughly the same — `matrix_metrics_exposure_enabled`, `matrix_metrics_exposure_http_basic_auth_enabled` and `matrix_metrics_exposure_http_basic_auth_users`. See the [Prometheus & Grafana](./docs/configuring-playbook-prometheus-grafana.md) docs page for details." msgstr "" -#: ../../../CHANGELOG.md:700 +#: ../../../CHANGELOG.md:1354 msgid "`matrix-nginx-proxy` is not acting as a \"global guardian\" anymore. Now, each role provides its own metrics exposure and protection by registering with Traefik. Nevertheless, all roles are wired (via playbook configuration in `group_vars/matrix_servers`) to obey these new `matrix_metrics_exposure_*` variables. We've eliminated the centralization, but have kept the ease of use. Now, you can also do per-service password-protection (with different credentials), should you need to do that for some reason." msgstr "" -#: ../../../CHANGELOG.md:702 +#: ../../../CHANGELOG.md:1356 msgid "The playbook will tell you about all variables that you need to migrate during runtime, so rest assured — you shouldn't be able to miss anything!" msgstr "" -#: ../../../CHANGELOG.md:704 +#: ../../../CHANGELOG.md:1358 msgid "Matrix static files" msgstr "" -#: ../../../CHANGELOG.md:706 +#: ../../../CHANGELOG.md:1360 msgid "As mentioned above, static files like `/.well-known/matrix/*` or your base domain's `index.html` file (when [serving the base domain via the Matrix server](./docs/configuring-playbook-base-domain-serving.md) was enabled) were generated by the `matrix-base` or `matrix-nginx-proxy` roles and put into a `/matrix/static-files` directory on the server. Then `matrix-nginx-proxy` was serving all these static files." msgstr "" -#: ../../../CHANGELOG.md:708 +#: ../../../CHANGELOG.md:1362 msgid "All of this has been extracted into a new `matrix-static-files` Ansible role that's part of the playbook. The static files generated by this new role still live at roughly the same place (`/matrix/static-files/public` directory, instead of `/matrix/static-files`)." msgstr "" -#: ../../../CHANGELOG.md:710 +#: ../../../CHANGELOG.md:1364 msgid "The playbook will migrate and update the `/.well-known/matrix/*` files automatically but not your own files in `nginx-proxy/data/matrix-domain/` you will need to back these up yourself otherwise they will be lost. It will also warn you about usage of old variable names, so you can adapt to the new names." msgstr "" -#: ../../../CHANGELOG.md:712 +#: ../../../CHANGELOG.md:1366 msgid "A note on performance" msgstr "" -#: ../../../CHANGELOG.md:714 +#: ../../../CHANGELOG.md:1368 msgid "Some of you have been voicing their concerns (for a long time) about Traefik being too slow and nginx being better." msgstr "" -#: ../../../CHANGELOG.md:716 +#: ../../../CHANGELOG.md:1370 msgid "Some online benchmarks support this by demonstrating slightly higher SSL-termination performance in favor of nginx. The upcoming Traefik v3 release is [said to](https://medium.com/beyn-technology/is-nginx-dead-is-traefik-v3-20-faster-than-traefik-v2-f28ffb7eed3e) improve Traefik's SSL performance by some 20%, but that still ends up being somewhat slower than nginx." msgstr "" -#: ../../../CHANGELOG.md:718 +#: ../../../CHANGELOG.md:1372 msgid "We believe that using Traefik provides way too many benefits to worry about this minor performance impairment." msgstr "" -#: ../../../CHANGELOG.md:720 +#: ../../../CHANGELOG.md:1374 msgid "The heaviest part of running a Matrix homeserver is all the slow and potentially inefficient things the homeserver (e.g. Synapse) is doing. These things affect performance much more than whatever reverse-proxy is in front. Your server will die the same way by joining the famously large **Matrix HQ** room, no matter which reverse-proxy you put in front." msgstr "" -#: ../../../CHANGELOG.md:722 +#: ../../../CHANGELOG.md:1376 msgid "Even our previously mentioned benchmarks (yielding ~1300 rps) are synthetic — hitting a useless `/_matrix/client/versions` endpoint. Real-use does much more than this." msgstr "" -#: ../../../CHANGELOG.md:724 +#: ../../../CHANGELOG.md:1378 msgid "If this is still not convincing enough for you and you want the best possible performance, consider [Fronting Traefik with another reverse-proxy](./docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy) (thus having the slowest part — SSL termination — happen elsewhere) or [Using no reverse-proxy on the Matrix side at all](./docs/configuring-playbook-own-webserver.md#using-no-reverse-proxy-on-the-matrix-side-at-all). The playbook will not get in your way of doing that, but these options may make your life much harder. Performance comes at a cost, after all." msgstr "" -#: ../../../CHANGELOG.md:726 +#: ../../../CHANGELOG.md:1380 msgid "Migration procedure" msgstr "" -#: ../../../CHANGELOG.md:728 +#: ../../../CHANGELOG.md:1382 msgid "The updated playbook will automatically perform some migration tasks for you:" msgstr "" -#: ../../../CHANGELOG.md:730 +#: ../../../CHANGELOG.md:1384 msgid "It will stop and remove the `matrix-nginx-proxy` systemd service and container for you. This behavior cannot be disabled. It's essential that this service gets stopped, because it remaining running (and having container labels) may confuse Traefik as to where to route HTTP requests." msgstr "" -#: ../../../CHANGELOG.md:732 +#: ../../../CHANGELOG.md:1386 msgid "It will delete the `/matrix/nginx-proxy` directory and all files within it. You can disable this behavior by adding `matrix_playbook_migration_matrix_nginx_proxy_uninstallation_enabled: false` to your `vars.yml` configuration file. Doing so will leave its data around." msgstr "" -#: ../../../CHANGELOG.md:734 +#: ../../../CHANGELOG.md:1388 msgid "It will delete the `/matrix/ssl` directory and all files within it. You can disable this behavior by adding `matrix_playbook_migration_matrix_ssl_uninstallation_enabled: false` to your `vars.yml` configuration file. If you have some important certificates there for some reason, take them out or temporarily disable removal of these files until you do." msgstr "" -#: ../../../CHANGELOG.md:736 +#: ../../../CHANGELOG.md:1390 msgid "It will tell you about all variables (`matrix_nginx_proxy_*` and many others — even from other roles) that have changed during this large nginx-elimination upgrade. You can disable this behavior by adding `matrix_playbook_migration_matrix_nginx_proxy_elimination_variable_transition_checks_enabled: false` to your `vars.yml` configuration file." msgstr "" -#: ../../../CHANGELOG.md:738 +#: ../../../CHANGELOG.md:1392 msgid "It will tell you about any leftover `matrix_nginx_proxy_*` variables in your `vars.yml` file. You can disable this behavior by adding `matrix_playbook_migration_matrix_nginx_proxy_leftover_variable_validation_checks_enabled: false` to your `vars.yml` configuration file." msgstr "" -#: ../../../CHANGELOG.md:740 +#: ../../../CHANGELOG.md:1394 msgid "It will tell you about any leftover `matrix_ssl_*` variables in your `vars.yml` file. You can disable this behavior by adding `matrix_playbook_migration_matrix_ssl_leftover_variable_checks_enabled: false` to your `vars.yml` configuration file." msgstr "" -#: ../../../CHANGELOG.md:742 +#: ../../../CHANGELOG.md:1396 msgid "We don't recommend changing these variables and suppressing warnings, unless you know what you're doing." msgstr "" -#: ../../../CHANGELOG.md:744 +#: ../../../CHANGELOG.md:1398 msgid "**Most people should just upgrade as per-normal**, bearing in mind that a lot has changed and some issues may arise. The playbook would guide you through renamed variables automatically." msgstr "" -#: ../../../CHANGELOG.md:746 +#: ../../../CHANGELOG.md:1400 msgid "Conclusion" msgstr "" -#: ../../../CHANGELOG.md:748 +#: ../../../CHANGELOG.md:1402 msgid "Thousands of lines of code were changed across hundreds of files. All addons (bridges, bots) were rewired in terms of container networking and in terms of how they reach the homeserver." msgstr "" -#: ../../../CHANGELOG.md:750 +#: ../../../CHANGELOG.md:1404 msgid "I don't actively use all the ~100 components offered by the playbook (no one does), nor do I operate servers exercising all edge-cases. As such, issues may arise. Please have patience and report (or try to fix) these issues!" msgstr "" -#: ../../../CHANGELOG.md:753 +#: ../../../CHANGELOG.md:1407 msgid "2024-01-14" msgstr "" -#: ../../../CHANGELOG.md:755 +#: ../../../CHANGELOG.md:1409 msgid "(Backward Compatibility) Configuration changes required for people fronting the integrated reverse-proxy webserver with another reverse-proxy" msgstr "" -#: ../../../CHANGELOG.md:757 +#: ../../../CHANGELOG.md:1411 msgid "If you're on the default setup (using the Traefik reverse-proxy as installed by the playbook), you don't need to do anything." msgstr "" -#: ../../../CHANGELOG.md:759 +#: ../../../CHANGELOG.md:1413 msgid "People who are [Fronting the integrated Traefik reverse-proxy webserver with another reverse-proxy](./docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy), as per our previous instructions are redefining `traefik_additional_entrypoints_auto` in their `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:761 +#: ../../../CHANGELOG.md:1415 msgid "Such a full variable redefinion is intrustive, because it prevents the playbook from injecting additional entrypoints into the Traefik webserver. In the future, the playbook may have a need to do so." msgstr "" -#: ../../../CHANGELOG.md:763 +#: ../../../CHANGELOG.md:1417 msgid "For this reason, we no longer recommend completely redefining `traefik_additional_entrypoints_auto`. The playbook now defines [various `matrix_playbook_public_matrix_federation_api_traefik_entrypoint_*` variables in the `defaults/main.yml` file](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/roles/custom/matrix-base/defaults/main.yml) of the `matrix-base` role which can be used as a safer alternative to `traefik_additional_entrypoints_auto`." msgstr "" -#: ../../../CHANGELOG.md:765 +#: ../../../CHANGELOG.md:1419 msgid "Adapt your configuration as seen below:" msgstr "" -#: ../../../CHANGELOG.md:798 +#: ../../../CHANGELOG.md:1452 msgid "Also, feel free to read the [Fronting the integrated Traefik reverse-proxy webserver with another reverse-proxy](./docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy) documentation section again for additional details." msgstr "" -#: ../../../CHANGELOG.md:801 +#: ../../../CHANGELOG.md:1455 msgid "2024-01-13" msgstr "" -#: ../../../CHANGELOG.md:803 +#: ../../../CHANGELOG.md:1457 msgid "matrix-reminder-bot update with more secure (backward-incompatible) default settings" msgstr "" -#: ../../../CHANGELOG.md:805 +#: ../../../CHANGELOG.md:1459 msgid "**TLDR**: your updated (to [v0.3.0](https://github.com/anoadragon453/matrix-reminder-bot/releases/tag/v0.3.0)) [matrix-reminder-bot](./docs/configuring-playbook-bot-matrix-reminder-bot.md) is now more secure. By default, like other bridges/bots managed by the playbook, it will only provide its services to users of your own server (not to anyone, even across the Matrix Federation). If that's fine, there's nothing you need to do." msgstr "" -#: ../../../CHANGELOG.md:807 +#: ../../../CHANGELOG.md:1461 msgid "Maintenance of [matrix-reminder-bot](./docs/configuring-playbook-bot-matrix-reminder-bot.md) has been picked up by [Kim Brose](https://github.com/HarHarLinks) and [@svierne](https://github.com/svierne)." msgstr "" -#: ../../../CHANGELOG.md:809 +#: ../../../CHANGELOG.md:1463 msgid "Thanks to them, a new [v0.3.0](https://github.com/anoadragon453/matrix-reminder-bot/releases/tag/v0.3.0) release is out. The new version is now available for the ARM64 architecture, so playbook users on this architecture will no longer need to wait for [self-building](./docs/self-building.md) to happen." msgstr "" -#: ../../../CHANGELOG.md:811 +#: ../../../CHANGELOG.md:1465 msgid "The new version also comes with new `allowlist` and `blocklist` settings, which make it possible to restrict who can use the bot. Previously anyone, even across the Matrix Federation could talk to it and schedule reminders." msgstr "" -#: ../../../CHANGELOG.md:813 +#: ../../../CHANGELOG.md:1467 msgid "The playbook defaults all bridges and bots (where possible) to only be exposed to users of the current homeserver, not users across federation. Thanks to the new version of this bot making such a restriction possible, we're now making use of it. The playbook (via its `group_vars/matrix_servers` file) automatically enables the `allowlist` (`matrix_bot_matrix_reminder_bot_allowlist_enabled: true`) and configures it in such a way (`matrix_bot_matrix_reminder_bot_allowlist_regexes_auto`) so as to restrict the bot to your homeserver's users." msgstr "" -#: ../../../CHANGELOG.md:815 +#: ../../../CHANGELOG.md:1469 msgid "If you need **to undo or tweak these security improvements**, you can change your `vars.yml` file to:" msgstr "" -#: ../../../CHANGELOG.md:817 +#: ../../../CHANGELOG.md:1471 msgid "disable the allowlist (`matrix_bot_matrix_reminder_bot_allowlist_enabled: false`), making the bot allow usage by anyone, anywhere" msgstr "" -#: ../../../CHANGELOG.md:819 +#: ../../../CHANGELOG.md:1473 msgid "inject additional allowed servers or users by adding **additional** (on top of the default allowlist in `matrix_bot_matrix_reminder_bot_allowlist_regexes_auto`) custom regexes in the `matrix_bot_matrix_reminder_bot_allowlist_regexes_custom` list variable (see the [syntax reference](https://github.com/anoadragon453/matrix-reminder-bot/blob/1e910c0aa3469d280d93ee7e6c6d577227a3460c/sample.config.yaml#L43-L49))" msgstr "" -#: ../../../CHANGELOG.md:821 +#: ../../../CHANGELOG.md:1475 msgid "override the default allowlist (in the `group_vars/matrix_servers` file) by redefining `matrix_bot_matrix_reminder_bot_allowlist_regexes_auto`" msgstr "" -#: ../../../CHANGELOG.md:824 +#: ../../../CHANGELOG.md:1478 msgid "2024-01-05" msgstr "" -#: ../../../CHANGELOG.md:826 +#: ../../../CHANGELOG.md:1480 msgid "matrix-mailer has been replaced by the exim-relay external role" msgstr "" -#: ../../../CHANGELOG.md:828 ../../../CHANGELOG.md:1468 +#: ../../../CHANGELOG.md:1482 ../../../CHANGELOG.md:2120 msgid "We're continuing our effort to make [the playbook use external roles for some things](#the-playbook-now-uses-external-roles-for-some-things), so as to avoid doing everything ourselves and to facilitate code re-use." msgstr "" -#: ../../../CHANGELOG.md:830 +#: ../../../CHANGELOG.md:1484 msgid "The `matrix-mailer` role has been moved to its own repository ([ansible-role-exim-relay](https://github.com/mother-of-all-self-hosting/ansible-role-exim-relay)) that this playbook now includes." msgstr "" -#: ../../../CHANGELOG.md:832 +#: ../../../CHANGELOG.md:1486 msgid "To migrate:" msgstr "" -#: ../../../CHANGELOG.md:834 +#: ../../../CHANGELOG.md:1488 msgid "pull the playbook changes, as usual" msgstr "" -#: ../../../CHANGELOG.md:835 +#: ../../../CHANGELOG.md:1489 msgid "update your roles (run `just roles` or `make roles`)" msgstr "" -#: ../../../CHANGELOG.md:836 +#: ../../../CHANGELOG.md:1490 msgid "update your `vars.yml`, renaming `matrix_mailer`-prefixed variables to `exim_relay`-prefixed ones (e.g. `matrix_mailer_sender_address` -> `exim_relay_sender_address`). If you find none, it means you're using the default configuration and your migraiton job is even simpler." msgstr "" -#: ../../../CHANGELOG.md:837 +#: ../../../CHANGELOG.md:1491 msgid "re-run the playbook (`install-all` or `setup-all`)" msgstr "" -#: ../../../CHANGELOG.md:839 +#: ../../../CHANGELOG.md:1493 msgid "The playbook will take care of stopping the old `matrix-mailer` systemd service, relocating its directory and restarting it under the new name (`matrix-exim-relay.service`)." msgstr "" -#: ../../../CHANGELOG.md:842 +#: ../../../CHANGELOG.md:1496 msgid "2024-01-02" msgstr "" -#: ../../../CHANGELOG.md:844 +#: ../../../CHANGELOG.md:1498 msgid "mautrix-signal now powered by the new Go-based bridge" msgstr "" -#: ../../../CHANGELOG.md:846 +#: ../../../CHANGELOG.md:1500 msgid "The old Python-based [mautrix-signal](https://github.com/mautrix/signal) bridge is no longer maintained upstream. It's also known to have issues linking new devices." msgstr "" -#: ../../../CHANGELOG.md:848 +#: ../../../CHANGELOG.md:1502 msgid "It seems like the path forward is to switch to the new mautrix-signal bridge written in Golang, which we did thanks to [PR #3031](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3041) by [Pierre 'McFly' Marty](https://github.com/pm-McFly)." msgstr "" -#: ../../../CHANGELOG.md:850 +#: ../../../CHANGELOG.md:1504 msgid "The playbook should **automatically migrate your mautrix-signal installation to the new bridge code**. You will **need to relink all your devices** to continue your bridged conversations." msgstr "" -#: ../../../CHANGELOG.md:853 +#: ../../../CHANGELOG.md:1507 msgid "2023-10-23" msgstr "" -#: ../../../CHANGELOG.md:855 +#: ../../../CHANGELOG.md:1509 msgid "Enabling `allow_public_rooms_over_federation` by default for Synapse" msgstr "" -#: ../../../CHANGELOG.md:857 +#: ../../../CHANGELOG.md:1511 msgid "**TDLR**: if your Matrix server is federating (which it mostly likely is, unless you've [disabled federation](docs/configuring-playbook-federation.md#disabling-federation)), your public rooms will not only be joinable across federation (as they've always been), but from now on will be discoverable (made available as a list across federation). We're changing this by flipping the value for Synapse's `allow_public_rooms_over_federation` setting to `true`, going against the upstream default. Servers that disable federation are not affected. Servers that have public rooms which are not published to the room directory are also not affected." msgstr "" -#: ../../../CHANGELOG.md:859 +#: ../../../CHANGELOG.md:1513 msgid "We generally try to stick to the default configuration for Synapse (and all other components), unless these defaults seem wrong or harmful. One such previous case from a few months ago was us [Enabling `forget_rooms_on_leave` by default for Synapse](#enabling-forget_rooms_on_leave-by-default-for-synapse) — the default value was making Synapse more wasteful of resources by default." msgstr "" -#: ../../../CHANGELOG.md:861 +#: ../../../CHANGELOG.md:1515 msgid "Today, we're going against upstream defaults again and flipping the `allow_public_rooms_over_federation` configuration option to `true`. This way, public rooms on your server will be made discoverable by others via federation, using the [`GET /_matrix/federation/v1/publicRooms` of the Server-Server API](https://spec.matrix.org/v1.8/server-server-api/#get_matrixfederationv1publicrooms)." msgstr "" -#: ../../../CHANGELOG.md:863 +#: ../../../CHANGELOG.md:1517 msgid "The upstream Synapse default is `false` (disabled), so that public rooms are not exposed for other servers to discover (learn about their existence). Nevertheless, even if these rooms are not exposed (listed) for discovery, they are **still joinable** by anyone who knows their address or is invited to the room by an existing member." msgstr "" -#: ../../../CHANGELOG.md:865 +#: ../../../CHANGELOG.md:1519 msgid "**We go against the upstream default** in an effort to make Matrix federation more useful — a public room should be globally public — not only joinable, but also discoverable across federation." msgstr "" -#: ../../../CHANGELOG.md:867 +#: ../../../CHANGELOG.md:1521 msgid "The **historical reasoning** behind this change is as follows:" msgstr "" -#: ../../../CHANGELOG.md:869 +#: ../../../CHANGELOG.md:1523 msgid "`allow_public_rooms_over_federation` seems to have been enabled by default for Synapse until v1.7.0 (~2019), just like we believe it should be for a globally-federating network — rooms should be joinable and discoverable across federation." msgstr "" -#: ../../../CHANGELOG.md:871 +#: ../../../CHANGELOG.md:1525 msgid "In Synapse v1.7.0 (~2019), `allow_public_rooms_over_federation` [got disabled](https://github.com/element-hq/synapse/blob/e9069c9f919685606506f04527332e83fbfa44d9/docs/upgrade.md?plain=1#L1877-L1891) by default in a [security-by-obscurity](https://en.wikipedia.org/wiki/Security_through_obscurity) workaround for misconfigured servers. See the [Avoiding unwelcome visitors on private Matrix servers](https://matrix.org/blog/2019/11/09/avoiding-unwelcome-visitors-on-private-matrix-servers/) `matrix.org` blog article. We believe that people wishing for a truly private server, should [disable federation](docs/configuring-playbook-federation.md#disabling-federation), instead of having a fully-federating server and trying to hide its public rooms. We also provide other workarounds below. We (and the Synapse team, obviously) believe that Matrix should federate by default, so federating the public room list seems to make sense." msgstr "" -#: ../../../CHANGELOG.md:873 +#: ../../../CHANGELOG.md:1527 #, python-format msgid "[etke.cc](https://etke.cc/) has been developing the free-software [Matrix Rooms Search](https://github.com/etkecc/mrs) project for a while now. One public (demo) instance of it is hosted at [matrixrooms.info](https://matrixrooms.info/). This search engine tries to go through the Matrix federation and discover & index public rooms to allow people to find them. We believe it's vital for Matrix (and any chat or social network for that matter) to be more discoverable, so that people can find communities and others to talk to. Today (on 23rd of October 2023), `matrixrooms.info` is indexing `23066` Matrix servers. Of these, only `1567` servers (7%) are making their public rooms discoverable. Who knows what wonderful communities and rooms are available on these 93% other Matrix servers that are supposedly federating, but are still gate-keeping their public room list. Indubitably, many of these servers are hosted via matrix-docker-ansible-deploy, so we feel partially responsible for making Matrix federation less useful." msgstr "" -#: ../../../CHANGELOG.md:875 +#: ../../../CHANGELOG.md:1529 msgid "Here are **actions you may wish to take** as a result of this change:" msgstr "" -#: ../../../CHANGELOG.md:877 +#: ../../../CHANGELOG.md:1531 msgid "(recommended) embrace the new default. If your Matrix server is federating, your public rooms have always been joinable across federation anyway. Exposing the list of public rooms does no harm and more-so does good by contributing to the usefulness of the Matrix network by facilitating room discovery." msgstr "" -#: ../../../CHANGELOG.md:879 +#: ../../../CHANGELOG.md:1533 msgid "(switch to a better way of doings things on your semi-private server) The problem that the Synapse team appears to have solved by flipping the `allow_public_rooms_over_federation` default in Synapse v1.7.0 seems to for \"mostly private\" servers, which federate and have a bunch of rooms made public (and published in their room directory) in an effort to allow people on the same homeserver to easily find and join them (self-onboarding). With the introduction of Matrix Spaces, you can reorganize your flow around spaces — you can auto-join your users to a Matrix Space (via Synapse's `auto_join_rooms` setting — controlled by our `matrix_synapse_auto_join_rooms` variable), then add a bunch of rooms to the space and make them joinable by people belonging to the space. That is to say, do not make rooms public and do not publish them to the room directory unless they are really public. Instead, use other mechanisms for semi-public rooms or private rooms. One alternative is to stick to what you're doing (public rooms published to your rooms directory) but having a `m.federate: true` flag set during creation (clients like Element Web have a nice UI checkbox for this) to explicitly disable federation for them." msgstr "" -#: ../../../CHANGELOG.md:881 +#: ../../../CHANGELOG.md:1535 msgid "(keeping the old behavior) if you wish to keep doing what you're doing (keeping your Matrix server federating, but hiding its public rooms list), add `matrix_synapse_allow_public_rooms_over_federation: false` to your `vars.yml` configuration. This restores the old behavior. You may also consider [disabling federation](docs/configuring-playbook-federation.md#disabling-federation) completely instead of relying on security-by-obscurity measures." msgstr "" -#: ../../../CHANGELOG.md:884 +#: ../../../CHANGELOG.md:1538 msgid "2023-10-18" msgstr "" -#: ../../../CHANGELOG.md:886 +#: ../../../CHANGELOG.md:1540 msgid "Postgres parameters are automatically tuned now" msgstr "" -#: ../../../CHANGELOG.md:888 +#: ../../../CHANGELOG.md:1542 msgid "The playbook has provided some hints about [Tuning PostgreSQL](docs/maintenance-postgres.md#tuning-postgresql) for quite a while now." msgstr "" -#: ../../../CHANGELOG.md:890 +#: ../../../CHANGELOG.md:1544 msgid "From now on, the [Postgres Ansible role](https://github.com/mother-of-all-self-hosting/ansible-role-postgres) automatically tunes your Postgres configuration with the same [calculation logic](https://github.com/le0pard/pgtune/blob/master/src/features/configuration/configurationSlice.js) that powers https://pgtune.leopard.in.ua/." msgstr "" -#: ../../../CHANGELOG.md:892 +#: ../../../CHANGELOG.md:1546 msgid "Our [Tuning PostgreSQL](docs/maintenance-postgres.md#tuning-postgresql) documentation page has details about how you can turn auto-tuning off or adjust the automatically-determined Postgres configuration parameters manually." msgstr "" -#: ../../../CHANGELOG.md:894 +#: ../../../CHANGELOG.md:1548 msgid "People who [enable load-balancing with Synapse workers](docs/configuring-playbook-synapse.md#load-balancing-with-workers) no longer need to increase the maximum number of Postgres connections manually (previously done via `postgres_process_extra_arguments`). There's a new variable (`postgres_max_connections`) for controlling this number and the playbook automatically raises its value from `200` to `500` for setups which enable workers." msgstr "" -#: ../../../CHANGELOG.md:897 +#: ../../../CHANGELOG.md:1551 msgid "2023-08-31" msgstr "" -#: ../../../CHANGELOG.md:899 +#: ../../../CHANGELOG.md:1553 msgid "SchildiChat Web support" msgstr "" -#: ../../../CHANGELOG.md:901 +#: ../../../CHANGELOG.md:1555 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up the [SchildiChat Web](https://github.com/SchildiChat/schildichat-desktop) client." msgstr "" -#: ../../../CHANGELOG.md:903 +#: ../../../CHANGELOG.md:1557 msgid "See our [Configuring SchildiChat Web](docs/configuring-playbook-client-schildichat-web.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:906 +#: ../../../CHANGELOG.md:1560 msgid "2023-08-23" msgstr "" -#: ../../../CHANGELOG.md:908 +#: ../../../CHANGELOG.md:1562 msgid "mautrix-wsproxy support" msgstr "" -#: ../../../CHANGELOG.md:910 +#: ../../../CHANGELOG.md:1564 msgid "Thanks to [Johan Swetzén](https://github.com/jswetzen)'s efforts (who finished what was started by [James Reilly](https://github.com/hanthor) and [Shreyas Ajjarapu](https://github.com/shreyasajj)), the playbook now supports bridging to Android SMS and Apple iMessage via the [mautrix-wsproxy](https://github.com/mautrix/wsproxy) service (in combination with a [mautrix-imessage](https://github.com/mautrix/imessage) bridge running on your Mac or Android phone)." msgstr "" -#: ../../../CHANGELOG.md:912 +#: ../../../CHANGELOG.md:1566 msgid "See our [Setting up Mautrix wsproxy for bridging Android SMS or Apple iMessage](docs/configuring-playbook-bridge-mautrix-wsproxy.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:915 +#: ../../../CHANGELOG.md:1569 msgid "2023-07-24" msgstr "" -#: ../../../CHANGELOG.md:917 +#: ../../../CHANGELOG.md:1571 msgid "matrix-registration-bot usage changed" msgstr "" -#: ../../../CHANGELOG.md:919 +#: ../../../CHANGELOG.md:1573 msgid "[matrix-registration-bot](docs/configuring-playbook-bot-matrix-registration-bot.md) got some updates and now supports password-only-based login. Therefore the bot now doesn't need any manual configuration except setting a password in your `vars.yml`. The bot will be registered as admin and access tokens will be obtained automatically by the bot." msgstr "" -#: ../../../CHANGELOG.md:921 +#: ../../../CHANGELOG.md:1575 msgid "**For existing users** You need to set `matrix_bot_matrix_registration_bot_bot_password` if you previously only used `matrix_bot_matrix_registration_bot_bot_access_token`. Please also remove the following deprecated settings" msgstr "" -#: ../../../CHANGELOG.md:923 +#: ../../../CHANGELOG.md:1577 msgid "`matrix_bot_matrix_registration_bot_bot_access_token`" msgstr "" -#: ../../../CHANGELOG.md:924 +#: ../../../CHANGELOG.md:1578 msgid "`matrix_bot_matrix_registration_bot_api_token`" msgstr "" -#: ../../../CHANGELOG.md:927 +#: ../../../CHANGELOG.md:1581 msgid "2023-07-21" msgstr "" -#: ../../../CHANGELOG.md:929 +#: ../../../CHANGELOG.md:1583 msgid "mautrix-gmessages support" msgstr "" -#: ../../../CHANGELOG.md:931 +#: ../../../CHANGELOG.md:1585 msgid "Thanks to [Shreyas Ajjarapu](https://github.com/shreyasajj)'s efforts, the playbook now supports bridging to [Google Messages](https://messages.google.com/) via the [mautrix-gmessages](https://github.com/mautrix/gmessages) bridge. See our [Setting up Mautrix Google Messages bridging](docs/configuring-playbook-bridge-mautrix-gmessages.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:934 +#: ../../../CHANGELOG.md:1588 msgid "2023-07-17" msgstr "" -#: ../../../CHANGELOG.md:936 +#: ../../../CHANGELOG.md:1590 msgid "matrix-media-repo support" msgstr "" -#: ../../../CHANGELOG.md:938 +#: ../../../CHANGELOG.md:1592 msgid "Thanks to [Michael Hollister](https://github.com/Michael-Hollister) from [FUTO](https://www.futo.org/), the creators of the [Circles app](https://circu.li/), the playbook can now set up [matrix-media-repo](https://github.com/turt2live/matrix-media-repo) — an alternative way to store homeserver media files, powered by a homeserver-independent implementation which supports S3 storage, IPFS, deduplication and other advanced features." msgstr "" -#: ../../../CHANGELOG.md:940 +#: ../../../CHANGELOG.md:1594 msgid "To learn more see our [Storing Matrix media files using matrix-media-repo](docs/configuring-playbook-matrix-media-repo.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:943 +#: ../../../CHANGELOG.md:1597 msgid "2023-05-25" msgstr "" -#: ../../../CHANGELOG.md:945 +#: ../../../CHANGELOG.md:1599 msgid "Enabling `forget_rooms_on_leave` by default for Synapse" msgstr "" -#: ../../../CHANGELOG.md:947 +#: ../../../CHANGELOG.md:1601 msgid "With the [Synapse v1.84.0 update](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2698), we've also **changed the default value** of the `forget_rooms_on_leave` setting of Synapse to a value of `true`. This way, **when you leave a room, Synapse will now forget it automatically**." msgstr "" -#: ../../../CHANGELOG.md:949 +#: ../../../CHANGELOG.md:1603 msgid "The upstream Synapse default is `false` (disabled), so that you must forget rooms manually after leaving." msgstr "" -#: ../../../CHANGELOG.md:951 +#: ../../../CHANGELOG.md:1605 msgid "**We go against the upstream default** ([somewhat controversially](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2700)) in an effort to make Synapse leaner and potentially do what we believe most users would expect their homeserver to be doing." msgstr "" -#: ../../../CHANGELOG.md:953 +#: ../../../CHANGELOG.md:1607 msgid "If you'd like to go back to the old behavior, add the following to your configuration: `matrix_synapse_forget_rooms_on_leave: false`" msgstr "" -#: ../../../CHANGELOG.md:956 +#: ../../../CHANGELOG.md:1610 msgid "2023-04-03" msgstr "" -#: ../../../CHANGELOG.md:958 +#: ../../../CHANGELOG.md:1612 msgid "The matrix-jitsi role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:960 +#: ../../../CHANGELOG.md:1614 msgid "**TLDR**: the `matrix-jitsi` role is now included from the [ansible-role-jitsi](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi) repository, part of the [MASH playbook](https://github.com/mother-of-all-self-hosting/mash-playbook). Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:962 +#: ../../../CHANGELOG.md:1616 msgid "The `matrix-jitsi` role has been relocated in its own repository, part of the [MASH playbook](https://github.com/mother-of-all-self-hosting/mash-playbook) project — an Ansible playbook for self-hosting [a growing list of FOSS software](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md). If hosting a Jitsi stack on the Matrix server itself did not stand right with you or you always wanted to host most stuff, you can now use this new playbook to do so." msgstr "" -#: ../../../CHANGELOG.md:964 +#: ../../../CHANGELOG.md:1618 msgid "As part of the extraction process of this role out of the Matrix playbook, a few other things improved:" msgstr "" -#: ../../../CHANGELOG.md:966 +#: ../../../CHANGELOG.md:1620 msgid "**native Traefik support** has been added" msgstr "" -#: ../../../CHANGELOG.md:967 +#: ../../../CHANGELOG.md:1621 msgid "**support for hosting under a subpath** has been added, although it suffers from a few minor issues listed [here](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/jitsi.md#url)" msgstr "" -#: ../../../CHANGELOG.md:969 +#: ../../../CHANGELOG.md:1623 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're using Jitsi or not." msgstr "" -#: ../../../CHANGELOG.md:971 +#: ../../../CHANGELOG.md:1625 msgid "If you're making use of Jitsi via this playbook, you will need to update variable references in your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:973 +#: ../../../CHANGELOG.md:1627 msgid "`matrix_jitsi_*_docker_image_` -> `matrix_jitsi_*_container_image_`" msgstr "" -#: ../../../CHANGELOG.md:974 +#: ../../../CHANGELOG.md:1628 msgid "`matrix_jitsi_` -> `jitsi_`" msgstr "" -#: ../../../CHANGELOG.md:975 ../../../CHANGELOG.md:1002 +#: ../../../CHANGELOG.md:1629 ../../../CHANGELOG.md:1656 msgid "some other internal variables have changed, but the playbook will tell you about them" msgstr "" -#: ../../../CHANGELOG.md:977 +#: ../../../CHANGELOG.md:1631 msgid "2023-03-22" msgstr "" -#: ../../../CHANGELOG.md:979 +#: ../../../CHANGELOG.md:1633 msgid "ntfy Web App is disabled by default" msgstr "" -#: ../../../CHANGELOG.md:981 +#: ../../../CHANGELOG.md:1635 msgid "ntfy provides a web app, which is now disabled by default, because it may be unknown to and unused by most users of this playbook. You can enable it by setting `ntfy_web_root: \"app\"` (see [ntfy documentation](docs/configuring-playbook-ntfy.md))." msgstr "" -#: ../../../CHANGELOG.md:983 +#: ../../../CHANGELOG.md:1637 msgid "This change was already applied a while before this entry, but as some users were reporting the missing web app, this entry was added (see [#2529](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2529))." msgstr "" -#: ../../../CHANGELOG.md:986 +#: ../../../CHANGELOG.md:1640 msgid "2023-03-21" msgstr "" -#: ../../../CHANGELOG.md:988 +#: ../../../CHANGELOG.md:1642 msgid "The matrix-prometheus role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:990 +#: ../../../CHANGELOG.md:1644 msgid "**TLDR**: the `matrix-prometheus` role is now included from the [ansible-role-prometheus](https://github.com/mother-of-all-self-hosting/ansible-role-prometheus) repository, part of the [MASH playbook](https://github.com/mother-of-all-self-hosting/mash-playbook). Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:992 +#: ../../../CHANGELOG.md:1646 msgid "The `matrix-prometheus` role has been relocated in its own repository, part of the [MASH playbook](https://github.com/mother-of-all-self-hosting/mash-playbook) project — an Ansible playbook for self-hosting [a growing list of FOSS software](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md). If hosting a Prometheus stack on the Matrix server itself did not stand right with you or you always wanted to host most stuff, you can now use this new playbook to do so." msgstr "" -#: ../../../CHANGELOG.md:994 +#: ../../../CHANGELOG.md:1648 msgid "Extracting the Prometheus role out of this Matrix playbook required huge internal refactoring to the way the Prometheus configuration (scraping jobs) is generated. If you notice any breakage after upgrading, let us know." msgstr "" -#: ../../../CHANGELOG.md:996 +#: ../../../CHANGELOG.md:1650 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're using Prometheus or not." msgstr "" -#: ../../../CHANGELOG.md:998 +#: ../../../CHANGELOG.md:1652 msgid "If you're making use of Prometheus via this playbook, you will need to update variable references in your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:1000 +#: ../../../CHANGELOG.md:1654 msgid "`matrix_prometheus_docker_image_` -> `matrix_prometheus_container_image_`" msgstr "" -#: ../../../CHANGELOG.md:1001 +#: ../../../CHANGELOG.md:1655 msgid "`matrix_prometheus_` -> `prometheus_`" msgstr "" -#: ../../../CHANGELOG.md:1005 +#: ../../../CHANGELOG.md:1659 msgid "2023-03-12" msgstr "" -#: ../../../CHANGELOG.md:1007 +#: ../../../CHANGELOG.md:1661 msgid "synapse-auto-compressor support" msgstr "" -#: ../../../CHANGELOG.md:1009 +#: ../../../CHANGELOG.md:1663 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up [rust-synapse-compress-state](https://github.com/matrix-org/rust-synapse-compress-state)'s `synapse_auto_compressor` tool to run periodically." msgstr "" -#: ../../../CHANGELOG.md:1011 +#: ../../../CHANGELOG.md:1665 msgid "If enabled, `synapse_auto_compressor` runs on a schedule and compresses your Synapse database's `state_groups` table. It was possible to run `rust-synapse-compress-state` manually via the playbook even before — see [Compressing state with rust-synapse-compress-state](docs/maintenance-synapse.md#compressing-state-with-rust-synapse-compress-state). However, using `synapse_auto_compressor` is better, because:" msgstr "" -#: ../../../CHANGELOG.md:1013 +#: ../../../CHANGELOG.md:1667 msgid "it runs on a more up-to-date version of `rust-synapse-compress-state`" msgstr "" -#: ../../../CHANGELOG.md:1014 +#: ../../../CHANGELOG.md:1668 msgid "it's a set-it-and-forget-it tool that you can enable and never have to deal with manual compression anymore" msgstr "" -#: ../../../CHANGELOG.md:1016 +#: ../../../CHANGELOG.md:1670 msgid "This tool needs to be enabled manually, for now. In the future, we're considering enabling it by default for all Synapse installations." msgstr "" -#: ../../../CHANGELOG.md:1018 +#: ../../../CHANGELOG.md:1672 msgid "See our [Setting up synapse-auto-compressor](docs/configuring-playbook-synapse-auto-compressor.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1021 +#: ../../../CHANGELOG.md:1675 msgid "2023-03-07" msgstr "" -#: ../../../CHANGELOG.md:1023 +#: ../../../CHANGELOG.md:1677 msgid "Sliding Sync proxy (Element X) support" msgstr "" -#: ../../../CHANGELOG.md:1025 +#: ../../../CHANGELOG.md:1679 msgid "Thanks to [Benjamin Kampmann](https://github.com/gnunicorn) for [getting it started](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2515), [FSG-Cat](https://github.com/FSG-Cat) for fixing it up and me ([Slavi](https://github.com/spantaleev)) for polishing it up, the playbook can now install and configure the [sliding-sync proxy](https://github.com/matrix-org/sliding-sync)." msgstr "" -#: ../../../CHANGELOG.md:1027 +#: ../../../CHANGELOG.md:1681 msgid "The upcoming Element X clients ([Element X iOS](https://github.com/vector-im/element-x-ios) and [Element X Android](https://github.com/vector-im/element-x-android)) require the `sliding-sync` proxy to do their job. **These clients are still in beta** (especially Element X Android, which requires manual compilation to get it working with a non-`matrix.org` homeseserver). Playbook users can now easily give these clients a try and help test them thanks to us having `sliding-sync` support." msgstr "" -#: ../../../CHANGELOG.md:1029 +#: ../../../CHANGELOG.md:1683 msgid "To get started, see our [Setting up the Sliding Sync proxy](docs/configuring-playbook-sliding-sync-proxy.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:1032 +#: ../../../CHANGELOG.md:1686 msgid "2023-03-02" msgstr "" -#: ../../../CHANGELOG.md:1034 +#: ../../../CHANGELOG.md:1688 msgid "The matrix-etherpad role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1036 +#: ../../../CHANGELOG.md:1690 msgid "**TLDR**: the `matrix-etherpad` role is now included from [another repository](https://github.com/mother-of-all-self-hosting/ansible-role-etherpad). Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1038 +#: ../../../CHANGELOG.md:1692 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're using Etherpad or not." msgstr "" -#: ../../../CHANGELOG.md:1040 +#: ../../../CHANGELOG.md:1694 msgid "If you're making use of Etherpad via this playbook, you will need to update variable references in your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:1042 +#: ../../../CHANGELOG.md:1696 msgid "Rename `matrix_etherpad_public_endpoint` to `etherpad_path_prefix`" msgstr "" -#: ../../../CHANGELOG.md:1044 +#: ../../../CHANGELOG.md:1698 msgid "Replace `matrix_etherpad_mode: dimension` with:" msgstr "" -#: ../../../CHANGELOG.md:1045 +#: ../../../CHANGELOG.md:1699 msgid "for `matrix-nginx-proxy` users:" msgstr "" -#: ../../../CHANGELOG.md:1046 +#: ../../../CHANGELOG.md:1700 msgid "`etherpad_nginx_proxy_dimension_integration_enabled: true`" msgstr "" -#: ../../../CHANGELOG.md:1047 +#: ../../../CHANGELOG.md:1701 msgid "`etherpad_hostname: \"{{ matrix_server_fqn_dimension }}\"`" msgstr "" -#: ../../../CHANGELOG.md:1048 +#: ../../../CHANGELOG.md:1702 msgid "for Traefik users:" msgstr "" -#: ../../../CHANGELOG.md:1049 +#: ../../../CHANGELOG.md:1703 msgid "define your own `etherpad_hostname` and `etherpad_path_prefix` as you see fit" msgstr "" -#: ../../../CHANGELOG.md:1051 +#: ../../../CHANGELOG.md:1705 msgid "Rename all other variables:" msgstr "" -#: ../../../CHANGELOG.md:1052 +#: ../../../CHANGELOG.md:1706 msgid "`matrix_etherpad_docker_image_` -> `matrix_etherpad_container_image_`" msgstr "" -#: ../../../CHANGELOG.md:1053 +#: ../../../CHANGELOG.md:1707 msgid "`matrix_etherpad_` -> `etherpad_`" msgstr "" -#: ../../../CHANGELOG.md:1055 +#: ../../../CHANGELOG.md:1709 msgid "Along with this relocation, the new role also:" msgstr "" -#: ../../../CHANGELOG.md:1057 +#: ../../../CHANGELOG.md:1711 msgid "supports [self-building](docs/self-building.md), so it should work on `arm32` and `arm64` architectures" msgstr "" -#: ../../../CHANGELOG.md:1058 +#: ../../../CHANGELOG.md:1712 msgid "has native Traefik reverse-proxy support (Etherpad requests no longer go through `matrix-nginx-proxy` when using Traefik)" msgstr "" -#: ../../../CHANGELOG.md:1061 +#: ../../../CHANGELOG.md:1715 msgid "2023-02-26" msgstr "" -#: ../../../CHANGELOG.md:1063 +#: ../../../CHANGELOG.md:1717 msgid "Traefik is the default reverse-proxy now" msgstr "" -#: ../../../CHANGELOG.md:1065 +#: ../../../CHANGELOG.md:1719 msgid "**TLDR**: new installations will now default to Traefik as their reverse-proxy. Existing users need to explicitly choose their reverse-proxy type. [Switching to Traefik](#how-do-i-switch-my-existing-setup-to-traefik) is strongly encouraged. `matrix-nginx-proxy` may break over time and will ultimately be removed." msgstr "" -#: ../../../CHANGELOG.md:1067 +#: ../../../CHANGELOG.md:1721 msgid "As mentioned 2 weeks ago in [(Backward Compatibility) Reverse-proxy configuration changes and initial Traefik support](#backward-compatibility-reverse-proxy-configuration-changes-and-initial-traefik-support), the playbook is moving to Traefik as its default SSL-terminating reverse-proxy." msgstr "" -#: ../../../CHANGELOG.md:1069 +#: ../../../CHANGELOG.md:1723 msgid "Until now, we've been doing the migration gradually and keeping full backward compatibility. New installations were defaulting to `matrix-nginx-proxy` (just like before), while existing installations were allowed to remain on `matrix-nginx-proxy` as well. This makes things very difficult for us, because we need to maintain and think about lots of different setups:" msgstr "" -#: ../../../CHANGELOG.md:1071 +#: ../../../CHANGELOG.md:1725 msgid "Traefik managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:1072 +#: ../../../CHANGELOG.md:1726 msgid "Traefik managed by the user in another way" msgstr "" -#: ../../../CHANGELOG.md:1073 +#: ../../../CHANGELOG.md:1727 msgid "another reverse-proxy on the same host (`127.0.0.1` port exposure)" msgstr "" -#: ../../../CHANGELOG.md:1074 +#: ../../../CHANGELOG.md:1728 msgid "another reverse-proxy on another host (`0.0.0.0` port exposure)" msgstr "" -#: ../../../CHANGELOG.md:1075 +#: ../../../CHANGELOG.md:1729 msgid "`matrix-nginx-proxy` — an `nginx` container managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:1076 +#: ../../../CHANGELOG.md:1730 msgid "`nginx` webserver operated by the user, running without a container on the same server" msgstr "" -#: ../../../CHANGELOG.md:1078 +#: ../../../CHANGELOG.md:1732 msgid "Each change we do and each new feature that comes in needs to support all these different ways of reverse-proxying. Because `matrix-nginx-proxy` was the default and pretty much everyone was (and still is) using it, means that new PRs also come with `matrix-nginx-proxy` as their main focus and Traefik as an afterthought, which means we need to spend hours fixing up Traefik support." msgstr "" -#: ../../../CHANGELOG.md:1080 +#: ../../../CHANGELOG.md:1734 msgid "We can't spend all this time maintaining so many different configurations anymore. Traefik support has been an option for 2 weeks and lots of people have already migrated their server and have tested things out. Traefik is what we use and preferentially test for." msgstr "" -#: ../../../CHANGELOG.md:1082 +#: ../../../CHANGELOG.md:1736 msgid "It's time for the **next step in our migration process** to Traefik and elimination of `matrix-nginx-proxy`:" msgstr "" -#: ../../../CHANGELOG.md:1084 +#: ../../../CHANGELOG.md:1738 msgid "Traefik is now the default reverse-proxy for new installations" msgstr "" -#: ../../../CHANGELOG.md:1085 +#: ../../../CHANGELOG.md:1739 msgid "All existing users need to explicitly choose their reverse-proxy type by defining the `matrix_playbook_reverse_proxy_type` variable in their `vars.yml` configuration file. We strongly encourage existing users to [switch the Traefik](#how-to-switch-an-existing-setup-to-traefik), as the nginx setup is bound to become more and more broken over time until it's ultimately removed" msgstr "" -#: ../../../CHANGELOG.md:1087 +#: ../../../CHANGELOG.md:1741 msgid "How do I switch my existing setup to Traefik?" msgstr "" -#: ../../../CHANGELOG.md:1089 +#: ../../../CHANGELOG.md:1743 msgid "**For users who are on `matrix-nginx-proxy`** (the default reverse-proxy provided by the playbook), switching to Traefik can happen with a simple configuration change. Follow this section from 2 weeks ago: [How do I explicitly switch to Traefik right now?](#how-do-i-explicitly-switch-to-traefik-right-now)." msgstr "" -#: ../../../CHANGELOG.md:1091 +#: ../../../CHANGELOG.md:1745 msgid "If you experience trouble:" msgstr "" -#: ../../../CHANGELOG.md:1093 +#: ../../../CHANGELOG.md:1747 msgid "Follow [How do I remain on matrix-nginx-proxy?](#how-do-i-remain-on-matrix-nginx-proxy) to bring your server back online using the old reverse-proxy" msgstr "" -#: ../../../CHANGELOG.md:1094 +#: ../../../CHANGELOG.md:1748 msgid "Ask for help in our [support channels](README.md#support)" msgstr "" -#: ../../../CHANGELOG.md:1095 +#: ../../../CHANGELOG.md:1749 msgid "Try switching to Traefik again later" msgstr "" -#: ../../../CHANGELOG.md:1097 +#: ../../../CHANGELOG.md:1751 msgid "**For users with a more special reverse-proxying setup** (another nginx server, Apache, Caddy, etc.), the migration may not be so smooth. Follow the [Using your own webserver](docs/configuring-playbook-own-webserver.md) guide. Ideally, your custom reverse-proxy will be configured in such a way that it **fronts the Traefik reverse-proxy** provided by the playbook. Other means of reverse-proxying are more fragile and may be deprecated in the future." msgstr "" -#: ../../../CHANGELOG.md:1099 +#: ../../../CHANGELOG.md:1753 msgid "I already use my own Traefik server. How do I plug that in?" msgstr "" -#: ../../../CHANGELOG.md:1101 +#: ../../../CHANGELOG.md:1755 msgid "See the [Traefik managed by the playbook](docs/configuring-playbook-own-webserver.md#traefik-managed-by-the-playbook) section." msgstr "" -#: ../../../CHANGELOG.md:1103 +#: ../../../CHANGELOG.md:1757 msgid "Why is matrix-nginx-proxy used even after switching to Traefik?" msgstr "" -#: ../../../CHANGELOG.md:1105 +#: ../../../CHANGELOG.md:1759 msgid "This playbook manages many different services. All these services were initially integrated with `matrix-nginx-proxy`." msgstr "" -#: ../../../CHANGELOG.md:1107 +#: ../../../CHANGELOG.md:1761 msgid "While we migrate all these components to have native Traefik support, some still go through nginx internally (Traefik -> local `matrix-nginx-proxy` -> component). As time goes on, internal reliance on `matrix-nginx-proxy` will gradually decrease until it's completely removed." msgstr "" -#: ../../../CHANGELOG.md:1109 +#: ../../../CHANGELOG.md:1763 msgid "How do I remain on matrix-nginx-proxy?" msgstr "" -#: ../../../CHANGELOG.md:1111 +#: ../../../CHANGELOG.md:1765 msgid "Most new work and testing targets Traefik, so remaining on nginx is **not** \"the good old stable\" option, but rather the \"still available, but largely untested and likely to be broken very soon\" option." msgstr "" -#: ../../../CHANGELOG.md:1113 +#: ../../../CHANGELOG.md:1767 msgid "To proceed regardless of this warning, add `matrix_playbook_reverse_proxy_type: playbook-managed-nginx` to your configuration." msgstr "" -#: ../../../CHANGELOG.md:1115 +#: ../../../CHANGELOG.md:1769 msgid "At some point in the **near** future (days, or even weeks at most), we hope to completely get rid of `matrix-nginx-proxy` (or break it enough to make it unusable), so you **will soon be forced to migrate** anyway. Plan your migration accordingly." msgstr "" -#: ../../../CHANGELOG.md:1117 +#: ../../../CHANGELOG.md:1771 msgid "How do I keep using my own other reverse-proxy?" msgstr "" -#: ../../../CHANGELOG.md:1119 +#: ../../../CHANGELOG.md:1773 msgid "We recommend that you follow the guide for [Fronting the integrated reverse-proxy webserver with another reverse-proxy](docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy)." msgstr "" -#: ../../../CHANGELOG.md:1122 +#: ../../../CHANGELOG.md:1776 msgid "2023-02-25" msgstr "" -#: ../../../CHANGELOG.md:1124 +#: ../../../CHANGELOG.md:1778 msgid "rageshake support" msgstr "" -#: ../../../CHANGELOG.md:1126 +#: ../../../CHANGELOG.md:1780 msgid "Thanks to [Benjamin Kampmann](https://github.com/gnunicorn), the playbook can now install and configure the [rageshake](https://github.com/matrix-org/rageshake) bug report server." msgstr "" -#: ../../../CHANGELOG.md:1128 +#: ../../../CHANGELOG.md:1782 msgid "Additional details are available in [Setting up rageshake](docs/configuring-playbook-rageshake.md)." msgstr "" -#: ../../../CHANGELOG.md:1131 +#: ../../../CHANGELOG.md:1785 msgid "2023-02-17" msgstr "" -#: ../../../CHANGELOG.md:1133 +#: ../../../CHANGELOG.md:1787 msgid "Synapse templates customization support" msgstr "" -#: ../../../CHANGELOG.md:1135 +#: ../../../CHANGELOG.md:1789 msgid "The playbook can now help you customize Synapse's templates." msgstr "" -#: ../../../CHANGELOG.md:1137 +#: ../../../CHANGELOG.md:1791 msgid "Additional details are available in the [Customizing templates](docs/configuring-playbook-synapse.md#customizing-templates) section of our Synapse documentation." msgstr "" -#: ../../../CHANGELOG.md:1139 +#: ../../../CHANGELOG.md:1793 msgid "The matrix-redis role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1141 +#: ../../../CHANGELOG.md:1795 msgid "**TLDR**: the `matrix-redis` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1143 +#: ../../../CHANGELOG.md:1797 msgid "The `matrix-redis` role (which configures [Redis](https://redis.io/)) has been extracted from the playbook and now lives in its [own repository](https://github.com/mother-of-all-self-hosting/ansible-role-redis). This makes it possible to easily use it in other Ansible playbooks." msgstr "" -#: ../../../CHANGELOG.md:1145 +#: ../../../CHANGELOG.md:1799 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're enabling Ntfy or not. If you're making use of Ntfy via this playbook, you will need to update variable references in your `vars.yml` file (`matrix_redis_` -> `redis_`)." msgstr "" -#: ../../../CHANGELOG.md:1147 +#: ../../../CHANGELOG.md:1801 msgid "The matrix-ntfy role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1149 +#: ../../../CHANGELOG.md:1803 msgid "**TLDR**: the `matrix-ntfy` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1151 +#: ../../../CHANGELOG.md:1805 msgid "The `matrix-ntfy` role (which configures [Ntfy](https://ntfy.sh/)) has been extracted from the playbook and now lives in its [own repository](https://github.com/mother-of-all-self-hosting/ansible-role-ntfy). This makes it possible to easily use it in other Ansible playbooks." msgstr "" -#: ../../../CHANGELOG.md:1153 +#: ../../../CHANGELOG.md:1807 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're enabling Ntfy or not. If you're making use of Ntfy via this playbook, you will need to update variable references in your `vars.yml` file (`matrix_ntfy_` -> `ntfy_`)." msgstr "" -#: ../../../CHANGELOG.md:1156 +#: ../../../CHANGELOG.md:1810 msgid "2023-02-15" msgstr "" -#: ../../../CHANGELOG.md:1158 +#: ../../../CHANGELOG.md:1812 msgid "The matrix-grafana role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1160 +#: ../../../CHANGELOG.md:1814 msgid "**TLDR**: the `matrix-grafana` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1162 +#: ../../../CHANGELOG.md:1816 msgid "The `matrix-grafana` role (which configures [Grafana](docs/configuring-playbook-prometheus-grafana.md)) has been extracted from the playbook and now lives in its [own repository](https://github.com/mother-of-all-self-hosting/ansible-role-grafana). This makes it possible to easily use it in other Ansible playbooks." msgstr "" -#: ../../../CHANGELOG.md:1164 +#: ../../../CHANGELOG.md:1818 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're enabling Grafana or not. If you're making use of Grafana via this playbook, you will need to update variable references in your `vars.yml` file (`matrix_grafana_` -> `grafana_`)." msgstr "" -#: ../../../CHANGELOG.md:1167 +#: ../../../CHANGELOG.md:1821 msgid "2023-02-13" msgstr "" -#: ../../../CHANGELOG.md:1169 +#: ../../../CHANGELOG.md:1823 msgid "The matrix-backup-borg role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1171 +#: ../../../CHANGELOG.md:1825 msgid "**TLDR**: the `matrix-backup-borg` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1173 +#: ../../../CHANGELOG.md:1827 msgid "Thanks to [moan0s](https://github.com/moan0s), the `matrix-backup-borg` role (which configures [BorgBackup](docs/configuring-playbook-backup-borg.md)) has been extracted from the playbook and now lives in its [own repository](https://github.com/mother-of-all-self-hosting/ansible-role-backup_borg). This makes it possible to easily use it in other Ansible playbooks and will become part of [nextcloud-docker-ansible-deploy](https://github.com/spantaleev/nextcloud-docker-ansible-deploy) soon." msgstr "" -#: ../../../CHANGELOG.md:1175 +#: ../../../CHANGELOG.md:1829 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're enabling Borg's backup functionality or not. If you're making use of BorgBackup via this playbook, you will need to update variable references in your `vars.yml` file (`matrix_backup_borg_` -> `backup_borg_`)." msgstr "" -#: ../../../CHANGELOG.md:1178 +#: ../../../CHANGELOG.md:1832 msgid "2023-02-12" msgstr "" -#: ../../../CHANGELOG.md:1180 +#: ../../../CHANGELOG.md:1834 msgid "(Backward Compatibility) Reverse-proxy configuration changes and initial Traefik support" msgstr "" -#: ../../../CHANGELOG.md:1182 +#: ../../../CHANGELOG.md:1836 msgid "**TLDR**:" msgstr "" -#: ../../../CHANGELOG.md:1184 +#: ../../../CHANGELOG.md:1838 msgid "there's a new `matrix_playbook_reverse_proxy_type` variable (see [roles/custom/matrix-base/defaults/main.yml](roles/custom/matrix-base/defaults/main.yml)), which lets you tell the playbook what reverse-proxy setup you'd like to have. This makes it easier for people who want to do reverse-proxying in other ways." msgstr "" -#: ../../../CHANGELOG.md:1185 +#: ../../../CHANGELOG.md:1839 msgid "the default reverse-proxy (`matrix_playbook_reverse_proxy_type`) is still `playbook-managed-nginx` (via `matrix-nginx-proxy`), for now. **Existing `matrix-nginx-proxy` users should not observe any changes** and can stay on this for now." msgstr "" -#: ../../../CHANGELOG.md:1186 +#: ../../../CHANGELOG.md:1840 msgid "**Users who use their [own other webserver](docs/configuring-playbook-own-webserver.md) (e.g. Apache, etc.) need to change** `matrix_playbook_reverse_proxy_type` to something like `other-on-same-host`, `other-on-another-host` or `other-nginx-non-container`" msgstr "" -#: ../../../CHANGELOG.md:1187 +#: ../../../CHANGELOG.md:1841 msgid "we now have **optional [Traefik](https://traefik.io/) support**, so you could easily host Matrix and other Traefik-native services in containers on the same server. Traefik support is still experimental (albeit, good enough) and will improve over time. It does work, but certain esoteric features may not be there yet." msgstr "" -#: ../../../CHANGELOG.md:1188 +#: ../../../CHANGELOG.md:1842 msgid "**Traefik will become the default reverse-proxy in the near future**. `matrix-nginx-proxy` will either remain as an option, or be completely removed to simplify the playbook" msgstr "" -#: ../../../CHANGELOG.md:1190 +#: ../../../CHANGELOG.md:1844 msgid "Motivation for redoing our reverse-proxy setup" msgstr "" -#: ../../../CHANGELOG.md:1192 +#: ../../../CHANGELOG.md:1846 msgid "The playbook has supported various reverse-proxy setups for a long time. We have various configuration variables (`matrix_nginx_proxy_enabled`, various `_host_bind_port` variables, etc.) which allow the playbook to adapt to these different setups. The whole situation was messy though — hard to figure out and with lots of variables to toggle to make things work as you'd expect — huge **operational complexity**." msgstr "" -#: ../../../CHANGELOG.md:1194 +#: ../../../CHANGELOG.md:1848 msgid "We love containers, proven by the fact that **everything** that this playbook manages runs in a container. Yet, we weren't allowing people to easily host other web-exposed containers alongside Matrix services on the same server. We were using `matrix-nginx-proxy` (our integrated [nginx](https://nginx.org/) server), which was handling web-exposure and SSL termination for our own services, but we **weren't helping you with all your other containers**." msgstr "" -#: ../../../CHANGELOG.md:1196 +#: ../../../CHANGELOG.md:1850 msgid "People who were **using `matrix-nginx-proxy`** were on the happy path on which everything worked well by default (Matrix-wise), **but** could not easily run other web-exposed services on their Matrix server because `matrix-nginx-proxy` was occupying ports `80` and `443`. Other services which wanted to get web exposure either had to be plugged into `matrix-nginx-proxy` (somewhat difficult) or people had to forgo using `matrix-nginx-proxy` in favor of something else." msgstr "" -#: ../../../CHANGELOG.md:1198 +#: ../../../CHANGELOG.md:1852 msgid "Of those that decided to forgo `matrix-nginx-proxy`, many were **using nginx** on the same server without a container. This was likely some ancient nginx version, depending on your choice of distro. The Matrix playbook was trying to be helpful and even with `matrix_nginx_proxy_enabled: false` was still generating nginx configuration in `/matrix/nginx-proxy/conf.d`. Those configuration files were adapted for inclusion into an nginx server running locally. Disabling the `matrix-nginx-proxy` role like this, yet still having it produce files is a bit disgusting, but it's what we've had since the early beginnings of this playbook." msgstr "" -#: ../../../CHANGELOG.md:1200 +#: ../../../CHANGELOG.md:1854 msgid "Others still, wanted to run Matrix locally (no SSL certificates), regardless of which web server technology this relied on, and then **reverse-proxy from another machine on the network** which was doing SSL termination. These people were:" msgstr "" -#: ../../../CHANGELOG.md:1202 +#: ../../../CHANGELOG.md:1856 msgid "*either* relying on `matrix_nginx_proxy_enabled: false` as well, combined with exposing services manually (setting `_bind_port` variables)" msgstr "" -#: ../../../CHANGELOG.md:1203 +#: ../../../CHANGELOG.md:1857 msgid "*or* better yet, they were keeping `matrix-nginx-proxy` enabled, but in `http`-only mode (no SSL certificate retrieval)." msgstr "" -#: ../../../CHANGELOG.md:1205 +#: ../../../CHANGELOG.md:1859 msgid "Despite this operational complexity, things worked and were reasonably flexible to adapt to all these situations." msgstr "" -#: ../../../CHANGELOG.md:1207 +#: ../../../CHANGELOG.md:1861 msgid "When using `matrix-nginx-proxy` as is, we still had another problem — one of **internal playbook complexity**. Too many services need to be web-exposed (port 80/443, SSL certificates). Because of this, they all had to integrate with the `matrix-nginx-proxy` role. Tens of different roles explicitly integrating with `matrix-nginx-proxy` is not what we call clean. The `matrix-nginx-proxy` role contains variables for many of these roles (yikes). Other roles were more decoupled from it and were injecting configuration into `matrix-nginx-proxy` at runtime — see all the `inject_into_nginx_proxy.yml` task files in this playbook (more decoupled, but still… yikes)." msgstr "" -#: ../../../CHANGELOG.md:1209 +#: ../../../CHANGELOG.md:1863 msgid "The next problem is one of **efficiency, interoperability and cost-saving**. We're working on other playbooks:" msgstr "" -#: ../../../CHANGELOG.md:1211 +#: ../../../CHANGELOG.md:1865 msgid "[vaultwarden-docker-ansible-deploy](https://github.com/spantaleev/vaultwarden-docker-ansible-deploy) for hosting the [Vaultwarden](https://github.com/dani-garcia/vaultwarden) server — an alternative implementation of the [Bitwarden](https://bitwarden.com/) password manager" msgstr "" -#: ../../../CHANGELOG.md:1212 +#: ../../../CHANGELOG.md:1866 msgid "[gitea-docker-ansible-deploy](https://github.com/spantaleev/gitea-docker-ansible-deploy) — for hosting the [Gitea](https://gitea.io/) git source code hosting service" msgstr "" -#: ../../../CHANGELOG.md:1213 +#: ../../../CHANGELOG.md:1867 msgid "[nextcloud-docker-ansible-deploy](https://github.com/spantaleev/nextcloud-docker-ansible-deploy) — for hosting the [Nextcloud](https://nextcloud.com/) groupware platform" msgstr "" -#: ../../../CHANGELOG.md:1215 +#: ../../../CHANGELOG.md:1869 msgid "We'd love for users to be able to **seamlessly use all these playbooks (and others, even) against a single server**. We don't want `matrix-nginx-proxy` to have a monopoly on port `80`/`443` and make it hard for other services to join in on the party. Such a thing forces people into running multiple servers (one for each service), which does provide nice security benefits, but is costly and ineffiecient. We'd like to make self-hosting these services cheap and easy." msgstr "" -#: ../../../CHANGELOG.md:1217 +#: ../../../CHANGELOG.md:1871 msgid "These other playbooks have been using [Traefik](https://traefik.io/) as their default reverse-proxy for a long time. They can all coexist nicely together (as an example, see the [Interoperability](https://github.com/spantaleev/nextcloud-docker-ansible-deploy/blob/master/docs/configuring-playbook-interoperability.md) documentation for the [Nextcloud playbook](https://github.com/spantaleev/nextcloud-docker-ansible-deploy)). Now that this playbook is gaining Traefik support, it will be able to interoperate with them. If you're going this way, make sure to have the Matrix playbook install Traefik and have the others use `*_reverse_proxy_type: other-traefik-container`." msgstr "" -#: ../../../CHANGELOG.md:1219 +#: ../../../CHANGELOG.md:1873 msgid "Finally, at [etke.cc — a managed Matrix server hosting service](https://etke.cc) (built on top of this playbook, and coincidentally [turning 2 years old today](https://etke.cc/news/upsyw4ykbtgmwhz8k7ukldx0zbbfq-fh0iqi3llixi0/) 🎉), we're allowing people to host some additional services besides Matrix components. Exposing these services to the web requires ugly hacks and configuration files being dropped into `/matrix/nginx-proxy/conf.d`. We believe that everything should run in independent containers and be exposed to the web via a Traefik server, without a huge Ansible role like `matrix-nginx-proxy` that everything else needs to integrate with." msgstr "" -#: ../../../CHANGELOG.md:1221 +#: ../../../CHANGELOG.md:1875 msgid "How do these changes fix all these problems?" msgstr "" -#: ../../../CHANGELOG.md:1223 +#: ../../../CHANGELOG.md:1877 msgid "The new `matrix_playbook_reverse_proxy_type` lets you easily specify your preferred reverse-proxy type, including `other-on-same-host`, `other-on-another-host` and `none`, so people who'd like to reverse-proxy with their own web server have more options now." msgstr "" -#: ../../../CHANGELOG.md:1225 +#: ../../../CHANGELOG.md:1879 msgid "Using Traefik greatly simplifies things, so going forward we'll have a simpler and easier to maintain playbook, which is also interoperable with other services." msgstr "" -#: ../../../CHANGELOG.md:1227 +#: ../../../CHANGELOG.md:1881 msgid "Traefik is a web server, which has been specifically **designed for reverse-proxying to services running in containers**. It's ideal for usage in an Ansible playbook which runs everything in containers." msgstr "" -#: ../../../CHANGELOG.md:1229 +#: ../../../CHANGELOG.md:1883 msgid "**Traefik obtains SSL certificates automatically**, so there's no need for plugging additional tools like [Certbot](https://certbot.eff.org/) into your web server (like we were doing in the `matrix-nginx-proxy` role). No more certificate renewal timers, web server reloading timers, etc. It's just simpler." msgstr "" -#: ../../../CHANGELOG.md:1231 +#: ../../../CHANGELOG.md:1885 msgid "Traefik is a **modern web server**. [HTTP/3](https://doc.traefik.io/traefik/routing/entrypoints/#http3) is supported already (experimentally) and will move to stable soon, in the upcoming Traefik v3 release." msgstr "" -#: ../../../CHANGELOG.md:1233 +#: ../../../CHANGELOG.md:1887 msgid "Traefik does not lock important functionality we'd like to use into [plus packages like nginx does](https://www.nginx.com/products/nginx/), leading us to resolve to configuration workarounds. The default Traefik package is good enough as it is." msgstr "" -#: ../../../CHANGELOG.md:1235 +#: ../../../CHANGELOG.md:1889 msgid "Where we're at right now?" msgstr "" -#: ../../../CHANGELOG.md:1237 +#: ../../../CHANGELOG.md:1891 msgid "`matrix_playbook_reverse_proxy_type` still defaults to a value of `playbook-managed-nginx`." msgstr "" -#: ../../../CHANGELOG.md:1239 +#: ../../../CHANGELOG.md:1893 msgid "Unless we have some regression, **existing `matrix-nginx-proxy` users should be able to update their Matrix server and not observe any changes**. Their setup should still remain on nginx and everything should still work as expected." msgstr "" -#: ../../../CHANGELOG.md:1241 +#: ../../../CHANGELOG.md:1895 msgid "**Users using [their own webservers](docs/configuring-playbook-own-webserver.md) will need to change `matrix_playbook_reverse_proxy_type`** to something like `other-on-same-host`, `other-on-another-host` or `other-nginx-non-container`. Previously, they could toggle `matrix_nginx_proxy_enabled` to `false`, and that made the playbook automatically expose services locally. Currently, we only do this if you change the reverse-proxy type to `other-on-same-host`, `other-on-another-host` or `other-nginx-non-container`." msgstr "" -#: ../../../CHANGELOG.md:1243 +#: ../../../CHANGELOG.md:1897 msgid "How do I explicitly switch to Traefik right now?" msgstr "" -#: ../../../CHANGELOG.md:1245 +#: ../../../CHANGELOG.md:1899 msgid "**Users who wish to migrate to Traefik** today, can do so by **adding** this to their configuration:" msgstr "" -#: ../../../CHANGELOG.md:1253 +#: ../../../CHANGELOG.md:1905 msgid "You may still need to keep certain old `matrix_nginx_proxy_*` variables (like `matrix_nginx_proxy_base_domain_serving_enabled`), even when using Traefik. For now, we recommend keeping all `matrix_nginx_proxy_*` variables just in case. In the future, reliance on `matrix-nginx-proxy` will be removed." msgstr "" -#: ../../../CHANGELOG.md:1255 +#: ../../../CHANGELOG.md:1907 msgid "Switching to Traefik will obtain new SSL certificates from Let's Encrypt (stored in `/matrix/traefik/ssl/acme.json`). **The switch is reversible**. You can always go back to `playbook-managed-nginx` if Traefik is causing you trouble." msgstr "" -#: ../../../CHANGELOG.md:1257 +#: ../../../CHANGELOG.md:1909 msgid "**Note**: toggling `matrix_playbook_reverse_proxy_type` between Traefik and nginx will uninstall the Traefik role and all of its data (under `/matrix/traefik`), so you may run into a Let's Encrypt rate limit if you do it often." msgstr "" -#: ../../../CHANGELOG.md:1259 +#: ../../../CHANGELOG.md:1911 msgid "Treafik directly reverse-proxies to **some** services right now, but for most other services it goes through `matrix-nginx-proxy` (e.g. Traefik -> `matrix-nginx-proxy` -> [Ntfy](docs/configuring-playbook-ntfy.md)). So, even if you opt into Traefik, you'll still see `matrix-nginx-proxy` being installed in local-only mode. This will improve with time." msgstr "" -#: ../../../CHANGELOG.md:1261 +#: ../../../CHANGELOG.md:1913 msgid "Some services (like [coturn](docs/configuring-playbook-turn.md) and [Postmoogle](docs/configuring-playbook-bridge-postmoogle.md)) cannot be reverse-proxied to directly from Traefik, so they require direct access to SSL certificate files extracted out of Traefik. The playbook does this automatically thanks to a new [com.devture.ansible.role.traefik_certs_dumper](https://github.com/devture/com.devture.ansible.role.traefik_certs_dumper) role utilizing the [traefik-certs-dumper](https://github.com/ldez/traefik-certs-dumper) tool." msgstr "" -#: ../../../CHANGELOG.md:1263 +#: ../../../CHANGELOG.md:1915 msgid "Our Traefik setup mostly works, but certain esoteric features may not work. If you have a default setup, we expect you to have a good experience." msgstr "" -#: ../../../CHANGELOG.md:1265 +#: ../../../CHANGELOG.md:1917 msgid "Where we're going in the near future?" msgstr "" -#: ../../../CHANGELOG.md:1267 +#: ../../../CHANGELOG.md:1919 msgid "The `matrix-nginx-proxy` role is quite messy. It manages both nginx and Certbot and its certificate renewal scripts and timers. It generates configuration even when the role is disabled (weird). Although it doesn't directly reach into variables from other roles, it has explicit awareness of various other services that it reverse-proxies to (`roles/custom/matrix-nginx-proxy/templates/nginx/conf.d/matrix-ntfy.conf.j2`, etc.). We'd like to clean this up. The only way is probably to just get rid of the whole thing at some point." msgstr "" -#: ../../../CHANGELOG.md:1269 +#: ../../../CHANGELOG.md:1921 msgid "For now, `matrix-nginx-proxy` will stay around." msgstr "" -#: ../../../CHANGELOG.md:1271 +#: ../../../CHANGELOG.md:1923 msgid "As mentioned above, Traefik still reverse-proxies to some (most) services by going through a local-only `matrix-nginx-proxy` server. This has allowed us to add Traefik support to the playbook early on (without having to rework all services), but is not the final goal. We'll **work on making each service support Traefik natively**, so that traffic will not need to go through `matrix-nginx-proxy` anymore. In the end, choosing Traefik should only give you a pure Traefik installation with no `matrix-nginx-proxy` in sight." msgstr "" -#: ../../../CHANGELOG.md:1273 +#: ../../../CHANGELOG.md:1925 msgid "As Traefik support becomes complete and proves to be stable for a while, especially as a playbook default, we will **most likely remove `matrix-nginx-proxy` completely**. It will likely be some months before this happens though. Keeping support for both Traefik and nginx in the playbook will be a burden, especially with most of us running Traefik in the future. The Traefik role should do everything nginx does in a better and cleaner way. Users who use their own `nginx` server on the Matrix server will be inconvenienced, as nothing will generate ready-to-include nginx configuration for them. Still, we hope it won't be too hard to migrate their setup to another way of doing things, like:" msgstr "" -#: ../../../CHANGELOG.md:1275 +#: ../../../CHANGELOG.md:1927 msgid "not using nginx anymore. A common reason for using nginx until now was that you were running other containers and you need your own nginx to reverse-proxy to all of them. Just switch them to Traefik as well." msgstr "" -#: ../../../CHANGELOG.md:1276 +#: ../../../CHANGELOG.md:1928 msgid "running Traefik in local-only mode (`traefik_config_entrypoint_web_secure_enabled: false`) and using some nginx configuration which reverse-proxies to Traefik (we should introduce examples for this in `examples/nginx`)." msgstr "" -#: ../../../CHANGELOG.md:1278 +#: ../../../CHANGELOG.md:1930 msgid "How do I help?" msgstr "" -#: ../../../CHANGELOG.md:1280 +#: ../../../CHANGELOG.md:1932 msgid "You can help by:" msgstr "" -#: ../../../CHANGELOG.md:1282 +#: ../../../CHANGELOG.md:1934 msgid "**explicitly switching your server to Traefik** right now (see example configuration in [How do I explicitly switch to Traefik right now?](#how-do-i-explicitly-switch-to-traefik-right-now) above), testing, reporting troubles" msgstr "" -#: ../../../CHANGELOG.md:1284 +#: ../../../CHANGELOG.md:1936 msgid "**adding native Traefik support to a role** (requires adding Traefik labels, etc.) — for inspiration, see these roles ([prometheus_node_exporter](https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-node-exporter), [prometheus_postgres_exporter](https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-postgres-exporter)) and how they're hooked into the playbook via [group_vars/matrix_servers](group_vars/matrix_servers)." msgstr "" -#: ../../../CHANGELOG.md:1286 +#: ../../../CHANGELOG.md:1938 msgid "**adding reverse-proxying examples for nginx users** in `examples/nginx`. People who insist on using their own `nginx` server on the same Matrix host, can run Traefik in local-only mode (`traefik_config_entrypoint_web_secure_enabled: false`) and reverse-proxy to the Traefik server" msgstr "" -#: ../../../CHANGELOG.md:1289 +#: ../../../CHANGELOG.md:1941 msgid "2023-02-10" msgstr "" -#: ../../../CHANGELOG.md:1291 +#: ../../../CHANGELOG.md:1943 msgid "Matrix Authentication Support for Jitsi" msgstr "" -#: ../../../CHANGELOG.md:1293 +#: ../../../CHANGELOG.md:1945 msgid "Thanks to [Jakob S.](https://github.com/jakicoll) ([zakk gGmbH](https://github.com/zakk-it)), Jitsi can now use Matrix for authentication (via [Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service))." msgstr "" -#: ../../../CHANGELOG.md:1295 +#: ../../../CHANGELOG.md:1947 msgid "Additional details are available in the [Authenticate using Matrix OpenID (Auth-Type 'matrix')](docs/configuring-playbook-jitsi.md#authenticate-using-matrix-openid-auth-type-matrix)." msgstr "" -#: ../../../CHANGELOG.md:1297 +#: ../../../CHANGELOG.md:1949 msgid "Draupnir moderation tool (bot) support" msgstr "" -#: ../../../CHANGELOG.md:1299 +#: ../../../CHANGELOG.md:1951 msgid "Thanks to [FSG-Cat](https://github.com/FSG-Cat), the playbook can now install and configure the [Draupnir](https://github.com/the-draupnir-project/Draupnir) moderation tool (bot). Draupnir is a fork of [Mjolnir](docs/configuring-playbook-bot-mjolnir.md) (which the playbook has supported for a long time) maintained by Mjolnir's former lead developer." msgstr "" -#: ../../../CHANGELOG.md:1301 +#: ../../../CHANGELOG.md:1953 msgid "Additional details are available in [Setting up Draupnir](docs/configuring-playbook-bot-draupnir.md)." msgstr "" -#: ../../../CHANGELOG.md:1304 +#: ../../../CHANGELOG.md:1956 msgid "2023-02-05" msgstr "" -#: ../../../CHANGELOG.md:1306 +#: ../../../CHANGELOG.md:1958 msgid "The matrix-prometheus-postgres-exporter role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1308 +#: ../../../CHANGELOG.md:1960 msgid "**TLDR**: the `matrix-prometheus-postgres-exporter` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1310 +#: ../../../CHANGELOG.md:1962 msgid "The `matrix-prometheus-postgres-exporter` role (which configures [Prometheus Postgres Exporter](https://github.com/prometheus-community/postgres_exporter)) has been extracted from the playbook and now lives in its own repository at https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-postgres-exporter" msgstr "" -#: ../../../CHANGELOG.md:1312 +#: ../../../CHANGELOG.md:1964 msgid "It's still part of the playbook, but is now installed via `ansible-galaxy` (by running `just roles` / `make roles`). Some variables have been renamed (`matrix_prometheus_postgres_exporter_` -> `prometheus_postgres_exporter_`, etc.). The playbook will report all variables that you need to rename to get upgraded. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1314 +#: ../../../CHANGELOG.md:1966 msgid "The `matrix-prometheus-services-proxy-connect` role has bee adjusted to help integrate the new `prometheus_postgres_exporter` role with our own services (`matrix-nginx-proxy`)" msgstr "" -#: ../../../CHANGELOG.md:1316 ../../../CHANGELOG.md:1358 +#: ../../../CHANGELOG.md:1968 ../../../CHANGELOG.md:2010 msgid "Other roles which aren't strictly related to Matrix are likely to follow this fate of moving to their own repositories. Extracting them out allows other Ansible playbooks to make use of these roles easily." msgstr "" -#: ../../../CHANGELOG.md:1319 +#: ../../../CHANGELOG.md:1971 msgid "2023-01-26" msgstr "" -#: ../../../CHANGELOG.md:1321 +#: ../../../CHANGELOG.md:1973 msgid "coturn can now use host-networking" msgstr "" -#: ../../../CHANGELOG.md:1323 -msgid "Large coturn deployments (with a huge range of ports specified via `matrix_coturn_turn_udp_min_port` and `matrix_coturn_turn_udp_max_port`) experience a huge slowdown with how Docker publishes all these ports (setting up firewall forwarding rules), which leads to a very slow coturn service startup and shutdown." +#: ../../../CHANGELOG.md:1975 +msgid "Large coturn deployments (with a huge range of ports specified via `coturn_turn_udp_min_port` and `coturn_turn_udp_max_port`) experience a huge slowdown with how Docker publishes all these ports (setting up firewall forwarding rules), which leads to a very slow coturn service startup and shutdown." msgstr "" -#: ../../../CHANGELOG.md:1325 +#: ../../../CHANGELOG.md:1977 msgid "Such deployments don't need to run coturn within a private container network anymore. coturn can now run with host-networking by using configuration like this:" msgstr "" -#: ../../../CHANGELOG.md:1331 +#: ../../../CHANGELOG.md:1983 msgid "With such a configuration, **Docker no longer needs to configure thousands of firewall forwarding rules** each time coturn starts and stops. This, however, means that **you will need to ensure these ports are open** in your firewall yourself." msgstr "" -#: ../../../CHANGELOG.md:1333 +#: ../../../CHANGELOG.md:1985 msgid "Thanks to us [tightening coturn security](#backward-compatibility-tightening-coturn-security-can-lead-to-connectivity-issues), running coturn with host-networking should be safe and not expose neither other services running on the host, nor other services running on the local network." msgstr "" -#: ../../../CHANGELOG.md:1335 +#: ../../../CHANGELOG.md:1987 msgid "(Backward Compatibility) Tightening coturn security can lead to connectivity issues" msgstr "" -#: ../../../CHANGELOG.md:1337 -msgid "**TLDR**: users who run and access their Matrix server on a private network (likely a small minority of users) may experience connectivity issues with our new default coturn blocklists. They may need to override `matrix_coturn_denied_peer_ips` and remove some IP ranges from it." +#: ../../../CHANGELOG.md:1989 +msgid "**TLDR**: users who run and access their Matrix server on a private network (likely a small minority of users) may experience connectivity issues with our new default coturn blocklists. They may need to override `coturn_denied_peer_ips` and remove some IP ranges from it." msgstr "" -#: ../../../CHANGELOG.md:1339 +#: ../../../CHANGELOG.md:1991 msgid "Inspired by [this security article](https://www.rtcsec.com/article/cve-2020-26262-bypass-of-coturns-access-control-protection/), we've decided to make use of coturn's `denied-peer-ip` functionality to prevent relaying network traffic to certain private IP subnets. This ensures that your coturn server won't accidentally try to forward traffic to certain services running on your local networks. We run coturn in a container and in a private container network by default, which should prevent such access anyway, but having additional block layers in place is better." msgstr "" -#: ../../../CHANGELOG.md:1341 -msgid "If you access your Matrix server from a local network and need coturn to relay to private IP addresses, you may observe that relaying is now blocked due to our new default `denied-peer-ip` lists (specified in `matrix_coturn_denied_peer_ips`). If you experience such connectivity problems, consider overriding this setting in your `vars.yml` file and removing certain networks from it." +#: ../../../CHANGELOG.md:1993 +msgid "If you access your Matrix server from a local network and need coturn to relay to private IP addresses, you may observe that relaying is now blocked due to our new default `denied-peer-ip` lists (specified in `coturn_denied_peer_ips`). If you experience such connectivity problems, consider overriding this setting in your `vars.yml` file and removing certain networks from it." msgstr "" -#: ../../../CHANGELOG.md:1343 +#: ../../../CHANGELOG.md:1995 msgid "We've also added `no-multicast-peers` to the default coturn configuration, but we don't expect this to cause trouble for most people." msgstr "" -#: ../../../CHANGELOG.md:1346 +#: ../../../CHANGELOG.md:1998 msgid "2023-01-21" msgstr "" -#: ../../../CHANGELOG.md:1348 +#: ../../../CHANGELOG.md:2000 msgid "The matrix-prometheus-node-exporter role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1350 +#: ../../../CHANGELOG.md:2002 msgid "**TLDR**: the `matrix-prometheus-node-exporter` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1352 +#: ../../../CHANGELOG.md:2004 msgid "The `matrix-prometheus-node-exporter` role (which configures [Prometheus node exporter](https://github.com/prometheus/node_exporter)) has been extracted from the playbook and now lives in its own repository at https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-node-exporter" msgstr "" -#: ../../../CHANGELOG.md:1354 +#: ../../../CHANGELOG.md:2006 msgid "It's still part of the playbook, but is now installed via `ansible-galaxy` (by running `just roles` / `make roles`). Some variables have been renamed (`matrix_prometheus_node_exporter_` -> `prometheus_node_exporter_`, etc.). The playbook will report all variables that you need to rename to get upgraded. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1356 +#: ../../../CHANGELOG.md:2008 msgid "A new `matrix-prometheus-services-proxy-connect` role was added to the playbook to help integrate the new `prometheus_node_exporter` role with our own services (`matrix-nginx-proxy`)" msgstr "" -#: ../../../CHANGELOG.md:1361 +#: ../../../CHANGELOG.md:2013 msgid "2023-01-13" msgstr "" -#: ../../../CHANGELOG.md:1363 +#: ../../../CHANGELOG.md:2015 msgid "Support for running commands via just" msgstr "" -#: ../../../CHANGELOG.md:1365 +#: ../../../CHANGELOG.md:2017 msgid "We've previously used [make](https://www.gnu.org/software/make/) for easily running some playbook commands (e.g. `make roles` which triggers `ansible-galaxy`, see [Makefile](Makefile)). Our `Makefile` is still around and you can still run these commands." msgstr "" -#: ../../../CHANGELOG.md:1367 +#: ../../../CHANGELOG.md:2019 msgid "In addition, we've added support for running commands via [just](https://github.com/casey/just) — a more modern command-runner alternative to `make`. Instead of `make roles`, you can now run `just roles` to accomplish the same." msgstr "" -#: ../../../CHANGELOG.md:1369 +#: ../../../CHANGELOG.md:2021 msgid "Our [justfile](justfile) already defines some additional helpful **shortcut** commands that weren't part of our `Makefile`. Here are some examples:" msgstr "" -#: ../../../CHANGELOG.md:1371 +#: ../../../CHANGELOG.md:2023 msgid "`just install-all` to trigger the much longer `ansible-playbook -i inventory/hosts setup.yml --tags=install-all,ensure-matrix-users-created,start` command" msgstr "" -#: ../../../CHANGELOG.md:1372 +#: ../../../CHANGELOG.md:2024 msgid "`just install-all --ask-vault-pass` — commands also support additional arguments (`--ask-vault-pass` will be appended to the above installation command)" msgstr "" -#: ../../../CHANGELOG.md:1373 +#: ../../../CHANGELOG.md:2025 msgid "`just run-tags install-mautrix-slack,start` — to run specific playbook tags" msgstr "" -#: ../../../CHANGELOG.md:1374 +#: ../../../CHANGELOG.md:2026 msgid "`just start-all` — (re-)starts all services" msgstr "" -#: ../../../CHANGELOG.md:1375 +#: ../../../CHANGELOG.md:2027 msgid "`just stop-group postgres` — to stop only the Postgres service" msgstr "" -#: ../../../CHANGELOG.md:1376 +#: ../../../CHANGELOG.md:2028 msgid "`just register-user alice secret-password yes` — registers an `alice` user with the `secret-password` password and admin access (admin = `yes`)" msgstr "" -#: ../../../CHANGELOG.md:1378 +#: ../../../CHANGELOG.md:2030 msgid "Additional helpful commands and shortcuts may be defined in the future." msgstr "" -#: ../../../CHANGELOG.md:1380 +#: ../../../CHANGELOG.md:2032 msgid "This is all completely optional. If you find it difficult to [install `just`](https://github.com/casey/just#installation) or don't find any of this convenient, feel free to run all commands manually." msgstr "" -#: ../../../CHANGELOG.md:1383 +#: ../../../CHANGELOG.md:2035 msgid "2023-01-11" msgstr "" -#: ../../../CHANGELOG.md:1385 +#: ../../../CHANGELOG.md:2037 msgid "mautrix-slack support" msgstr "" -#: ../../../CHANGELOG.md:1387 +#: ../../../CHANGELOG.md:2039 msgid "Thanks to [Cody Neiman](https://github.com/xangelix)'s efforts, the playbook now supports bridging to [Slack](https://slack.com/) via the [mautrix-slack](https://mau.dev/mautrix/slack) bridge. See our [Setting up Mautrix Slack bridging](docs/configuring-playbook-bridge-mautrix-slack.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:1389 +#: ../../../CHANGELOG.md:2041 msgid "**Note**: this is a new Slack bridge. The playbook still retains Slack bridging via [matrix-appservice-slack](docs/configuring-playbook-bridge-appservice-slack.md) and [mx-puppet-slack](docs/configuring-playbook-bridge-mx-puppet-slack.md). You're free to use the bridge that serves you better, or even all three of them (for different users and use-cases)." msgstr "" -#: ../../../CHANGELOG.md:1392 +#: ../../../CHANGELOG.md:2044 msgid "2023-01-10" msgstr "" -#: ../../../CHANGELOG.md:1394 +#: ../../../CHANGELOG.md:2046 msgid "ChatGPT support" msgstr "" -#: ../../../CHANGELOG.md:1396 +#: ../../../CHANGELOG.md:2048 msgid "Thanks to [@bertybuttface](https://github.com/bertybuttface), the playbook can now help you set up [matrix-chatgpt-bot](https://github.com/matrixgpt/matrix-chatgpt-bot) — a bot through which you can talk to the [ChatGPT](https://openai.com/blog/chatgpt/) model." msgstr "" -#: ../../../CHANGELOG.md:1398 +#: ../../../CHANGELOG.md:2050 msgid "See our [Setting up matrix-bot-chatgpt](docs/configuring-playbook-bot-chatgpt.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1401 +#: ../../../CHANGELOG.md:2053 msgid "2022-11-30" msgstr "" -#: ../../../CHANGELOG.md:1403 +#: ../../../CHANGELOG.md:2055 msgid "matrix-postgres-backup has been replaced by the ansible-role-postgres-backup external role" msgstr "" -#: ../../../CHANGELOG.md:1405 +#: ../../../CHANGELOG.md:2057 msgid "Just like we've [replaced Postgres with an external role](#matrix-postgres-has-been-replaced-by-the-comdevtureansiblerolepostgres-external-role) on 2022-11-28, we're now replacing `matrix-postgres-backup` with an external role — [com.devture.ansible.role.postgres_backup](https://github.com/mother-of-all-self-hosting/ansible-role-postgres_backup)." msgstr "" -#: ../../../CHANGELOG.md:1407 +#: ../../../CHANGELOG.md:2059 msgid "You'll need to rename your `matrix_postgres_backup`-prefixed variables such that they use a `postgres_backup` prefix." msgstr "" -#: ../../../CHANGELOG.md:1410 +#: ../../../CHANGELOG.md:2062 msgid "2022-11-28" msgstr "" -#: ../../../CHANGELOG.md:1412 +#: ../../../CHANGELOG.md:2064 msgid "matrix-postgres has been replaced by the ansible-role-postgres external role" msgstr "" -#: ../../../CHANGELOG.md:1414 +#: ../../../CHANGELOG.md:2066 msgid "**TLDR**: the tasks that install the integrated Postgres server now live in an external role — [ansible-role-postgres](https://github.com/mother-of-all-self-hosting/ansible-role-postgres). You'll need to run `make roles` to install it, and to also rename your `matrix_postgres`-prefixed variables to use a `devture_postgres` prefix (e.g. `matrix_postgres_connection_password` -> `postgres_connection_password`). All your data will still be there! Some scripts have moved (`/usr/local/bin/matrix-postgres-cli` -> `/matrix/postgres/bin/cli`)." msgstr "" -#: ../../../CHANGELOG.md:1416 +#: ../../../CHANGELOG.md:2068 msgid "The `matrix-postgres` role that has been part of the playbook for a long time has been replaced with the [ansible-role-postgres](https://github.com/mother-of-all-self-hosting/ansible-role-postgres) role. This was done as part of our work to [use external roles for some things](#the-playbook-now-uses-external-roles-for-some-things) for better code re-use and maintainability." msgstr "" -#: ../../../CHANGELOG.md:1418 +#: ../../../CHANGELOG.md:2070 msgid "The new role is an upgraded version of the old `matrix-postgres` role with these notable differences:" msgstr "" -#: ../../../CHANGELOG.md:1420 +#: ../../../CHANGELOG.md:2072 msgid "it uses different names for its variables (`matrix_postgres` -> `devture_postgres`)" msgstr "" -#: ../../../CHANGELOG.md:1421 +#: ../../../CHANGELOG.md:2073 msgid "when [Vacuuming PostgreSQL](docs/maintenance-postgres.md#vacuuming-postgresql), it will vacuum all your databases, not just the Synapse one" msgstr "" -#: ../../../CHANGELOG.md:1423 +#: ../../../CHANGELOG.md:2075 msgid "You'll need to run `make roles` to install the new role. You would also need to rename your `matrix_postgres`-prefixed variables to use a `devture_postgres` prefix." msgstr "" -#: ../../../CHANGELOG.md:1425 +#: ../../../CHANGELOG.md:2077 msgid "Note: the systemd service still remains the same — `matrix-postgres.service`. Your data will still be in `/matrix/postgres`, etc. Postgres-related scripts will be moved to `/matrix/postgres/bin` (`/usr/local/bin/matrix-postgres-cli` -> `/matrix/postgres/bin/cli`, etc). Also see [The playbook no longer installs scripts in /usr/local/bin](#the-playbook-no-longer-installs-scripts-in-usrlocalbin)." msgstr "" -#: ../../../CHANGELOG.md:1427 +#: ../../../CHANGELOG.md:2079 msgid "The playbook no longer installs scripts to /usr/local/bin" msgstr "" -#: ../../../CHANGELOG.md:1429 +#: ../../../CHANGELOG.md:2081 msgid "The locations of various scripts installed by the playbook have changed." msgstr "" -#: ../../../CHANGELOG.md:1431 +#: ../../../CHANGELOG.md:2083 msgid "The playbook no longer contaminates your `/usr/local/bin` directory. All scripts installed by the playbook now live in `bin/` directories under `/matrix`. Some examples are below:" msgstr "" -#: ../../../CHANGELOG.md:1433 +#: ../../../CHANGELOG.md:2085 msgid "`/usr/local/bin/matrix-remove-all` -> `/matrix/bin/remove-all`" msgstr "" -#: ../../../CHANGELOG.md:1434 +#: ../../../CHANGELOG.md:2086 msgid "`/usr/local/bin/matrix-postgres-cli` -> `/matrix/postgres/bin/cli`" msgstr "" -#: ../../../CHANGELOG.md:1435 +#: ../../../CHANGELOG.md:2087 msgid "`/usr/local/bin/matrix-ssl-lets-encrypt-certificates-renew` -> `/matrix/ssl/bin/lets-encrypt-certificates-renew`" msgstr "" -#: ../../../CHANGELOG.md:1436 +#: ../../../CHANGELOG.md:2088 msgid "`/usr/local/bin/matrix-synapse-register-user` -> `/matrix/synapse/bin/register-user`" msgstr "" -#: ../../../CHANGELOG.md:1439 +#: ../../../CHANGELOG.md:2091 msgid "2022-11-25" msgstr "" -#: ../../../CHANGELOG.md:1441 +#: ../../../CHANGELOG.md:2093 msgid "2x-5x performance improvements in playbook runtime" msgstr "" -#: ../../../CHANGELOG.md:1443 +#: ../../../CHANGELOG.md:2095 msgid "**TLDR**: the playbook is 2x faster for running `--tags=setup-all` (and various other tags). It also has new `--tags=install-*` tags (like `--tags=install-all`), which skip uninstallation tasks and bring an additional 2.5x speedup. In total, the playbook can maintain your server 5 times faster." msgstr "" -#: ../../../CHANGELOG.md:1445 +#: ../../../CHANGELOG.md:2097 msgid "Our [etke.cc managed Matrix hosting service](https://etke.cc) runs maintenance against hundreds of servers, so the playbook being fast means a lot. The [etke.cc Ansible playbook](https://github.com/etkecc/ansible) (which is an extension of this one) is growing to support more and more services (besides just Matrix), so the Matrix playbook being leaner prevents runtimes from becoming too slow and improves the customer experience." msgstr "" -#: ../../../CHANGELOG.md:1447 +#: ../../../CHANGELOG.md:2099 msgid "Even when running `ansible-playbook` manually (as most of us here do), it's beneficial not to waste time and CPU resources." msgstr "" -#: ../../../CHANGELOG.md:1449 +#: ../../../CHANGELOG.md:2101 msgid "Recently, a few large optimizations have been done to this playbook and its external roles (see [The playbook now uses external roles for some things](#the-playbook-now-uses-external-roles-for-some-things) and don't forget to run `make roles`):" msgstr "" -#: ../../../CHANGELOG.md:1451 +#: ../../../CHANGELOG.md:2103 msgid "Replacing Ansible `import_tasks` calls with `include_tasks`, which decreased runtime in half. Using `import_tasks` is slower and causes Ansible to go through and skip way too many tasks (tasks which could have been skipped altogether by not having Ansible include them in the first place). On an experimental VM, **deployment time was decreased from ~530 seconds to ~250 seconds**." msgstr "" -#: ../../../CHANGELOG.md:1453 +#: ../../../CHANGELOG.md:2105 msgid "Introducing new `install-*` tags (`install-all` and `install-COMPONENT`, e.g. `install-synapse`, `install-bot-mjolnir`), which only run Ansible tasks pertaining to installation, while skipping uninstallation tasks. In most cases, people are maintaining the same setup or they're *adding* new components. Removing components is rare. Running thousands of uninstallation tasks each time is wasteful. On an experimental VM, **deployment time was decreased from ~250 seconds (`--tags=setup-all`) to ~100 seconds (`--tags=install-all`)**." msgstr "" -#: ../../../CHANGELOG.md:1455 +#: ../../../CHANGELOG.md:2107 msgid "You can still use `--tags=setup-all`. In fact, that's the best way to ensure your server is reconciled with the `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:1457 +#: ../../../CHANGELOG.md:2109 msgid "If you know you haven't uninstalled any services since the last time you ran the playbook, you could run `--tags=install-all` instead and benefit from quicker runtimes. It should be noted that a service may become \"eligible for uninstallation\" even if your `vars.yml` file remains the same. In rare cases, we toggle services from being auto-installed to being optional, like we did on the 17th of March 2022 when we made [ma1sd not get installed by default](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md#compatibility-break-ma1sd-identity-server-no-longer-installed-by-default). In such rare cases, you'd also need to run `--tags=setup-all`." msgstr "" -#: ../../../CHANGELOG.md:1460 +#: ../../../CHANGELOG.md:2112 msgid "2022-11-22" msgstr "" -#: ../../../CHANGELOG.md:1462 +#: ../../../CHANGELOG.md:2114 msgid "Automatic `matrix_architecture` determination" msgstr "" -#: ../../../CHANGELOG.md:1464 +#: ../../../CHANGELOG.md:2116 msgid "From now on, the playbook automatically determines your server's architecture and sets the `matrix_architecture` variable accordingly. You no longer need to set this variable manually in your `vars.yml` file." msgstr "" -#: ../../../CHANGELOG.md:1466 +#: ../../../CHANGELOG.md:2118 msgid "Docker and the Docker SDK for Python are now installed via external roles" msgstr "" -#: ../../../CHANGELOG.md:1470 +#: ../../../CHANGELOG.md:2122 msgid "Docker will now be installed on the server via the [geerlingguy.docker](https://github.com/geerlingguy/ansible-role-docker) Ansible role. If you'd like to manage the Docker installation yourself, you can disable the playbook's installation of Docker by setting `matrix_playbook_docker_installation_enabled: false`." msgstr "" -#: ../../../CHANGELOG.md:1472 +#: ../../../CHANGELOG.md:2124 msgid "The Docker SDK for Python (named `docker-python`, `python-docker`, etc. on the different platforms) is now also installed by another role ([com.devture.ansible.role.docker_sdk_for_python](https://github.com/devture/com.devture.ansible.role.docker_sdk_for_python)). To disable this role and install the necessary tools yourself, use `devture_docker_sdk_for_python_installation_enabled: false`." msgstr "" -#: ../../../CHANGELOG.md:1474 +#: ../../../CHANGELOG.md:2126 msgid "If you're hitting issues with Docker installation or Docker SDK for Python installation, consider reporting bugs or contributing to these other projects." msgstr "" -#: ../../../CHANGELOG.md:1476 +#: ../../../CHANGELOG.md:2128 msgid "These additional roles are downloaded into the playbook directory (to `roles/galaxy`) via an `ansible-galaxy …` command. `make roles` is an easy shortcut for invoking the `ansible-galaxy` command to download these roles." msgstr "" -#: ../../../CHANGELOG.md:1479 +#: ../../../CHANGELOG.md:2131 msgid "2022-11-20" msgstr "" -#: ../../../CHANGELOG.md:1481 +#: ../../../CHANGELOG.md:2133 msgid "(Backward Compatibility Break) Changing how reverse-proxying to Synapse works — now via a `matrix-synapse-reverse-proxy-companion` service" msgstr "" -#: ../../../CHANGELOG.md:1483 +#: ../../../CHANGELOG.md:2135 msgid "**TLDR**: There's now a `matrix-synapse-reverse-proxy-companion` nginx service, which helps with reverse-proxying to Synapse and its various worker processes (if workers are enabled), so that `matrix-nginx-proxy` can be relieved of this role. `matrix-nginx-proxy` still remains as the public SSL-terminating reverse-proxy in the playbook. `matrix-synapse-reverse-proxy-companion` is just one more reverse-proxy thrown into the mix for convenience. People with a more custom reverse-proxying configuration may be affected — see [Webserver configuration](#webserver-configuration) below." msgstr "" -#: ../../../CHANGELOG.md:1485 +#: ../../../CHANGELOG.md:2137 msgid "Background" msgstr "" -#: ../../../CHANGELOG.md:1487 +#: ../../../CHANGELOG.md:2139 msgid "Previously, `matrix-nginx-proxy` forwarded requests to Synapse directly. When Synapse is running in worker mode, the reverse-proxying configuration is more complicated (different requests need to go to different Synapse worker processes). `matrix-nginx-proxy` had configuration for sending each URL endpoint to the correct Synapse worker responsible for handling it. However, sometimes people like to disable `matrix-nginx-proxy` (for whatever reason) as detailed in [Using your own webserver, instead of this playbook's nginx proxy](docs/configuring-playbook-own-webserver.md)." msgstr "" -#: ../../../CHANGELOG.md:1489 +#: ../../../CHANGELOG.md:2141 msgid "Because `matrix-nginx-proxy` was so central to request forwarding, when it was disabled and Synapse was running with workers enabled, there was nothing which could forward requests to the correct place anymore… which caused [problems such as this one affecting Dimension](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2090)." msgstr "" -#: ../../../CHANGELOG.md:1491 +#: ../../../CHANGELOG.md:2143 msgid "Solution" msgstr "" -#: ../../../CHANGELOG.md:1493 +#: ../../../CHANGELOG.md:2145 msgid "From now on, `matrix-nginx-proxy` is relieved of its function of reverse-proxying to Synapse and its various worker processes. This role is now handled by the new `matrix-synapse-reverse-proxy-companion` nginx service and works even if `matrix-nginx-proxy` is disabled. The purpose of the new `matrix-synapse-reverse-proxy-companion` service is to:" msgstr "" -#: ../../../CHANGELOG.md:1495 +#: ../../../CHANGELOG.md:2147 msgid "serve as a companion to Synapse and know how to reverse-proxy to Synapse correctly (no matter if workers are enabled or not)" msgstr "" -#: ../../../CHANGELOG.md:1497 +#: ../../../CHANGELOG.md:2149 msgid "provide a unified container address for reaching Synapse (no matter if workers are enabled or not)" msgstr "" -#: ../../../CHANGELOG.md:1498 +#: ../../../CHANGELOG.md:2150 msgid "`matrix-synapse-reverse-proxy-companion:8008` for Synapse Client-Server API traffic" msgstr "" -#: ../../../CHANGELOG.md:1499 +#: ../../../CHANGELOG.md:2151 msgid "`matrix-synapse-reverse-proxy-companion:8048` for Synapse Server-Server (Federation) API traffic" msgstr "" -#: ../../../CHANGELOG.md:1501 +#: ../../../CHANGELOG.md:2153 msgid "simplify `matrix-nginx-proxy` configuration — it now only needs to send requests to `matrix-synapse-reverse-proxy-companion` or `matrix-dendrite`, etc., without having to worry about workers" msgstr "" -#: ../../../CHANGELOG.md:1503 +#: ../../../CHANGELOG.md:2155 msgid "allow reverse-proxying to Synapse, even if `matrix-nginx-proxy` is disabled" msgstr "" -#: ../../../CHANGELOG.md:1505 +#: ../../../CHANGELOG.md:2157 msgid "`matrix-nginx-proxy` still remains as the public SSL-terminating reverse-proxy in the playbook. All traffic goes through it before reaching any of the services. It's just that now the Synapse traffic is routed through `matrix-synapse-reverse-proxy-companion` like this:" msgstr "" -#: ../../../CHANGELOG.md:1507 +#: ../../../CHANGELOG.md:2159 msgid "(`matrix-nginx-proxy` -> `matrix-synapse-reverse-proxy-companion` -> (`matrix-synapse` or some Synapse worker))." msgstr "" -#: ../../../CHANGELOG.md:1509 +#: ../../../CHANGELOG.md:2161 msgid "Various services (like Dimension, etc.) still talk to Synapse via `matrix-nginx-proxy` (e.g. `http://matrix-nginx-proxy:12080`) preferentially. They only talk to Synapse via the reverse-proxy companion (e.g. `http://matrix-synapse-reverse-proxy-companion:8008`) if `matrix-nginx-proxy` is disabled. Services should not be talking to Synapse (e.g. `https://matrix-synapse:8008` directly anymore), because when workers are enabled, that's the Synapse `master` process and may not be serving all URL endpoints needed by the service." msgstr "" -#: ../../../CHANGELOG.md:1511 +#: ../../../CHANGELOG.md:2163 msgid "Webserver configuration" msgstr "" -#: ../../../CHANGELOG.md:1513 +#: ../../../CHANGELOG.md:2165 msgid "if you're using `matrix-nginx-proxy` (`matrix_nginx_proxy_enabled: true`, which is the default for the playbook), you don't need to do anything" msgstr "" -#: ../../../CHANGELOG.md:1515 +#: ../../../CHANGELOG.md:2167 msgid "if you're using your own `nginx` webserver running on the server, you shouldn't be affected. The `/matrix/nginx/conf.d` configuration and exposed ports that you're relying on will automatically be updated in a way that should work" msgstr "" -#: ../../../CHANGELOG.md:1517 +#: ../../../CHANGELOG.md:2169 msgid "if you're using another local webserver (e.g. Apache, etc.) and haven't changed any ports (`matrix_*_host_bind_port` definitions), you shouldn't be affected. You're likely sending Matrix traffic to `127.0.0.1:8008` and `127.0.0.1:8048`. These ports (`8008` and `8048`) will still be exposed on `127.0.0.1` by default — just not by the `matrix-synapse` container from now on, but by the `matrix-synapse-reverse-proxy-companion` container instead" msgstr "" -#: ../../../CHANGELOG.md:1519 +#: ../../../CHANGELOG.md:2171 msgid "if you've been exposing `matrix-synapse` ports (`matrix_synapse_container_client_api_host_bind_port`, etc.) manually, you should consider exposing `matrix-synapse-reverse-proxy-companion` ports instead" msgstr "" -#: ../../../CHANGELOG.md:1521 +#: ../../../CHANGELOG.md:2173 msgid "if you're running Traefik and reverse-proxying directly to the `matrix-synapse` container, you should start reverse-proxying to the `matrix-synapse-reverse-proxy-companion` container instead. See [our updated Traefik example configuration](docs/configuring-playbook-own-webserver.md#sample-configuration-for-running-behind-traefik-20). Note: we now recommend calling the federation entry point `federation` (instead of `synapse`) and reverse-proxying the federation traffic via `matrix-nginx-proxy`, instead of sending it directly to Synapse (or `matrix-synapse-reverse-proxy-companion`). This makes the configuration simpler." msgstr "" -#: ../../../CHANGELOG.md:1524 +#: ../../../CHANGELOG.md:2176 msgid "2022-11-05" msgstr "" -#: ../../../CHANGELOG.md:1526 +#: ../../../CHANGELOG.md:2178 msgid "(Backward Compatibility Break) A new default standalone mode for Etherpad" msgstr "" -#: ../../../CHANGELOG.md:1528 +#: ../../../CHANGELOG.md:2180 msgid "Until now, [Etherpad](https://etherpad.org/) (which [the playbook could install for you](docs/configuring-playbook-etherpad.md)) required the [Dimension integration manager](docs/configuring-playbook-dimension.md) to also be installed, because Etherpad was hosted on the Dimension domain (at `dimension.example.com/etherpad`)." msgstr "" -#: ../../../CHANGELOG.md:1530 +#: ../../../CHANGELOG.md:2182 msgid "From now on, Etherpad can be installed in `standalone` mode on `etherpad.example.com` and used even without Dimension. This is much more versatile, so the playbook now defaults to this new mode (`etherpad_mode: standalone`)." msgstr "" -#: ../../../CHANGELOG.md:1532 +#: ../../../CHANGELOG.md:2184 msgid "If you've already got both Etherpad and Dimension in use you could:" msgstr "" -#: ../../../CHANGELOG.md:1534 +#: ../../../CHANGELOG.md:2186 msgid "**either** keep hosting Etherpad under the Dimension domain by adding `etherpad_mode: dimension` to your `vars.yml` file. All your existing room widgets will continue working at the same URLs and no other changes will be necessary." msgstr "" -#: ../../../CHANGELOG.md:1536 +#: ../../../CHANGELOG.md:2188 msgid "**or**, you could change to hosting Etherpad separately on `etherpad.example.com`. You will need to [configure a DNS record](docs/configuring-dns.md) for this new domain. You will also need to reconfigure Dimension to use the new pad URLs (`https://etherpad.example.com/…`) going forward (refer to our [configuring Etherpad documentation](docs/configuring-playbook-etherpad.md)). All your existing room widgets (which still use `https://dimension.example.com/etherpad/…`) will break as Etherpad is not hosted there anymore. You will need to re-add them or to consider not using `standalone` mode" msgstr "" -#: ../../../CHANGELOG.md:1539 +#: ../../../CHANGELOG.md:2191 msgid "2022-11-04" msgstr "" -#: ../../../CHANGELOG.md:1541 +#: ../../../CHANGELOG.md:2193 msgid "The playbook now uses external roles for some things" msgstr "" -#: ../../../CHANGELOG.md:1543 +#: ../../../CHANGELOG.md:2195 msgid "**TLDR**: when updating the playbook and before running it, you'll need to run `make roles` to make [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) download dependency roles (see the [`requirements.yml` file](requirements.yml)) to the `roles/galaxy` directory. Without this, the playbook won't work." msgstr "" -#: ../../../CHANGELOG.md:1545 +#: ../../../CHANGELOG.md:2197 msgid "We're in the process of trimming the playbook and making it reuse Ansible roles." msgstr "" -#: ../../../CHANGELOG.md:1547 +#: ../../../CHANGELOG.md:2199 msgid "Starting now, the playbook is composed of 2 types of Ansible roles:" msgstr "" -#: ../../../CHANGELOG.md:1549 +#: ../../../CHANGELOG.md:2201 msgid "those that live within the playbook itself (`roles/custom/*`)" msgstr "" -#: ../../../CHANGELOG.md:1551 +#: ../../../CHANGELOG.md:2203 msgid "those downloaded from other sources (using [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) to `roles/galaxy`, based on the [`requirements.yml` file](requirements.yml)). These roles are maintained by us or by other people from the Ansible community." msgstr "" -#: ../../../CHANGELOG.md:1553 +#: ../../../CHANGELOG.md:2205 msgid "We're doing this for greater code-reuse (across Ansible playbooks, including our own related playbooks [gitea-docker-ansible-deploy](https://github.com/spantaleev/gitea-docker-ansible-deploy) and [nextcloud-docker-ansible-deploy](https://github.com/spantaleev/nextcloud-docker-ansible-deploy)) and decreased maintenance burden. Until now, certain features were copy-pasted across playbooks or were maintained separately in each one, with improvements often falling behind. We've also tended to do too much by ourselves — installing Docker on the server from our `matrix-base` role, etc. — something that we'd rather not do anymore by switching to the [geerlingguy.docker](https://galaxy.ansible.com/geerlingguy/docker) role." msgstr "" -#: ../../../CHANGELOG.md:1555 +#: ../../../CHANGELOG.md:2207 msgid "Some variable names will change during the transition to having more and more external (galaxy) roles. There's a new `custom/matrix_playbook_migration` role added to the playbook which will tell you about these changes each time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:1557 +#: ../../../CHANGELOG.md:2209 msgid "**From now on**, every time you update the playbook (well, every time the `requirements.yml` file changes), it's best to run `make roles` to update the roles downloaded from other sources. `make roles` is a shortcut (a `roles` target defined in [`Makefile`](Makefile) and executed by the [`make`](https://www.gnu.org/software/make/) utility) which ultimately runs [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) to download Ansible roles. If you don't have `make`, you can also manually run the commands seen in the `Makefile`." msgstr "" -#: ../../../CHANGELOG.md:1560 +#: ../../../CHANGELOG.md:2212 msgid "2022-10-14" msgstr "" -#: ../../../CHANGELOG.md:1562 +#: ../../../CHANGELOG.md:2214 msgid "synapse-s3-storage-provider support" msgstr "" -#: ../../../CHANGELOG.md:1564 +#: ../../../CHANGELOG.md:2216 msgid "**`synapse-s3-storage-provider` support is very new and still relatively untested. Using it may cause data loss.**" msgstr "" -#: ../../../CHANGELOG.md:1566 +#: ../../../CHANGELOG.md:2218 msgid "You can now store your Synapse media repository files on Amazon S3 (or another S3-compatible object store) using [synapse-s3-storage-provider](https://github.com/matrix-org/synapse-s3-storage-provider) — a media provider for Synapse (Python module), which should work faster and more reliably than our previous [Goofys](docs/configuring-playbook-s3-goofys.md) implementation (Goofys will continue to work)." msgstr "" -#: ../../../CHANGELOG.md:1568 +#: ../../../CHANGELOG.md:2220 msgid "This is not just for initial installations. Users with existing files (stored in the local filesystem) can also migrate their files to `synapse-s3-storage-provider`." msgstr "" -#: ../../../CHANGELOG.md:1570 +#: ../../../CHANGELOG.md:2222 msgid "To get started, see our [Storing Synapse media files on Amazon S3 with synapse-s3-storage-provider](docs/configuring-playbook-synapse-s3-storage-provider.md) documentation." msgstr "" -#: ../../../CHANGELOG.md:1572 +#: ../../../CHANGELOG.md:2224 msgid "Synapse container image customization support" msgstr "" -#: ../../../CHANGELOG.md:1574 +#: ../../../CHANGELOG.md:2226 msgid "We now support customizing the Synapse container image by adding additional build steps to its [`Dockerfile`](https://docs.docker.com/engine/reference/builder/)." msgstr "" -#: ../../../CHANGELOG.md:1576 +#: ../../../CHANGELOG.md:2228 msgid "Our [synapse-s3-storage-provider support](#synapse-s3-storage-provider-support) is actually built on this. When `s3-storage-provider` is enabled, we automatically add additional build steps to install its Python module into the Synapse image." msgstr "" -#: ../../../CHANGELOG.md:1578 +#: ../../../CHANGELOG.md:2230 msgid "Besides this kind of auto-added build steps (for components supported by the playbook), we also let you inject your own custom build steps using configuration like this:" msgstr "" -#: ../../../CHANGELOG.md:1589 +#: ../../../CHANGELOG.md:2241 msgid "People who have needed to customize Synapse previously had to fork the git repository, make their changes to the `Dockerfile` there, point the playbook to the new repository (`matrix_synapse_container_image_self_build_repo`) and enable self-building from scratch (`matrix_synapse_container_image_self_build: true`). This is harder and slower." msgstr "" -#: ../../../CHANGELOG.md:1591 +#: ../../../CHANGELOG.md:2243 msgid "With the new Synapse-customization feature in the playbook, we use the original upstream (pre-built, if available) Synapse image and only build on top of it, right on the Matrix server. This is much faster than building all of Synapse from scratch." msgstr "" -#: ../../../CHANGELOG.md:1594 +#: ../../../CHANGELOG.md:2246 msgid "2022-10-02" msgstr "" -#: ../../../CHANGELOG.md:1596 +#: ../../../CHANGELOG.md:2248 msgid "matrix-ldap-registration-proxy support" msgstr "" -#: ../../../CHANGELOG.md:1598 +#: ../../../CHANGELOG.md:2250 msgid "Thanks to [@TheOneWithTheBraid](https://github.com/TheOneWithTheBraid), we now support installing [matrix-ldap-registration-proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy) — a proxy which handles Matrix registration requests and forwards them to LDAP." msgstr "" -#: ../../../CHANGELOG.md:1600 +#: ../../../CHANGELOG.md:2252 msgid "See our [Setting up matrix-ldap-registration-proxy](docs/configuring-playbook-matrix-ldap-registration-proxy.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1603 +#: ../../../CHANGELOG.md:2255 msgid "2022-09-15" msgstr "" -#: ../../../CHANGELOG.md:1605 +#: ../../../CHANGELOG.md:2257 msgid "(Potential Backward Compatibility Break) Major improvements to Synapse workers" msgstr "" -#: ../../../CHANGELOG.md:1607 +#: ../../../CHANGELOG.md:2259 msgid "People who are interested in running a Synapse worker setup should know that **our Synapse worker implementation is much more powerful now**:" msgstr "" -#: ../../../CHANGELOG.md:1609 +#: ../../../CHANGELOG.md:2261 msgid "we've added support for [Stream writers](#stream-writers-support)" msgstr "" -#: ../../../CHANGELOG.md:1610 +#: ../../../CHANGELOG.md:2262 msgid "we've added support for [multiple federation sender workers](#multiple-federation-sender-workers-support)" msgstr "" -#: ../../../CHANGELOG.md:1611 +#: ../../../CHANGELOG.md:2263 msgid "we've added support for [multiple pusher workers](#multiple-pusher-workers-support)" msgstr "" -#: ../../../CHANGELOG.md:1612 +#: ../../../CHANGELOG.md:2264 msgid "we've added support for [running background tasks on a worker](#background-tasks-can-run-on-a-worker)" msgstr "" -#: ../../../CHANGELOG.md:1613 +#: ../../../CHANGELOG.md:2265 msgid "we've restored support for [`appservice` workers](#appservice-worker-support-is-back)" msgstr "" -#: ../../../CHANGELOG.md:1614 +#: ../../../CHANGELOG.md:2266 msgid "we've restored support for [`user_dir` workers](#user-directory-worker-support-is-back)" msgstr "" -#: ../../../CHANGELOG.md:1615 +#: ../../../CHANGELOG.md:2267 msgid "we've made it possible to [reliably use more than 1 `media_repository` worker](#using-more-than-1-media-repository-worker-is-now-more-reliable)" msgstr "" -#: ../../../CHANGELOG.md:1616 +#: ../../../CHANGELOG.md:2268 msgid "see the [Potential Backward Incompatibilities after these Synapse worker changes](#potential-backward-incompatibilities-after-these-synapse-worker-changes)" msgstr "" -#: ../../../CHANGELOG.md:1618 +#: ../../../CHANGELOG.md:2270 msgid "Stream writers support" msgstr "" -#: ../../../CHANGELOG.md:1620 +#: ../../../CHANGELOG.md:2272 msgid "From now on, the playbook lets you easily set up various [stream writer workers](https://matrix-org.github.io/synapse/latest/workers.html#stream-writers) which can handle different streams (`events` stream; `typing` URL endpoints, `to_device` URL endpoints, `account_data` URL endpoints, `receipts` URL endpoints, `presence` URL endpoints). All of this work was previously handled by the main Synapse process, but can now be offloaded to stream writer worker processes." msgstr "" -#: ../../../CHANGELOG.md:1622 +#: ../../../CHANGELOG.md:2274 msgid "If you're using `matrix_synapse_workers_preset: one-of-each`, you'll automatically get 6 additional workers (one for each of the above stream types). Our `little-federation-helper` preset (meant to be quite minimal and focusing in improved federation performance) does not include stream writer workers." msgstr "" -#: ../../../CHANGELOG.md:1624 +#: ../../../CHANGELOG.md:2276 msgid "If you'd like to customize the number of workers we also make that possible using these variables:" msgstr "" -#: ../../../CHANGELOG.md:1637 +#: ../../../CHANGELOG.md:2289 msgid "Multiple federation sender workers support" msgstr "" -#: ../../../CHANGELOG.md:1639 +#: ../../../CHANGELOG.md:2291 msgid "Until now, we only supported a single `federation_sender` worker (`matrix_synapse_workers_federation_sender_workers_count` could either be `0` or `1`). From now on, you can have as many as you want to help with your federation traffic." msgstr "" -#: ../../../CHANGELOG.md:1641 +#: ../../../CHANGELOG.md:2293 msgid "Multiple pusher workers support" msgstr "" -#: ../../../CHANGELOG.md:1643 +#: ../../../CHANGELOG.md:2295 msgid "Until now, we only supported a single `pusher` worker (`matrix_synapse_workers_pusher_workers_count` could either be `0` or `1`). From now on, you can have as many as you want to help with pushing notifications out." msgstr "" -#: ../../../CHANGELOG.md:1645 +#: ../../../CHANGELOG.md:2297 msgid "Background tasks can run on a worker" msgstr "" -#: ../../../CHANGELOG.md:1647 +#: ../../../CHANGELOG.md:2299 msgid "From now on, you can put [background task processing on a worker](https://matrix-org.github.io/synapse/latest/workers.html#background-tasks)." msgstr "" -#: ../../../CHANGELOG.md:1649 +#: ../../../CHANGELOG.md:2301 msgid "With `matrix_synapse_workers_preset: one-of-each`, you'll get one `background` worker automatically. You can also control the `background` workers count with `matrix_synapse_workers_background_workers_count`. Only `0` or `1` workers of this type are supported by Synapse." msgstr "" -#: ../../../CHANGELOG.md:1651 +#: ../../../CHANGELOG.md:2303 msgid "Appservice worker support is back" msgstr "" -#: ../../../CHANGELOG.md:1653 +#: ../../../CHANGELOG.md:2305 msgid "We previously had an `appservice` worker type, which [Synapse deprecated in v1.59.0](https://github.com/element-hq/synapse/blob/v1.59.0/docs/upgrade.md#deprecation-of-the-synapseappappservice-and-synapseappuser_dir-worker-application-types). So did we, at the time." msgstr "" -#: ../../../CHANGELOG.md:1655 +#: ../../../CHANGELOG.md:2307 msgid "The new way to implement such workers is by using a `generic_worker` and dedicating it to the task of talking to Application Services. From now on, we have support for this." msgstr "" -#: ../../../CHANGELOG.md:1657 +#: ../../../CHANGELOG.md:2309 msgid "With `matrix_synapse_workers_preset: one-of-each`, you'll get one `appservice` worker automatically. You can also control the `appservice` workers count with `matrix_synapse_workers_appservice_workers_count`. Only `0` or `1` workers of this type are supported by Synapse." msgstr "" -#: ../../../CHANGELOG.md:1659 +#: ../../../CHANGELOG.md:2311 msgid "User Directory worker support is back" msgstr "" -#: ../../../CHANGELOG.md:1661 +#: ../../../CHANGELOG.md:2313 msgid "We previously had a `user_dir` worker type, which [Synapse deprecated in v1.59.0](https://github.com/element-hq/synapse/blob/v1.59.0/docs/upgrade.md#deprecation-of-the-synapseappappservice-and-synapseappuser_dir-worker-application-types). So did we, at the time." msgstr "" -#: ../../../CHANGELOG.md:1663 +#: ../../../CHANGELOG.md:2315 msgid "The new way to implement such workers is by using a `generic_worker` and dedicating it to the task of serving the user directory. From now on, we have support for this." msgstr "" -#: ../../../CHANGELOG.md:1665 +#: ../../../CHANGELOG.md:2317 msgid "With `matrix_synapse_workers_preset: one-of-each`, you'll get one `user_dir` worker automatically. You can also control the `user_dir` workers count with `matrix_synapse_workers_user_dir_workers_count`. Only `0` or `1` workers of this type are supported by Synapse." msgstr "" -#: ../../../CHANGELOG.md:1667 +#: ../../../CHANGELOG.md:2319 msgid "Using more than 1 media repository worker is now more reliable" msgstr "" -#: ../../../CHANGELOG.md:1669 +#: ../../../CHANGELOG.md:2321 msgid "With `matrix_synapse_workers_preset: one-of-each`, we only launch one `media_repository` worker." msgstr "" -#: ../../../CHANGELOG.md:1671 +#: ../../../CHANGELOG.md:2323 msgid "If you've been configuring `matrix_synapse_workers_media_repository_workers_count` manually, you may have increased that to more workers. When multiple media repository workers are in use, background tasks related to the media repository must always be configured to run on a single `media_repository` worker via `media_instance_running_background_jobs`. Until now, we weren't doing this correctly, but we now are." msgstr "" -#: ../../../CHANGELOG.md:1673 +#: ../../../CHANGELOG.md:2325 msgid "Potential Backward Incompatibilities after these Synapse worker changes" msgstr "" -#: ../../../CHANGELOG.md:1675 +#: ../../../CHANGELOG.md:2327 msgid "Below we'll discuss **potential backward incompatibilities**." msgstr "" -#: ../../../CHANGELOG.md:1677 +#: ../../../CHANGELOG.md:2329 msgid "**Worker names** (container names, systemd services, worker configuration files) **have changed**. Workers are now labeled sequentially (e.g. `matrix-synapse-worker_generic_worker-18111` -> `matrix-synapse-worker-generic-0`). The playbook will handle these changes automatically." msgstr "" -#: ../../../CHANGELOG.md:1679 +#: ../../../CHANGELOG.md:2331 msgid "Due to increased worker types support above, people who use `matrix_synapse_workers_preset: one-of-each` should be aware that with these changes, **the playbook will deploy 9 additional workers** (6 stream writers, 1 `appservice` worker, 1 `user_dir` worker, 1 background task worker). This **may increase RAM/CPU usage**, etc. If you find your server struggling, consider disabling some workers with the appropriate `matrix_synapse_workers_*_workers_count` variables." msgstr "" -#: ../../../CHANGELOG.md:1681 +#: ../../../CHANGELOG.md:2333 msgid "**Metric endpoints have also changed** (`/metrics/synapse/worker/generic_worker-18111` -> `/metrics/synapse/worker/generic-worker-0`). If you're [collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server), consider revisiting our [Collecting Synapse worker metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-synapse-worker-metrics-to-an-external-prometheus-server) docs and updating your Prometheus configuration. **If you're collecting metrics to the integrated Prometheus server** (not enabled by default), **your Prometheus configuration will be updated automatically**. Old data (from before this change) may stick around though." msgstr "" -#: ../../../CHANGELOG.md:1683 +#: ../../../CHANGELOG.md:2335 msgid "**the format of `matrix_synapse_workers_enabled_list` has changed**. You were never advised to use this variable for directly creating workers (we advise people to control workers using `matrix_synapse_workers_preset` or by tweaking `matrix_synapse_workers_*_workers_count` variables only), but some people may have started using the `matrix_synapse_workers_enabled_list` variable to gain more control over workers. If you're one of them, you'll need to adjust its value. See `roles/custom/matrix-synapse/defaults/main.yml` for more information on the new format. The playbook will also do basic validation and complain if you got something wrong." msgstr "" -#: ../../../CHANGELOG.md:1686 +#: ../../../CHANGELOG.md:2338 msgid "2022-09-09" msgstr "" -#: ../../../CHANGELOG.md:1688 +#: ../../../CHANGELOG.md:2340 msgid "Cactus Comments support" msgstr "" -#: ../../../CHANGELOG.md:1690 +#: ../../../CHANGELOG.md:2342 msgid "Thanks to [Julian-Samuel Gebühr (@moan0s)](https://github.com/moan0s), the playbook can now set up [Cactus Comments](https://cactus.chat) — federated comment system for the web based on Matrix." msgstr "" -#: ../../../CHANGELOG.md:1692 +#: ../../../CHANGELOG.md:2344 msgid "See our [Setting up Cactus Comments](docs/configuring-playbook-cactus-comments.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1695 +#: ../../../CHANGELOG.md:2347 msgid "2022-08-23" msgstr "" -#: ../../../CHANGELOG.md:1697 +#: ../../../CHANGELOG.md:2349 msgid "Postmoogle email bridge support" msgstr "" -#: ../../../CHANGELOG.md:1699 +#: ../../../CHANGELOG.md:2351 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up the new [Postmoogle](https://github.com/etkecc/postmoogle) email bridge. Postmoogle is like the [Email2Matrix bridge](https://github.com/devture/email2matrix) (also [already supported by the playbook](docs/configuring-playbook-email2matrix.md)), but more capable and with the intention to soon support *sending* emails, not just receiving." msgstr "" -#: ../../../CHANGELOG.md:1701 +#: ../../../CHANGELOG.md:2353 msgid "See our [Setting up Postmoogle email bridging](docs/configuring-playbook-bridge-postmoogle.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1704 +#: ../../../CHANGELOG.md:2356 msgid "2022-08-10" msgstr "" -#: ../../../CHANGELOG.md:1706 +#: ../../../CHANGELOG.md:2358 msgid "mautrix-whatsapp default configuration changes" msgstr "" -#: ../../../CHANGELOG.md:1708 +#: ../../../CHANGELOG.md:2360 msgid "In [Pull Request #2012](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2012), we've made some changes to the default configuration used by the `mautrix-whatsapp` bridge." msgstr "" -#: ../../../CHANGELOG.md:1710 +#: ../../../CHANGELOG.md:2362 msgid "If you're using this bridge, you should look into this PR and see if the new configuration suits you. If not, you can always change individual preferences in your `vars.yml` file." msgstr "" -#: ../../../CHANGELOG.md:1712 +#: ../../../CHANGELOG.md:2364 msgid "Most notably, spaces support has been enabled by default. The bridge will now group rooms into a Matrix space. **If you've already bridged to Whatsapp** prior to this update, you will need to send `!wa sync space` to the bridge bot to make it create the space and put your existing rooms into it." msgstr "" -#: ../../../CHANGELOG.md:1715 +#: ../../../CHANGELOG.md:2367 msgid "2022-08-09" msgstr "" -#: ../../../CHANGELOG.md:1717 +#: ../../../CHANGELOG.md:2369 msgid "Conduit support" msgstr "" -#: ../../../CHANGELOG.md:1719 +#: ../../../CHANGELOG.md:2371 msgid "Thanks to [Charles Wright](https://github.com/cvwright), we now have optional experimental [Conduit](https://conduit.rs) homeserver support for new installations. This comes as a follow-up to the playbook getting [Dendrite support](#dendrite-support) earlier this year." msgstr "" -#: ../../../CHANGELOG.md:1721 +#: ../../../CHANGELOG.md:2373 msgid "Existing Synapse or Dendrite installations do **not** need to be updated. **Synapse is still the default homeserver implementation** installed by the playbook." msgstr "" -#: ../../../CHANGELOG.md:1723 +#: ../../../CHANGELOG.md:2375 msgid "To try out Conduit, we recommend that you **use a new server** and the following `vars.yml` configuration:" msgstr "" -#: ../../../CHANGELOG.md:1729 +#: ../../../CHANGELOG.md:2381 msgid "**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse or Dendrite to Conduit) without data loss." msgstr "" -#: ../../../CHANGELOG.md:1732 +#: ../../../CHANGELOG.md:2384 msgid "2022-07-29" msgstr "" -#: ../../../CHANGELOG.md:1734 +#: ../../../CHANGELOG.md:2386 msgid "mautrix-discord support" msgstr "" -#: ../../../CHANGELOG.md:1736 +#: ../../../CHANGELOG.md:2388 msgid "Thanks to [MdotAmaan](https://github.com/MdotAmaan)'s efforts, the playbook now supports bridging to [Discord](https://discordapp.com/) via the [mautrix-discord](https://mau.dev/mautrix/discord) bridge. See our [Setting up Mautrix Discord bridging](docs/configuring-playbook-bridge-mautrix-discord.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:1738 +#: ../../../CHANGELOG.md:2390 msgid "**Note**: this is a new Discord bridge. The playbook still retains Discord bridging via [matrix-appservice-discord](docs/configuring-playbook-bridge-appservice-discord.md) and [mx-puppet-discord](docs/configuring-playbook-bridge-mx-puppet-discord.md). You're free to use the bridge that serves you better, or even all three of them (for different users and use-cases)." msgstr "" -#: ../../../CHANGELOG.md:1741 +#: ../../../CHANGELOG.md:2393 msgid "2022-07-27" msgstr "" -#: ../../../CHANGELOG.md:1743 +#: ../../../CHANGELOG.md:2395 msgid "matrix-appservice-kakaotalk support" msgstr "" -#: ../../../CHANGELOG.md:1745 +#: ../../../CHANGELOG.md:2397 msgid "The playbook now supports bridging to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG) via [matrix-appservice-kakaotalk](https://src.miscworks.net/fair/matrix-appservice-kakaotalk) — a bridge based on [node-kakao](https://github.com/storycraft/node-kakao) (now unmaintained) and some [mautrix-facebook](https://github.com/mautrix/facebook) code. Thanks to [hnarjis](https://github.com/hnarjis) for helping us add support for this!" msgstr "" -#: ../../../CHANGELOG.md:1747 +#: ../../../CHANGELOG.md:2399 msgid "See our [Setting up Appservice Kakaotalk bridging](docs/configuring-playbook-bridge-appservice-kakaotalk.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1750 +#: ../../../CHANGELOG.md:2402 msgid "2022-07-20" msgstr "" -#: ../../../CHANGELOG.md:1752 +#: ../../../CHANGELOG.md:2404 msgid "maubot support" msgstr "" -#: ../../../CHANGELOG.md:1754 +#: ../../../CHANGELOG.md:2406 msgid "Thanks to [Stuart Mumford (@Cadair)](https://github.com/cadair) for starting ([PR #373](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/373) and [PR #622](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/622)) and to [Julian-Samuel Gebühr (@moan0s)](https://github.com/moan0s) for finishing up (in [PR #1894](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1894)), the playbook can now help you set up [maubot](https://github.com/maubot/maubot) — a plugin-based Matrix bot system." msgstr "" -#: ../../../CHANGELOG.md:1756 +#: ../../../CHANGELOG.md:2408 msgid "See our [Setting up maubot](docs/configuring-playbook-bot-maubot.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1759 +#: ../../../CHANGELOG.md:2411 msgid "2022-07-14" msgstr "" -#: ../../../CHANGELOG.md:1761 +#: ../../../CHANGELOG.md:2413 msgid "mx-puppet-skype removal" msgstr "" -#: ../../../CHANGELOG.md:1763 +#: ../../../CHANGELOG.md:2415 msgid "The playbook no longer includes the [mx-puppet-skype](https://github.com/Sorunome/mx-puppet-skype) bridge, because it has been broken and unmaintained for a long time. Users that have `matrix_mx_puppet_skype_enabled` in their configuration files will encounter an error when running the playbook until they remove references to this bridge from their configuration." msgstr "" -#: ../../../CHANGELOG.md:1765 +#: ../../../CHANGELOG.md:2417 msgid "To completely clean up your server from `mx-puppet-skype`'s presence on it:" msgstr "" -#: ../../../CHANGELOG.md:1767 +#: ../../../CHANGELOG.md:2419 msgid "ensure your Ansible configuration (`vars.yml` file) no longer contains `matrix_mx_puppet_skype_*` references" msgstr "" -#: ../../../CHANGELOG.md:1768 +#: ../../../CHANGELOG.md:2420 msgid "stop and disable the systemd service (run `systemctl disable --now matrix-mx-puppet-skype` on the server)" msgstr "" -#: ../../../CHANGELOG.md:1769 +#: ../../../CHANGELOG.md:2421 msgid "delete the systemd service (run `rm /etc/systemd/system/matrix-mx-puppet-skype.service` on the server)" msgstr "" -#: ../../../CHANGELOG.md:1770 +#: ../../../CHANGELOG.md:2422 msgid "delete `/matrix/mx-puppet-skype` (run `rm -rf /matrix/mx-puppet-skype` on the server)" msgstr "" -#: ../../../CHANGELOG.md:1771 +#: ../../../CHANGELOG.md:2423 msgid "drop the `matrix_mx_puppet_skype` database (run `/usr/local/bin/matrix-postgres-cli` on the server, and execute the `DROP DATABASE matrix_mx_puppet_skype;` query there)" msgstr "" -#: ../../../CHANGELOG.md:1773 +#: ../../../CHANGELOG.md:2425 msgid "If you still need bridging to [Skype](https://www.skype.com/), consider switching to [go-skype-bridge](https://github.com/kelaresg/go-skype-bridge) instead. See [Setting up Go Skype Bridge bridging](docs/configuring-playbook-bridge-go-skype-bridge.md)." msgstr "" -#: ../../../CHANGELOG.md:1775 +#: ../../../CHANGELOG.md:2427 msgid "If you think this is a mistake and `mx-puppet-skype` works for you (or you get it to work somehow), let us know and we may reconsider this removal." msgstr "" -#: ../../../CHANGELOG.md:1777 +#: ../../../CHANGELOG.md:2429 msgid "signald (0.19.0+) upgrade requires data migration" msgstr "" -#: ../../../CHANGELOG.md:1779 +#: ../../../CHANGELOG.md:2431 msgid "In [Pull Request #1921](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1921) we upgraded [signald](https://signald.org/) (used by the mautrix-signal bridge) from `v0.18.5` to `v0.20.0`." msgstr "" -#: ../../../CHANGELOG.md:1781 +#: ../../../CHANGELOG.md:2433 msgid "Back in the [`v0.19.0` released of signald](https://gitlab.com/signald/signald/-/blob/main/releases/0.19.0.md) (which we skipped and migrated straight to `v0.20.0`), a new `--migrate-data` command had been added that migrates avatars, group images, attachments, etc., into the database (those were previously stored in the filesystem)." msgstr "" -#: ../../../CHANGELOG.md:1783 +#: ../../../CHANGELOG.md:2435 msgid "If you've been using the mautrix-signal bridge for a while, you may have files stored in the local filesystem, which will need to be upgraded." msgstr "" -#: ../../../CHANGELOG.md:1785 +#: ../../../CHANGELOG.md:2437 msgid "We attempt to do this data migration automatically every time Signald starts (`matrix-mautrix-signal-daemon.service`) using a `ExecStartPre` systemd unit definition." msgstr "" -#: ../../../CHANGELOG.md:1787 +#: ../../../CHANGELOG.md:2439 msgid "Keep an eye on your Signal bridge and let us know (in our [support room](README.md#support) or in [Pull Request #1921](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1921)) if you experience any trouble!" msgstr "" -#: ../../../CHANGELOG.md:1790 +#: ../../../CHANGELOG.md:2442 msgid "2022-07-05" msgstr "" -#: ../../../CHANGELOG.md:1792 +#: ../../../CHANGELOG.md:2444 msgid "Ntfy push notifications support" msgstr "" -#: ../../../CHANGELOG.md:1794 +#: ../../../CHANGELOG.md:2446 msgid "Thanks to [Julian Foad](https://matrix.to/#/@julian:foad.me.uk), the playbook can now install a [ntfy](https://ntfy.sh/) push notifications server for you." msgstr "" -#: ../../../CHANGELOG.md:1796 +#: ../../../CHANGELOG.md:2448 msgid "See our [Setting up the ntfy push notifications server](docs/configuring-playbook-ntfy.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1799 +#: ../../../CHANGELOG.md:2451 msgid "2022-06-23" msgstr "" -#: ../../../CHANGELOG.md:1801 +#: ../../../CHANGELOG.md:2453 msgid "(Potential Backward Compatibility Break) Changes around metrics collection" msgstr "" -#: ../../../CHANGELOG.md:1803 +#: ../../../CHANGELOG.md:2455 msgid "**TLDR**: we've made extensive **changes to metrics exposure/collection, which concern people using an external Prometheus server**. If you don't know what that is, you don't need to read below." msgstr "" -#: ../../../CHANGELOG.md:1805 +#: ../../../CHANGELOG.md:2457 msgid "**Why do major changes to metrics**? Because various services were exposing metrics in different, hacky, ways. Synapse was exposing metrics at `/_synapse/metrics` and `/_synapse-worker-…/metrics` on the `matrix.example.com`. The Hookshot role was **repurposing** the Granana web UI domain (`stats.example.com`) for exposing its metrics on `stats.example.com/hookshot/metrics`, while protecting these routes using Basic Authentication **normally used for Synapse** (`/_synapse/metrics`). Node-exporter and Postgres-exporter roles were advising for more `stats.example.com` usage in manual ways. Each role was doing things differently and mixing variables from other roles. Each metrics endpoint was ending up in a different place, protected by who knows what Basic Authentication credentials (if protected at all)." msgstr "" -#: ../../../CHANGELOG.md:1807 +#: ../../../CHANGELOG.md:2459 msgid "**The solution**: a completely revamped way to expose metrics to an external Prometheus server. We are **introducing new `https://matrix.example.com/metrics/*` endpoints**, where various services *can* expose their metrics, for collection by external Prometheus servers. To enable the `/metrics/*` endpoints, use `matrix_nginx_proxy_proxy_matrix_metrics_enabled: true`. There's also a way to protect access using [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). See the `matrix-nginx-proxy` role or our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation for additional variables around `matrix_nginx_proxy_proxy_matrix_metrics_enabled`." msgstr "" -#: ../../../CHANGELOG.md:1809 +#: ../../../CHANGELOG.md:2461 msgid "**If you are using the [Hookshot bridge](docs/configuring-playbook-bridge-hookshot.md)**, you may find that:" msgstr "" -#: ../../../CHANGELOG.md:1810 +#: ../../../CHANGELOG.md:2462 msgid "**Metrics may not be enabled by default anymore**:" msgstr "" -#: ../../../CHANGELOG.md:1811 +#: ../../../CHANGELOG.md:2463 msgid "If Prometheus is enabled (`prometheus_enabled: true`), then Hookshot metrics will be enabled automatically (`matrix_hookshot_metrics_enabled: true`). These metrics will be collected from the local (in-container) Prometheus over the container network." msgstr "" -#: ../../../CHANGELOG.md:1812 +#: ../../../CHANGELOG.md:2464 msgid "**If Prometheus is not enabled** (you are either not using Prometheus or are using an external one), **Hookshot metrics will not be enabled by default anymore**. Feel free to enable them by setting `matrix_hookshot_metrics_enabled: true`. Also, see below." msgstr "" -#: ../../../CHANGELOG.md:1813 +#: ../../../CHANGELOG.md:2465 msgid "When metrics are meant to be **consumed by an external Prometheus server**, `matrix_hookshot_metrics_proxying_enabled` needs to be set to `true`, so that metrics would be exposed (proxied) \"publicly\" on `https://matrix.example.com/metrics/hookshot`. To make use of this, you'll also need to enable the new `https://matrix.example.com/metrics/*` endpoints mentioned above, using `matrix_nginx_proxy_proxy_matrix_metrics_enabled`. Learn more in our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation." msgstr "" -#: ../../../CHANGELOG.md:1814 +#: ../../../CHANGELOG.md:2466 msgid "**We've changed the URL we're exposing Hookshot metrics at** for external Prometheus servers. Until now, you were advised to consume Hookshot metrics from `https://stats.example.com/hookshot/metrics` (working in conjunction with `matrix_nginx_proxy_proxy_synapse_metrics`). From now on, **this no longer works**. As described above, you need to start consuming metrics from `https://matrix.example.com/metrics/hookshot`." msgstr "" -#: ../../../CHANGELOG.md:1816 +#: ../../../CHANGELOG.md:2468 msgid "**If you're using node-exporter** (`matrix_prometheus_node_exporter_enabled: true`) and would like to collect its metrics from an external Prometheus server, see `matrix_prometheus_node_exporter_metrics_proxying_enabled` described in our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation. You will be able to collect its metrics from `https://matrix.example.com/metrics/node-exporter`." msgstr "" -#: ../../../CHANGELOG.md:1818 -msgid "**If you're using [postgres-exporter](docs/configuring-playbook-prometheus-postgres.md)** (`prometheus_postgres_exporter_enabled: true`) and would like to collect its metrics from an external Prometheus server, see `matrix_prometheus_services_proxy_connect_prometheus_postgres_exporter_metrics_proxying_enabled` described in our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation. You will be able to collect its metrics from `https://matrix.example.com/metrics/postgres-exporter`." +#: ../../../CHANGELOG.md:2470 +msgid "**If you're using [postgres-exporter](docs/configuring-playbook-prometheus-grafana.md#enable-metrics-and-graphs-for-postgres-optional)** (`prometheus_postgres_exporter_enabled: true`) and would like to collect its metrics from an external Prometheus server, see `matrix_prometheus_services_proxy_connect_prometheus_postgres_exporter_metrics_proxying_enabled` described in our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation. You will be able to collect its metrics from `https://matrix.example.com/metrics/postgres-exporter`." msgstr "" -#: ../../../CHANGELOG.md:1820 +#: ../../../CHANGELOG.md:2472 msgid "**If you're using Synapse** and would like to collect its metrics from an external Prometheus server, you may find that:" msgstr "" -#: ../../../CHANGELOG.md:1822 +#: ../../../CHANGELOG.md:2474 msgid "Exposing metrics is now done using `matrix_synapse_metrics_proxying_enabled`, not `matrix_nginx_proxy_proxy_synapse_metrics: true`. You may still need to enable metrics using `matrix_synapse_metrics_enabled: true` before exposing them." msgstr "" -#: ../../../CHANGELOG.md:1823 +#: ../../../CHANGELOG.md:2475 msgid "Protecting metrics endpoints using [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) is now done in another way. See our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation" msgstr "" -#: ../../../CHANGELOG.md:1824 +#: ../../../CHANGELOG.md:2476 msgid "If Synapse metrics are exposed, they will be made available at `https://matrix.example.com/metrics/synapse/main-process` or `https://matrix.example.com/metrics/synapse/worker/TYPE-ID` (when workers are enabled), not at `https://matrix.example.com/_synapse/metrics` and `https://matrix.example.com/_synapse-worker-…/metrics`" msgstr "" -#: ../../../CHANGELOG.md:1825 +#: ../../../CHANGELOG.md:2477 msgid "The playbook still generates an `external_prometheus.yml.example` sample file for scraping Synapse from Prometheus as described in [Collecting Synapse worker metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-synapse-worker-metrics-to-an-external-prometheus-server), but it's now saved under `/matrix/synapse` (not `/matrix`)." msgstr "" -#: ../../../CHANGELOG.md:1827 +#: ../../../CHANGELOG.md:2479 msgid "**If you where already using a external Prometheus server** before this change, and you gave a hashed version of the password as a variable, the playbook will now take care of hashing the password for you. Thus, you need to provide the non-hashed version now." msgstr "" -#: ../../../CHANGELOG.md:1829 +#: ../../../CHANGELOG.md:2481 msgid "2022-06-13" msgstr "" -#: ../../../CHANGELOG.md:1831 +#: ../../../CHANGELOG.md:2483 msgid "go-skype-bridge bridging support" msgstr "" -#: ../../../CHANGELOG.md:1833 +#: ../../../CHANGELOG.md:2485 msgid "Thanks to [CyberShadow](https://github.com/CyberShadow), the playbook can now install the [go-skype-bridge](https://github.com/kelaresg/go-skype-bridge) bridge for bridging Matrix to [Skype](https://www.skype.com/)." msgstr "" -#: ../../../CHANGELOG.md:1835 +#: ../../../CHANGELOG.md:2487 msgid "See our [Setting up Go Skype Bridge bridging](docs/configuring-playbook-bridge-go-skype-bridge.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1837 +#: ../../../CHANGELOG.md:2489 msgid "The playbook has supported [mx-puppet-skype](https://github.com/Sorunome/mx-puppet-skype) bridging (see [Setting up MX Puppet Skype bridging](docs/configuring-playbook-bridge-mx-puppet-skype.md)) since [2020-04-09](#2020-04-09), but `mx-puppet-skype` is reportedly broken." msgstr "" -#: ../../../CHANGELOG.md:1840 +#: ../../../CHANGELOG.md:2492 msgid "2022-06-09" msgstr "" -#: ../../../CHANGELOG.md:1842 +#: ../../../CHANGELOG.md:2494 msgid "Running Ansible in a container can now happen on the Matrix server itself" msgstr "" -#: ../../../CHANGELOG.md:1844 +#: ../../../CHANGELOG.md:2496 msgid "If you're tired of being on an old and problematic Ansible version, you can now run [run Ansible in a container on the Matrix server itself](docs/ansible.md#running-ansible-in-a-container-on-the-matrix-server-itself)." msgstr "" -#: ../../../CHANGELOG.md:1847 +#: ../../../CHANGELOG.md:2499 msgid "2022-05-31" msgstr "" -#: ../../../CHANGELOG.md:1849 +#: ../../../CHANGELOG.md:2501 msgid "Synapse v1.60 upgrade may cause trouble and require manual intervention" msgstr "" -#: ../../../CHANGELOG.md:1851 +#: ../../../CHANGELOG.md:2503 msgid "Synapse v1.60 will try to add a new unique index to `state_group_edges` upon startup and could fail if your database is corrupted." msgstr "" -#: ../../../CHANGELOG.md:1853 +#: ../../../CHANGELOG.md:2505 msgid "We haven't observed this problem yet, but [the Synapse v1.60.0 upgrade notes](https://github.com/element-hq/synapse/blob/v1.60.0/docs/upgrade.md#adding-a-new-unique-index-to-state_group_edges-could-fail-if-your-database-is-corrupted) mention it, so we're giving you a heads up here in case you're unlucky." msgstr "" -#: ../../../CHANGELOG.md:1855 +#: ../../../CHANGELOG.md:2507 msgid "**If Synapse fails to start** after your next playbook run, you'll need to:" msgstr "" -#: ../../../CHANGELOG.md:1857 +#: ../../../CHANGELOG.md:2509 msgid "SSH into the Matrix server" msgstr "" -#: ../../../CHANGELOG.md:1858 +#: ../../../CHANGELOG.md:2510 msgid "launch `/usr/local/bin/matrix-postgres-cli`" msgstr "" -#: ../../../CHANGELOG.md:1859 +#: ../../../CHANGELOG.md:2511 msgid "switch to the `synapse` database: `\\c synapse`" msgstr "" -#: ../../../CHANGELOG.md:1860 +#: ../../../CHANGELOG.md:2512 msgid "run the following SQL query:" msgstr "" -#: ../../../CHANGELOG.md:1879 +#: ../../../CHANGELOG.md:2531 msgid "You could then restart services: `ansible-playbook -i inventory/hosts setup.yml --tags=start`" msgstr "" -#: ../../../CHANGELOG.md:1882 +#: ../../../CHANGELOG.md:2534 msgid "2022-04-25" msgstr "" -#: ../../../CHANGELOG.md:1884 +#: ../../../CHANGELOG.md:2536 msgid "Buscarron bot support" msgstr "" -#: ../../../CHANGELOG.md:1886 +#: ../../../CHANGELOG.md:2538 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up [the Buscarron bot](https://github.com/etkecc/buscarron). It's a bot you can use to send any form (HTTP POST, HTML) to a (encrypted) Matrix room" msgstr "" -#: ../../../CHANGELOG.md:1888 +#: ../../../CHANGELOG.md:2540 msgid "See our [Setting up Buscarron](docs/configuring-playbook-bot-buscarron.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1891 +#: ../../../CHANGELOG.md:2543 msgid "2022-04-21" msgstr "" -#: ../../../CHANGELOG.md:1893 +#: ../../../CHANGELOG.md:2545 msgid "matrix-registration-bot support" msgstr "" -#: ../../../CHANGELOG.md:1895 +#: ../../../CHANGELOG.md:2547 msgid "Thanks to [Julian-Samuel Gebühr (@moan0s)](https://github.com/moan0s), the playbook can now help you set up [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot) — a bot that is used to create and manage registration tokens for a Matrix server." msgstr "" -#: ../../../CHANGELOG.md:1897 +#: ../../../CHANGELOG.md:2549 msgid "See our [Setting up matrix-registration-bot](docs/configuring-playbook-bot-matrix-registration-bot.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1900 +#: ../../../CHANGELOG.md:2552 msgid "2022-04-19" msgstr "" -#: ../../../CHANGELOG.md:1902 +#: ../../../CHANGELOG.md:2554 msgid "BorgBackup support" msgstr "" -#: ../../../CHANGELOG.md:1904 +#: ../../../CHANGELOG.md:2556 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up [Borg](https://www.borgbackup.org/) backups with [borgmatic](https://torsion.org/borgmatic/) of your Matrix server." msgstr "" -#: ../../../CHANGELOG.md:1906 +#: ../../../CHANGELOG.md:2558 msgid "See our [Setting up BorgBackup](docs/configuring-playbook-backup-borg.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1908 +#: ../../../CHANGELOG.md:2560 msgid "(Compatibility Break) Upgrading to Synapse v1.57 on setups using workers may require manual action" msgstr "" -#: ../../../CHANGELOG.md:1910 +#: ../../../CHANGELOG.md:2562 msgid "If you're running a worker setup for Synapse (`matrix_synapse_workers_enabled: true`), the [Synapse v1.57 upgrade notes](https://github.com/element-hq/synapse/blob/v1.57.0rc1/docs/upgrade.md#changes-to-database-schema-for-application-services) say that you may need to take special care when upgrading:" msgstr "" -#: ../../../CHANGELOG.md:1912 +#: ../../../CHANGELOG.md:2564 msgid "Synapse v1.57.0 includes a change to the way transaction IDs are managed for application services. If your deployment uses a dedicated worker for application service traffic, **it must be stopped** when the database is upgraded (which normally happens when the main process is upgraded), to ensure the change is made safely without any risk of reusing transaction IDs." msgstr "" -#: ../../../CHANGELOG.md:1914 +#: ../../../CHANGELOG.md:2566 msgid "If you're not running an `appservice` worker (`matrix_synapse_workers_preset: little-federation-helper` or `matrix_synapse_workers_appservice_workers_count: 0`), you are probably safe to upgrade as per normal, without taking any special care." msgstr "" -#: ../../../CHANGELOG.md:1916 +#: ../../../CHANGELOG.md:2568 msgid "If you are running a setup with an `appservice` worker, or otherwise want to be on the safe side, we recommend the following upgrade path:" msgstr "" -#: ../../../CHANGELOG.md:1918 +#: ../../../CHANGELOG.md:2570 msgid "Pull the latest playbook changes" msgstr "" -#: ../../../CHANGELOG.md:1919 +#: ../../../CHANGELOG.md:2571 msgid "Stop all services (`ansible-playbook -i inventory/hosts setup.yml --tags=stop`)" msgstr "" -#: ../../../CHANGELOG.md:1920 +#: ../../../CHANGELOG.md:2572 msgid "Re-run the playbook (`ansible-playbook -i inventory/hosts setup.yml --tags=setup-all`)" msgstr "" -#: ../../../CHANGELOG.md:1921 +#: ../../../CHANGELOG.md:2573 msgid "Start Postgres (`systemctl start matrix-postgres` on the server)" msgstr "" -#: ../../../CHANGELOG.md:1922 +#: ../../../CHANGELOG.md:2574 msgid "Start the main Synapse process (`systemctl start matrix-synapse` on the server)" msgstr "" -#: ../../../CHANGELOG.md:1923 +#: ../../../CHANGELOG.md:2575 msgid "Wait a while so that Synapse can start and complete the database migrations. You can use `journalctl -fu matrix-synapse` on the server to get a clue. Waiting a few minutes should also be enough." msgstr "" -#: ../../../CHANGELOG.md:1924 +#: ../../../CHANGELOG.md:2576 msgid "It should now be safe to start all other services. `ansible-playbook -i inventory/hosts setup.yml --tags=start` will do it for you" msgstr "" -#: ../../../CHANGELOG.md:1927 +#: ../../../CHANGELOG.md:2579 msgid "2022-04-14" msgstr "" -#: ../../../CHANGELOG.md:1929 +#: ../../../CHANGELOG.md:2581 msgid "(Compatibility Break) Changes to `docker-src` permissions necessitating manual action" msgstr "" -#: ../../../CHANGELOG.md:1931 +#: ../../../CHANGELOG.md:2583 msgid "Users who build container images from source will need to manually correct file permissions of some directories on the server." msgstr "" -#: ../../../CHANGELOG.md:1933 +#: ../../../CHANGELOG.md:2585 msgid "When self-building, the playbook used to `git clone` repositories (into `/matrix/SERVICE/docker-src`) using the `root` user, but now uses `matrix` instead to work around [the following issue with git 2.35.2](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1749)." msgstr "" -#: ../../../CHANGELOG.md:1935 +#: ../../../CHANGELOG.md:2587 msgid "If you're on a non-`amd64` architecture (that is, you're overriding `matrix_architecture` in your `vars.yml` file) or you have enabled self-building for some service (e.g. `matrix_*_self_build: true`), you're certainly building some container images from source and have `docker-src` directories with mixed permissions lying around in various `/matrix/SERVICE` directories." msgstr "" -#: ../../../CHANGELOG.md:1937 +#: ../../../CHANGELOG.md:2589 msgid "The playbook *could* correct these permissions automatically, but that requires additional Ansible tasks in some ~45 different places — something that takes considerable effort. So we ask users observing errors related to `docker-src` directories to correct the problem manually by **running this command on the Matrix server** (which deletes all `/matrix/*/docker-src` directories): `find /matrix -maxdepth 2 -name 'docker-src' | xargs rm -rf`" msgstr "" -#: ../../../CHANGELOG.md:1940 +#: ../../../CHANGELOG.md:2592 msgid "2022-03-17" msgstr "" -#: ../../../CHANGELOG.md:1942 +#: ../../../CHANGELOG.md:2594 msgid "(Compatibility Break) ma1sd identity server no longer installed by default" msgstr "" -#: ../../../CHANGELOG.md:1944 +#: ../../../CHANGELOG.md:2596 msgid "The playbook no longer installs the [ma1sd](https://github.com/ma1uta/ma1sd) identity server by default. The next time you run the playbook, ma1sd will be uninstalled from your server, unless you explicitly enable the ma1sd service (see how below)." msgstr "" -#: ../../../CHANGELOG.md:1946 +#: ../../../CHANGELOG.md:2598 msgid "The main reason we used to install ma1sd by default in the past was to prevent Element clients from talking to the `matrix.org` / `vector.im` identity servers, by forcing it to talk to our own self-hosted (but otherwise useless) identity server instead, thus preventing contact list leaks." msgstr "" -#: ../../../CHANGELOG.md:1948 +#: ../../../CHANGELOG.md:2600 msgid "Since Element clients no longer default to using a public identity server if another one is not provided, we can stop installing ma1sd." msgstr "" -#: ../../../CHANGELOG.md:1950 +#: ../../../CHANGELOG.md:2602 msgid "If you need to install the ma1sd identity server for some reason, you can explicitly enable it by adding this to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:1957 +#: ../../../CHANGELOG.md:2609 msgid "2022-02-12" msgstr "" -#: ../../../CHANGELOG.md:1959 +#: ../../../CHANGELOG.md:2611 msgid "matrix_encryption_disabler support" msgstr "" -#: ../../../CHANGELOG.md:1961 +#: ../../../CHANGELOG.md:2613 msgid "We now support installing the [matrix_encryption_disabler](https://github.com/digitalentity/matrix_encryption_disabler) Synapse module, which lets you prevent End-to-End-Encryption from being enabled by users on your homeserver. The popular opinion is that this is dangerous and shouldn't be done, but there are valid use cases for disabling encryption discussed [here](https://github.com/matrix-org/synapse/issues/4401)." msgstr "" -#: ../../../CHANGELOG.md:1963 +#: ../../../CHANGELOG.md:2615 msgid "To enable this module (and prevent encryption from being used on your homserver), add `matrix_synapse_ext_encryption_disabler_enabled: true` to your configuration. This module provides further customization. Check its other configuration settings (and defaults) in `roles/custom/matrix-synapse/defaults/main.yml`." msgstr "" -#: ../../../CHANGELOG.md:1966 +#: ../../../CHANGELOG.md:2618 msgid "2022-02-01" msgstr "" -#: ../../../CHANGELOG.md:1968 +#: ../../../CHANGELOG.md:2620 msgid "matrix-hookshot bridging support" msgstr "" -#: ../../../CHANGELOG.md:1970 +#: ../../../CHANGELOG.md:2622 msgid "Thanks to [HarHarLinks](https://github.com/HarHarLinks), the playbook can now install the [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) bridge for bridging Matrix to multiple project management services, such as GitHub, GitLab and JIRA. See our [Setting up matrix-hookshot](docs/configuring-playbook-bridge-hookshot.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1973 +#: ../../../CHANGELOG.md:2625 msgid "2022-01-31" msgstr "" -#: ../../../CHANGELOG.md:1975 +#: ../../../CHANGELOG.md:2627 msgid "ARM support for matrix-corporal" msgstr "" -#: ../../../CHANGELOG.md:1977 +#: ../../../CHANGELOG.md:2629 msgid "[matrix-corporal](https://github.com/devture/matrix-corporal) (as of version `2.2.3`) is now published to Docker Hub (see [devture/matrix-corporal](https://hub.docker.com/r/devture/matrix-corporal)) as a multi-arch container image with support for all these platforms: `linux/amd64`, `linux/arm64/v8` and `linux/arm/v7`. The playbook no longer resorts to self-building matrix-corporal on these ARM architectures." msgstr "" -#: ../../../CHANGELOG.md:1980 +#: ../../../CHANGELOG.md:2632 msgid "2022-01-07" msgstr "" -#: ../../../CHANGELOG.md:1982 +#: ../../../CHANGELOG.md:2634 msgid "Dendrite support" msgstr "" -#: ../../../CHANGELOG.md:1984 +#: ../../../CHANGELOG.md:2636 msgid "**TLDR**: We now have optional experimental [Dendrite](https://github.com/matrix-org/dendrite) homeserver support for new installations. **Existing (Synapse) installations need to be updated**, because some internals changed. See [Adapting the configuration for existing Synapse installations](#adapting-the-configuration-for-existing-synapse-installations)." msgstr "" -#: ../../../CHANGELOG.md:1986 +#: ../../../CHANGELOG.md:2638 msgid "[Jip J. Dekker](https://github.com/Dekker1) did the [initial work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/818) of adding [Dendrite](https://github.com/matrix-org/dendrite) support to the playbook back in January 2021. Lots of work (and time) later, Dendrite support is finally ready for testing." msgstr "" -#: ../../../CHANGELOG.md:1988 +#: ../../../CHANGELOG.md:2640 msgid "We believe that 2022 will be the year of the non-Synapse Matrix server!" msgstr "" -#: ../../../CHANGELOG.md:1990 +#: ../../../CHANGELOG.md:2642 msgid "The playbook was previously quite [Synapse](https://github.com/element-hq/synapse)-centric, but can now accommodate multiple homeserver implementations. Only one homeserver implementation can be active (installed) at a given time." msgstr "" -#: ../../../CHANGELOG.md:1992 +#: ../../../CHANGELOG.md:2644 msgid "**Synapse is still the default homeserver implementation** installed by the playbook. A new variable (`matrix_homeserver_implementation`) controls which server implementation is enabled (`synapse` or `dendrite` at the given moment)." msgstr "" -#: ../../../CHANGELOG.md:1994 +#: ../../../CHANGELOG.md:2646 msgid "Adapting the configuration for existing Synapse installations" msgstr "" -#: ../../../CHANGELOG.md:1996 +#: ../../../CHANGELOG.md:2648 msgid "Because the playbook is not so Synapse-centric anymore, a small configuration change is necessary for existing installations to bring them up to date." msgstr "" -#: ../../../CHANGELOG.md:1998 +#: ../../../CHANGELOG.md:2650 msgid "The `vars.yml` file for **existing installations will need to be updated** by adding this **additional configuration**:" msgstr "" -#: ../../../CHANGELOG.md:2010 +#: ../../../CHANGELOG.md:2662 msgid "Trying out Dendrite" msgstr "" -#: ../../../CHANGELOG.md:2012 +#: ../../../CHANGELOG.md:2664 msgid "Finally, **to try out Dendrite**, we recommend that you **use a new server** and the following addition to your `vars.yml` configuration:" msgstr "" -#: ../../../CHANGELOG.md:2018 +#: ../../../CHANGELOG.md:2670 msgid "**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse to Dendrite) without data loss." msgstr "" -#: ../../../CHANGELOG.md:2020 +#: ../../../CHANGELOG.md:2672 msgid "We're excited to gain support for other homeserver implementations, like [Conduit](https://conduit.rs/), etc!" msgstr "" -#: ../../../CHANGELOG.md:2022 +#: ../../../CHANGELOG.md:2674 msgid "Honoroit bot support" msgstr "" -#: ../../../CHANGELOG.md:2024 +#: ../../../CHANGELOG.md:2676 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now help you set up [Honoroit](https://github.com/etkecc/honoroit) — a helpdesk bot." msgstr "" -#: ../../../CHANGELOG.md:2026 +#: ../../../CHANGELOG.md:2678 msgid "See our [Setting up Honoroit](docs/configuring-playbook-bot-honoroit.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2029 +#: ../../../CHANGELOG.md:2681 msgid "2022-01-06" msgstr "" -#: ../../../CHANGELOG.md:2031 +#: ../../../CHANGELOG.md:2683 msgid "Cinny support" msgstr "" -#: ../../../CHANGELOG.md:2033 +#: ../../../CHANGELOG.md:2685 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook now supports [Cinny](https://cinny.in/) — a new simple, elegant and secure Matrix client." msgstr "" -#: ../../../CHANGELOG.md:2035 +#: ../../../CHANGELOG.md:2687 msgid "By default, we still install Element Web. Still, people who'd like to try Cinny out can now install it via the playbook." msgstr "" -#: ../../../CHANGELOG.md:2037 +#: ../../../CHANGELOG.md:2689 msgid "Additional details are available in [Setting up Cinny](docs/configuring-playbook-client-cinny.md)." msgstr "" -#: ../../../CHANGELOG.md:2040 +#: ../../../CHANGELOG.md:2692 msgid "2021-12-22" msgstr "" -#: ../../../CHANGELOG.md:2042 +#: ../../../CHANGELOG.md:2694 msgid "Twitter bridging support via mautrix-twitter" msgstr "" -#: ../../../CHANGELOG.md:2044 +#: ../../../CHANGELOG.md:2696 msgid "Thanks to [Matthew Cengia](https://github.com/mattcen) and [Shreyas Ajjarapu](https://github.com/shreyasajj), besides [mx-puppet-twitter](docs/configuring-playbook-bridge-mx-puppet-twitter.md), bridging to [Twitter](https://twitter.com/) can now also happen with [mautrix-twitter](docs/configuring-playbook-bridge-mautrix-twitter.md)." msgstr "" -#: ../../../CHANGELOG.md:2047 +#: ../../../CHANGELOG.md:2699 msgid "2021-12-14" msgstr "" -#: ../../../CHANGELOG.md:2049 +#: ../../../CHANGELOG.md:2701 msgid "(Security) Users of the Signal bridge may wish to upgrade it to work around log4j vulnerability" msgstr "" -#: ../../../CHANGELOG.md:2051 +#: ../../../CHANGELOG.md:2703 msgid "Recently, a security vulnerability affecting the Java logging package `log4j` [has been discovered](https://www.huntress.com/blog/rapid-response-critical-rce-vulnerability-is-affecting-java). Software that uses this Java package is potentially vulnerable." msgstr "" -#: ../../../CHANGELOG.md:2053 +#: ../../../CHANGELOG.md:2705 msgid "One such piece of software that is part of the playbook is the [mautrix-signal bridge](./docs/configuring-playbook-bridge-mautrix-signal.md), which [has been patched already](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1452). If you're running this bridge, you may wish to [upgrade](./docs/maintenance-upgrading-services.md)." msgstr "" -#: ../../../CHANGELOG.md:2056 +#: ../../../CHANGELOG.md:2708 msgid "2021-11-11" msgstr "" -#: ../../../CHANGELOG.md:2058 +#: ../../../CHANGELOG.md:2710 msgid "Dropped support for Postgres v9.6" msgstr "" -#: ../../../CHANGELOG.md:2060 +#: ../../../CHANGELOG.md:2712 msgid "Postgres v9.6 reached its end of life today, so the playbook will refuse to run for you if you're still on that version." msgstr "" -#: ../../../CHANGELOG.md:2062 +#: ../../../CHANGELOG.md:2714 msgid "Synapse still supports v9.6 (for now), but we're retiring support for it early, to avoid having to maintain support for so many Postgres versions. Users that are still on Postgres v9.6 can easily [upgrade Postgres](docs/maintenance-postgres.md#upgrading-postgresql) via the playbook." msgstr "" -#: ../../../CHANGELOG.md:2065 +#: ../../../CHANGELOG.md:2717 msgid "2021-10-23" msgstr "" -#: ../../../CHANGELOG.md:2067 +#: ../../../CHANGELOG.md:2719 msgid "Hangouts bridge no longer updated, superseded by a Googlechat bridge" msgstr "" -#: ../../../CHANGELOG.md:2069 +#: ../../../CHANGELOG.md:2721 msgid "The mautrix-hangouts bridge is no longer receiving updates upstream and is likely to stop working in the future. We still retain support for this bridge in the playbook, but you're encouraged to switch away from it." msgstr "" -#: ../../../CHANGELOG.md:2071 +#: ../../../CHANGELOG.md:2723 msgid "There's a new [mautrix-googlechat](https://github.com/mautrix/googlechat) bridge that you can [install using the playbook](docs/configuring-playbook-bridge-mautrix-googlechat.md). Your **Hangouts bridge data will not be migrated**, however. You need to start fresh with the new bridge." msgstr "" -#: ../../../CHANGELOG.md:2074 +#: ../../../CHANGELOG.md:2726 msgid "2021-08-23" msgstr "" -#: ../../../CHANGELOG.md:2076 +#: ../../../CHANGELOG.md:2728 msgid "LinkedIn bridging support via beeper-linkedin" msgstr "" -#: ../../../CHANGELOG.md:2078 +#: ../../../CHANGELOG.md:2730 msgid "Thanks to [Alexandar Mechev](https://github.com/apmechev), the playbook can now install the [beeper-linkedin](https://gitlab.com/beeper/linkedin) bridge for bridging to [LinkedIn](https://www.linkedin.com/) Messaging." msgstr "" -#: ../../../CHANGELOG.md:2080 +#: ../../../CHANGELOG.md:2732 msgid "This brings the total number of bridges supported by the playbook up to 20. See all supported bridges [here](docs/configuring-playbook.md#bridging-other-networks)." msgstr "" -#: ../../../CHANGELOG.md:2082 +#: ../../../CHANGELOG.md:2734 msgid "To get started with bridging to LinkedIn, see [Setting up Beeper LinkedIn bridging](docs/configuring-playbook-bridge-beeper-linkedin.md)." msgstr "" -#: ../../../CHANGELOG.md:2085 +#: ../../../CHANGELOG.md:2737 msgid "2021-08-20" msgstr "" -#: ../../../CHANGELOG.md:2087 +#: ../../../CHANGELOG.md:2739 msgid "Sygnal upgraded — ARM support and no longer requires a database" msgstr "" -#: ../../../CHANGELOG.md:2089 +#: ../../../CHANGELOG.md:2741 msgid "The [Sygnal](docs/configuring-playbook-sygnal.md) push gateway has been upgraded from `v0.9.0` to `v0.10.1`." msgstr "" -#: ../../../CHANGELOG.md:2091 +#: ../../../CHANGELOG.md:2743 msgid "This is an optional component for the playbook, so most of our users wouldn't care about this announcement." msgstr "" -#: ../../../CHANGELOG.md:2093 +#: ../../../CHANGELOG.md:2745 msgid "Since this feels like a relatively big (and untested, as of yet) Sygnal change, we're putting up this changelog entry." msgstr "" -#: ../../../CHANGELOG.md:2095 +#: ../../../CHANGELOG.md:2747 msgid "The new version is also available for the ARM architecture. It also no longer requires a database anymore. If you need to downgrade to the previous version, changing `matrix_sygnal_version` or `matrix_sygnal_docker_image` will not be enough, as we've removed the `database` configuration completely. You'd need to switch to an earlier playbook commit." msgstr "" -#: ../../../CHANGELOG.md:2098 +#: ../../../CHANGELOG.md:2750 msgid "2021-05-21" msgstr "" -#: ../../../CHANGELOG.md:2100 +#: ../../../CHANGELOG.md:2752 msgid "Hydrogen support" msgstr "" -#: ../../../CHANGELOG.md:2102 +#: ../../../CHANGELOG.md:2754 msgid "Thanks to [Aaron Raimist](https://github.com/aaronraimist), the playbook now supports [Hydrogen](https://github.com/vector-im/hydrogen-web) — a new lightweight Matrix client with legacy and mobile browser support." msgstr "" -#: ../../../CHANGELOG.md:2104 +#: ../../../CHANGELOG.md:2756 msgid "By default, we still install Element Web, as Hydrogen is still not fully-featured. Still, people who'd like to try Hydrogen out can now install it via the playbook." msgstr "" -#: ../../../CHANGELOG.md:2106 +#: ../../../CHANGELOG.md:2758 msgid "Additional details are available in [Setting up Hydrogen](docs/configuring-playbook-client-hydrogen.md)." msgstr "" -#: ../../../CHANGELOG.md:2109 +#: ../../../CHANGELOG.md:2761 msgid "2021-05-19" msgstr "" -#: ../../../CHANGELOG.md:2111 +#: ../../../CHANGELOG.md:2763 msgid "Heisenbridge support" msgstr "" -#: ../../../CHANGELOG.md:2113 +#: ../../../CHANGELOG.md:2765 msgid "Thanks to [Toni Spets (hifi)](https://github.com/hifi), the playbook now supports bridging to [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) using yet another bridge (besides matrix-appservice-irc), called [Heisenbridge](https://github.com/hifi/heisenbridge)." msgstr "" -#: ../../../CHANGELOG.md:2115 +#: ../../../CHANGELOG.md:2767 msgid "Additional details are available in [Setting up Heisenbridge bouncer-style IRC bridging](docs/configuring-playbook-bridge-heisenbridge.md)." msgstr "" -#: ../../../CHANGELOG.md:2118 +#: ../../../CHANGELOG.md:2770 msgid "2021-04-16" msgstr "" -#: ../../../CHANGELOG.md:2120 +#: ../../../CHANGELOG.md:2772 msgid "Disabling TLSv1 and TLSv1.1 for coturn" msgstr "" -#: ../../../CHANGELOG.md:2122 +#: ../../../CHANGELOG.md:2774 msgid "To improve security, we've [removed TLSv1 and TLSv1.1 support](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/999) from our default [coturn](https://github.com/coturn/coturn) configuration." msgstr "" -#: ../../../CHANGELOG.md:2124 +#: ../../../CHANGELOG.md:2776 msgid "If you need to support old clients, you can re-enable both (or whichever one you need) with the following configuration:" msgstr "" -#: ../../../CHANGELOG.md:2132 +#: ../../../CHANGELOG.md:2784 msgid "2021-04-05" msgstr "" -#: ../../../CHANGELOG.md:2134 +#: ../../../CHANGELOG.md:2786 msgid "Automated local Postgres backup support" msgstr "" -#: ../../../CHANGELOG.md:2136 +#: ../../../CHANGELOG.md:2788 msgid "Thanks to [foxcris](https://github.com/foxcris), the playbook can now make automated local Postgres backups on a fixed schedule using [docker-postgres-backup-local](https://github.com/prodrigestivill/docker-postgres-backup-local)." msgstr "" -#: ../../../CHANGELOG.md:2138 -msgid "Additional details are available in [Setting up postgres backup](docs/configuring-playbook-postgres-backup.md)." +#: ../../../CHANGELOG.md:2790 +msgid "Additional details are available in [Setting up Postgres backup](docs/configuring-playbook-postgres-backup.md)." msgstr "" -#: ../../../CHANGELOG.md:2141 +#: ../../../CHANGELOG.md:2793 msgid "2021-04-03" msgstr "" -#: ../../../CHANGELOG.md:2143 +#: ../../../CHANGELOG.md:2795 msgid "Mjolnir moderation tool (bot) support" msgstr "" -#: ../../../CHANGELOG.md:2145 +#: ../../../CHANGELOG.md:2797 msgid "Thanks to [Aaron Raimist](https://github.com/aaronraimist), the playbook can now install and configure the [Mjolnir](https://github.com/matrix-org/mjolnir) moderation tool (bot)." msgstr "" -#: ../../../CHANGELOG.md:2147 +#: ../../../CHANGELOG.md:2799 msgid "Additional details are available in [Setting up Mjolnir](docs/configuring-playbook-bot-mjolnir.md)." msgstr "" -#: ../../../CHANGELOG.md:2150 +#: ../../../CHANGELOG.md:2802 msgid "2021-03-20" msgstr "" -#: ../../../CHANGELOG.md:2152 +#: ../../../CHANGELOG.md:2804 msgid "Sygnal push gateway support" msgstr "" -#: ../../../CHANGELOG.md:2154 +#: ../../../CHANGELOG.md:2806 msgid "The playbook can now install the [Sygnal](https://github.com/matrix-org/sygnal) push gateway for you." msgstr "" -#: ../../../CHANGELOG.md:2156 +#: ../../../CHANGELOG.md:2808 msgid "This is only useful to people who develop/build their own Matrix client applications." msgstr "" -#: ../../../CHANGELOG.md:2158 +#: ../../../CHANGELOG.md:2810 msgid "Additional details are available in our [Setting up the Sygnal push gateway](docs/configuring-playbook-sygnal.md) docs." msgstr "" -#: ../../../CHANGELOG.md:2161 +#: ../../../CHANGELOG.md:2813 msgid "2021-03-16" msgstr "" -#: ../../../CHANGELOG.md:2163 +#: ../../../CHANGELOG.md:2815 msgid "Go-NEB support" msgstr "" -#: ../../../CHANGELOG.md:2165 +#: ../../../CHANGELOG.md:2817 msgid "Thanks to [Zir0h](https://github.com/Zir0h), the playbook can now install and configure the [Go-NEB](https://github.com/matrix-org/go-neb) bot." msgstr "" -#: ../../../CHANGELOG.md:2167 +#: ../../../CHANGELOG.md:2819 msgid "Additional details are available in [Setting up Go-NEB](docs/configuring-playbook-bot-go-neb.md)." msgstr "" -#: ../../../CHANGELOG.md:2170 +#: ../../../CHANGELOG.md:2822 msgid "2021-02-19" msgstr "" -#: ../../../CHANGELOG.md:2172 +#: ../../../CHANGELOG.md:2824 msgid "GroupMe bridging support via mx-puppet-groupme" msgstr "" -#: ../../../CHANGELOG.md:2174 +#: ../../../CHANGELOG.md:2826 msgid "Thanks to [Cody Neiman](https://github.com/xangelix), the playbook can now install the [mx-puppet-groupme](https://gitlab.com/robintown/mx-puppet-groupme) bridge for bridging to [GroupMe](https://groupme.com)." msgstr "" -#: ../../../CHANGELOG.md:2176 +#: ../../../CHANGELOG.md:2828 msgid "This brings the total number of bridges supported by the playbook up to 18. See all supported bridges [here](docs/configuring-playbook.md#bridging-other-networks)." msgstr "" -#: ../../../CHANGELOG.md:2178 +#: ../../../CHANGELOG.md:2830 msgid "To get started, follow our [Setting up MX Puppet GroupMe](docs/configuring-playbook-bridge-mx-puppet-groupme.md) docs." msgstr "" -#: ../../../CHANGELOG.md:2180 +#: ../../../CHANGELOG.md:2832 msgid "Mautrix Instagram bridging support" msgstr "" -#: ../../../CHANGELOG.md:2182 +#: ../../../CHANGELOG.md:2834 msgid "The playbook now supports bridging with [Instagram](https://www.instagram.com/) by installing the [mautrix-instagram](https://github.com/tulir/mautrix-instagram) bridge. This playbook functionality is available thanks to [@MarcProe](https://github.com/MarcProe)." msgstr "" -#: ../../../CHANGELOG.md:2184 +#: ../../../CHANGELOG.md:2836 msgid "Additional details are available in [Setting up Mautrix Instagram bridging](docs/configuring-playbook-bridge-mautrix-instagram.md)." msgstr "" -#: ../../../CHANGELOG.md:2186 +#: ../../../CHANGELOG.md:2838 msgid "Synapse workers support" msgstr "" -#: ../../../CHANGELOG.md:2188 +#: ../../../CHANGELOG.md:2840 msgid "After [lots and lots of work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/456) (done over many months by [Marcel Partap](https://github.com/eMPee584), [Max Klenk](https://github.com/maxklenk), a few others from the [Technical University of Dresden, Germany](https://tu-dresden.de/) and various other contributors), support for Synapse workers has finally landed." msgstr "" -#: ../../../CHANGELOG.md:2190 +#: ../../../CHANGELOG.md:2842 msgid "Having support for workers makes the playbook suitable for larger homeserver deployments." msgstr "" -#: ../../../CHANGELOG.md:2192 +#: ../../../CHANGELOG.md:2844 msgid "Our setup is not yet perfect (we don't support all types of workers; scaling some of them (like `pusher`, `federation_sender`) beyond a single instance is not yet supported). Still, it's a great start and can already power homeservers with thousands of users, like the [Matrix deployment at TU Dresden](https://doc.matrix.tu-dresden.de/en/) discussed in [Matrix Live S06E09 — TU Dresden on their Matrix deployment](https://www.youtube.com/watch?v=UHJX2pmT2gk)." msgstr "" -#: ../../../CHANGELOG.md:2194 +#: ../../../CHANGELOG.md:2846 msgid "By default, workers are disabled and Synapse runs as a single process (homeservers don't necessarily need the complexity and increased memory requirements of running a worker-based setup)." msgstr "" -#: ../../../CHANGELOG.md:2196 +#: ../../../CHANGELOG.md:2848 msgid "To enable Synapse workers, follow our [Load balancing with workers](docs/configuring-playbook-synapse.md#load-balancing-with-workers) documentation." msgstr "" -#: ../../../CHANGELOG.md:2199 +#: ../../../CHANGELOG.md:2851 msgid "2021-02-12" msgstr "" -#: ../../../CHANGELOG.md:2201 +#: ../../../CHANGELOG.md:2853 msgid "(Potential Breaking Change) Monitoring/metrics support using Prometheus and Grafana" msgstr "" -#: ../../../CHANGELOG.md:2203 +#: ../../../CHANGELOG.md:2855 msgid "Thanks to [@Peetz0r](https://github.com/Peetz0r), the playbook can now install a bunch of tools for monitoring your Matrix server: the [Prometheus](https://prometheus.io) time-series database server, the Prometheus [node-exporter](https://prometheus.io/docs/guides/node-exporter/) host metrics exporter, and the [Grafana](https://grafana.com/) web UI." msgstr "" -#: ../../../CHANGELOG.md:2205 +#: ../../../CHANGELOG.md:2857 msgid "To get get these installed, follow our [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](docs/configuring-playbook-prometheus-grafana.md) docs page." msgstr "" -#: ../../../CHANGELOG.md:2207 +#: ../../../CHANGELOG.md:2859 msgid "This update comes with a **potential breaking change** for people who were already exposing Synapse metrics (for consumption via another Prometheus installation). From now on, `matrix_synapse_metrics_enabled: true` no longer exposes metrics publicly via matrix-nginx-proxy (at `https://matrix.example.com/_synapse/metrics`). To do so, you'd need to explicitly set `matrix_nginx_proxy_proxy_synapse_metrics: true`." msgstr "" -#: ../../../CHANGELOG.md:2210 +#: ../../../CHANGELOG.md:2862 msgid "2021-01-31" msgstr "" -#: ../../../CHANGELOG.md:2212 +#: ../../../CHANGELOG.md:2864 msgid "Etherpad support" msgstr "" -#: ../../../CHANGELOG.md:2214 +#: ../../../CHANGELOG.md:2866 msgid "Thanks to [@pushytoxin](https://github.com/pushytoxin), the playbook can now install the [Etherpad](https://etherpad.org) realtime collaborative text editor. It can be used in a [Jitsi](https://jitsi.org/) audio/video call or integrated as a widget into Matrix chat rooms via the [Dimension](https://dimension.t2bot.io) integration manager." msgstr "" -#: ../../../CHANGELOG.md:2216 +#: ../../../CHANGELOG.md:2868 msgid "To get it installed, follow [our Etherpad docs page](docs/configuring-playbook-etherpad.md)." msgstr "" -#: ../../../CHANGELOG.md:2219 +#: ../../../CHANGELOG.md:2871 msgid "2021-01-22" msgstr "" -#: ../../../CHANGELOG.md:2221 +#: ../../../CHANGELOG.md:2873 msgid "(Breaking Change) Postgres changes that require manual intervention" msgstr "" -#: ../../../CHANGELOG.md:2223 +#: ../../../CHANGELOG.md:2875 msgid "We've made a lot of changes to our Postgres setup and some manual action is required (described below). Sorry about the hassle." msgstr "" -#: ../../../CHANGELOG.md:2225 +#: ../../../CHANGELOG.md:2877 msgid "**TLDR**: people running an [external Postgres server](docs/configuring-playbook-external-postgres.md) don't need to change anything for now. Everyone else (the common/default case) is affected and manual intervention is required." msgstr "" -#: ../../../CHANGELOG.md:2227 +#: ../../../CHANGELOG.md:2879 msgid "Why?" msgstr "" -#: ../../../CHANGELOG.md:2229 +#: ../../../CHANGELOG.md:2881 msgid "we had a default Postgres password (`matrix_postgres_connection_password: synapse-password`), which we think is **not ideal for security anymore**. We now ask you to generate/provide a strong password yourself. Postgres is normally not exposed outside the container network, making it relatively secure, but still:" msgstr "" -#: ../../../CHANGELOG.md:2230 +#: ../../../CHANGELOG.md:2882 msgid "by tweaking the configuration, you may end up intentionally or unintentionally exposing your Postgres server to the local network (or even publicly), while still using the default default credentials (`synapse` + `synapse-password`)" msgstr "" -#: ../../../CHANGELOG.md:2231 +#: ../../../CHANGELOG.md:2883 msgid "we can't be sure we trust all these services (bridges, etc). Some of them may try to talk to or attack `matrix-postgres` using the default credentials (`synapse` + `synapse-password`)" msgstr "" -#: ../../../CHANGELOG.md:2232 +#: ../../../CHANGELOG.md:2884 msgid "you may have other containers running on the same Docker network, which may try to talk to or attack `matrix-postgres` using the default credentials (`synapse` + `synapse-password`)" msgstr "" -#: ../../../CHANGELOG.md:2233 +#: ../../../CHANGELOG.md:2885 msgid "our Postgres usage **was overly-focused on Synapse** (default username of `synapse` and default/main database of `homeserver`). Additional homeserver options are likely coming in the future ([Dendrite](https://matrix.org/docs/projects/server/dendrite), [Conduit](https://matrix.org/docs/projects/server/conduit), [The Construct](https://matrix.org/docs/projects/server/construct)), so being too focused on `matrix-synapse` is not great. From now on, Synapse is just another component of this playbook, which happens to have an *additional database* (called `synapse`) on the Postgres server." msgstr "" -#: ../../../CHANGELOG.md:2234 +#: ../../../CHANGELOG.md:2886 msgid "we try to reorganize things a bit, to make the playbook even friendlier to people running an [external Postgres server](docs/configuring-playbook-external-postgres.md). Work on this will proceed in the future." msgstr "" -#: ../../../CHANGELOG.md:2236 +#: ../../../CHANGELOG.md:2888 msgid "So, this is some **effort to improve security** and to **prepare for a brighter future of having more homeserver options** than just Synapse." msgstr "" -#: ../../../CHANGELOG.md:2238 +#: ../../../CHANGELOG.md:2890 msgid "What has really changed?" msgstr "" -#: ../../../CHANGELOG.md:2240 +#: ../../../CHANGELOG.md:2892 msgid "the default superuser Postgres username is now `matrix` (used to be `synapse`)" msgstr "" -#: ../../../CHANGELOG.md:2241 +#: ../../../CHANGELOG.md:2893 msgid "the default Postgres database is now `matrix` (used to be `homeserver`)" msgstr "" -#: ../../../CHANGELOG.md:2242 +#: ../../../CHANGELOG.md:2894 msgid "Synapse's database is now `synapse` (used to be `homeserver`). This is now just another \"additional database\" that the playbook manages for you" msgstr "" -#: ../../../CHANGELOG.md:2243 +#: ../../../CHANGELOG.md:2895 msgid "Synapse's user called `synapse` is just a regular user that can only use the `synapse` database (not a superuser anymore)" msgstr "" -#: ../../../CHANGELOG.md:2245 +#: ../../../CHANGELOG.md:2897 msgid "What do I do if I'm using the integrated Postgres server (default)?" msgstr "" -#: ../../../CHANGELOG.md:2247 +#: ../../../CHANGELOG.md:2899 msgid "By default, the playbook runs an integrated Postgres server for you in a container (`matrix-postgres`). Unless you've explicitly configured an [external Postgres server](docs/configuring-playbook-external-postgres.md), these steps are meant for you." msgstr "" -#: ../../../CHANGELOG.md:2249 +#: ../../../CHANGELOG.md:2901 msgid "To migrate to the new setup, expect a few minutes of downtime, while you follow these steps:" msgstr "" -#: ../../../CHANGELOG.md:2251 +#: ../../../CHANGELOG.md:2903 msgid "We believe the steps below are safe and you won't encounter any data loss, but consider [making a Postgres backup](docs/maintenance-postgres.md#backing-up-postgresql) anyway. If you've never backed up Postgres, now would be a good time to try it." msgstr "" -#: ../../../CHANGELOG.md:2253 +#: ../../../CHANGELOG.md:2905 msgid "Generate a strong password to be used for your superuser Postgres user (called `matrix`). You can create one with a command like `pwgen -s 64 1`. The **maximum length** for a Postgres password is 100 bytes (characters). Don't go crazy!" msgstr "" -#: ../../../CHANGELOG.md:2255 +#: ../../../CHANGELOG.md:2907 msgid "Update your playbook's `inventory/host_vars/matrix.example.com/vars.yml` file, adding a line like this:" msgstr "" -#: ../../../CHANGELOG.md:2260 ../../../CHANGELOG.md:2272 +#: ../../../CHANGELOG.md:2912 ../../../CHANGELOG.md:2924 msgid "… where `YOUR_POSTGRES_PASSWORD_HERE` is to be replaced with the password you generated during step #2." msgstr "" -#: ../../../CHANGELOG.md:2262 +#: ../../../CHANGELOG.md:2914 msgid "Stop all services: `ansible-playbook -i inventory/hosts setup.yml --tags=stop`" msgstr "" -#: ../../../CHANGELOG.md:2263 +#: ../../../CHANGELOG.md:2915 msgid "Log in to the server via SSH. The next commands will be performed there." msgstr "" -#: ../../../CHANGELOG.md:2264 +#: ../../../CHANGELOG.md:2916 msgid "Start the Postgres database server: `systemctl start matrix-postgres`" msgstr "" -#: ../../../CHANGELOG.md:2265 +#: ../../../CHANGELOG.md:2917 msgid "Open a Postgres shell: `/usr/local/bin/matrix-postgres-cli`" msgstr "" -#: ../../../CHANGELOG.md:2266 +#: ../../../CHANGELOG.md:2918 msgid "Execute the following query, while making sure to **change the password inside** (**don't forget the ending `;`**):" msgstr "" -#: ../../../CHANGELOG.md:2274 +#: ../../../CHANGELOG.md:2926 msgid "Execute the following queries as you see them (no modifications necessary, so you can just **paste them all at once**):" msgstr "" -#: ../../../CHANGELOG.md:2292 +#: ../../../CHANGELOG.md:2944 msgid "You may need to press *Enter* after pasting the lines above." msgstr "" -#: ../../../CHANGELOG.md:2294 +#: ../../../CHANGELOG.md:2946 msgid "Re-run the playbook normally: `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start`" msgstr "" -#: ../../../CHANGELOG.md:2296 +#: ../../../CHANGELOG.md:2948 msgid "What do I do if I'm using an external Postgres server?" msgstr "" -#: ../../../CHANGELOG.md:2298 +#: ../../../CHANGELOG.md:2950 msgid "If you've explicitly configured an [external Postgres server](docs/configuring-playbook-external-postgres.md), there are **no changes** that you need to do at this time." msgstr "" -#: ../../../CHANGELOG.md:2300 +#: ../../../CHANGELOG.md:2952 msgid "The fact that we've renamed Synapse's database from `homeserver` to `synapse` (in our defaults) should not affect you, as you're already explicitly defining `matrix_synapse_database_database` (if you've followed our guide, that is). If you're not explicitly defining this variable, you may wish to do so (`matrix_synapse_database_database: homeserver`), to avoid the new `synapse` default and keep things as they were." msgstr "" -#: ../../../CHANGELOG.md:2303 +#: ../../../CHANGELOG.md:2955 msgid "2021-01-20" msgstr "" -#: ../../../CHANGELOG.md:2305 +#: ../../../CHANGELOG.md:2957 msgid "(Breaking Change) The mautrix-facebook bridge now requires a Postgres database" msgstr "" -#: ../../../CHANGELOG.md:2307 +#: ../../../CHANGELOG.md:2959 msgid "**Update from 2021-11-15**: SQLite support has been re-added to the mautrix-facebook bridge in [v0.3.2](https://github.com/mautrix/facebook/releases/tag/v0.3.2). You can ignore this changelog entry." msgstr "" -#: ../../../CHANGELOG.md:2309 +#: ../../../CHANGELOG.md:2961 msgid "A new version of the [mautrix-facebook](https://github.com/tulir/mautrix-facebook) bridge has been released. It's a full rewrite of its backend and the bridge now requires Postgres. New versions of the bridge can no longer run on SQLite." msgstr "" -#: ../../../CHANGELOG.md:2311 +#: ../../../CHANGELOG.md:2963 msgid "**TLDR**: if you're NOT using an [external Postgres server](docs/configuring-playbook-external-postgres.md) and have NOT forcefully kept the bridge on SQLite during [The big move to all-on-Postgres (potentially dangerous)](#the-big-move-to-all-on-postgres-potentially-dangerous), you will be automatically upgraded without manual intervention. All you need to do is send a `login` message to the Facebook bridge bot again." msgstr "" -#: ../../../CHANGELOG.md:2313 +#: ../../../CHANGELOG.md:2965 msgid "Whether this change requires your intervention depends mostly on:" msgstr "" -#: ../../../CHANGELOG.md:2314 +#: ../../../CHANGELOG.md:2966 msgid "whether you're using an [external Postgres server](docs/configuring-playbook-external-postgres.md). If yes, then [you need to do something](#upgrade-path-for-people-running-an-external-postgres-server)." msgstr "" -#: ../../../CHANGELOG.md:2315 +#: ../../../CHANGELOG.md:2967 msgid "or whether you've force-changed the bridge's database engine to SQLite (`matrix_mautrix_facebook_database_engine: 'sqlite'` in your `vars.yml`) some time in the past (likely during [The big move to all-on-Postgres (potentially dangerous)](#the-big-move-to-all-on-postgres-potentially-dangerous))." msgstr "" -#: ../../../CHANGELOG.md:2317 +#: ../../../CHANGELOG.md:2969 msgid "As already mentioned above, you most likely don't need to do anything. If you rerun the playbook and don't get an error, you've been automatically upgraded. Just send a `login` message to the Facebook bridge bot again. Otherwise, read below for a solution." msgstr "" -#: ../../../CHANGELOG.md:2319 +#: ../../../CHANGELOG.md:2971 msgid "Upgrade path for people NOT running an external Postgres server (default for the playbook)" msgstr "" -#: ../../../CHANGELOG.md:2321 +#: ../../../CHANGELOG.md:2973 msgid "If you're **not running an external Postgres server**, then this bridge either already works on Postgres for you, or you've intentionally kept it back on SQLite with custom configuration (`matrix_mautrix_facebook_database_engine: 'sqlite'` in your `vars.yml`) ." msgstr "" -#: ../../../CHANGELOG.md:2323 +#: ../../../CHANGELOG.md:2975 msgid "Simply remove that custom configuration from your `vars.yml` file (if it's there) and re-run the playbook. It should upgrade you automatically. You'll need to send a `login` message to the Facebook bridge bot again." msgstr "" -#: ../../../CHANGELOG.md:2325 +#: ../../../CHANGELOG.md:2977 msgid "Alternatively, [you can stay on SQLite for a little longer](#staying-on-sqlite-for-a-little-longer-temporary-solution)." msgstr "" -#: ../../../CHANGELOG.md:2327 +#: ../../../CHANGELOG.md:2979 msgid "Upgrade path for people running an external Postgres server" msgstr "" -#: ../../../CHANGELOG.md:2329 +#: ../../../CHANGELOG.md:2981 msgid "For people using the internal Postgres server (the default for the playbook):" msgstr "" -#: ../../../CHANGELOG.md:2330 +#: ../../../CHANGELOG.md:2982 msgid "we automatically create an additional `matrix_mautrix_facebook` Postgres database and credentials to access it" msgstr "" -#: ../../../CHANGELOG.md:2331 +#: ../../../CHANGELOG.md:2983 msgid "we automatically adjust the bridge's `matrix_mautrix_facebook_database_*` variables to point the bridge to that Postgres database" msgstr "" -#: ../../../CHANGELOG.md:2332 +#: ../../../CHANGELOG.md:2984 msgid "we use [pgloader](https://pgloader.io/) to automatically import the existing SQLite data for the bridge into the `matrix_mautrix_facebook` Postgres database" msgstr "" -#: ../../../CHANGELOG.md:2334 +#: ../../../CHANGELOG.md:2986 msgid "If you are using an [external Postgres server](docs/configuring-playbook-external-postgres.md), unfortunately we currently can't do any of that for you." msgstr "" -#: ../../../CHANGELOG.md:2336 +#: ../../../CHANGELOG.md:2988 msgid "You have 3 ways to proceed:" msgstr "" -#: ../../../CHANGELOG.md:2338 +#: ../../../CHANGELOG.md:2990 msgid "contribute to the playbook to make this possible (difficult)" msgstr "" -#: ../../../CHANGELOG.md:2339 +#: ../../../CHANGELOG.md:2991 msgid "or, do the migration \"steps\" manually:" msgstr "" -#: ../../../CHANGELOG.md:2340 +#: ../../../CHANGELOG.md:2992 msgid "stop the bridge (`systemctl stop matrix-mautrix-facebook`)" msgstr "" -#: ../../../CHANGELOG.md:2341 +#: ../../../CHANGELOG.md:2993 msgid "create a new `matrix_mautrix_facebook` Postgres database for it" msgstr "" -#: ../../../CHANGELOG.md:2342 +#: ../../../CHANGELOG.md:2994 msgid "run [pgloader](https://pgloader.io/) manually (we import this bridge's data using default settings and it works well)" msgstr "" -#: ../../../CHANGELOG.md:2343 +#: ../../../CHANGELOG.md:2995 msgid "define `matrix_mautrix_facebook_database_*` variables in your `vars.yml` file (credentials, etc.) — you can find their defaults in `roles/custom/matrix-mautrix-facebook/defaults/main.yml`" msgstr "" -#: ../../../CHANGELOG.md:2344 +#: ../../../CHANGELOG.md:2996 msgid "switch the bridge to Postgres (`matrix_mautrix_facebook_database_engine: 'postgres'` in your `vars.yml` file)" msgstr "" -#: ../../../CHANGELOG.md:2345 +#: ../../../CHANGELOG.md:2997 msgid "re-run the playbook (`--tags=setup-all,start`) and ensure the bridge works (`systemctl status matrix-mautrix-facebook` and `journalctl -fu matrix-mautrix-facebook`)" msgstr "" -#: ../../../CHANGELOG.md:2346 +#: ../../../CHANGELOG.md:2998 msgid "send a `login` message to the Facebook bridge bot again" msgstr "" -#: ../../../CHANGELOG.md:2347 +#: ../../../CHANGELOG.md:2999 msgid "or, [stay on SQLite for a little longer (temporary solution)](#staying-on-sqlite-for-a-little-longer-temporary-solution)" msgstr "" -#: ../../../CHANGELOG.md:2349 +#: ../../../CHANGELOG.md:3001 msgid "Staying on SQLite for a little longer (temporary solution)" msgstr "" -#: ../../../CHANGELOG.md:2351 +#: ../../../CHANGELOG.md:3003 msgid "To keep using this bridge with SQLite for a little longer (**not recommended**), use the following configuration in your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:2361 +#: ../../../CHANGELOG.md:3013 msgid "If you do this, keep in mind that **you can't run this forever**. This SQLite-supporting bridge version is not getting any updates and will break sooner or later. The playbook will also drop support for SQLite at some point in the future." msgstr "" -#: ../../../CHANGELOG.md:2364 +#: ../../../CHANGELOG.md:3016 msgid "2021-01-17" msgstr "" -#: ../../../CHANGELOG.md:2366 +#: ../../../CHANGELOG.md:3018 msgid "matrix-corporal goes 2.0" msgstr "" -#: ../../../CHANGELOG.md:2368 +#: ../../../CHANGELOG.md:3020 msgid "[matrix-corporal v2 has been released](https://github.com/devture/matrix-corporal/releases/tag/2.0.0) and the playbook also supports it now." msgstr "" -#: ../../../CHANGELOG.md:2370 +#: ../../../CHANGELOG.md:3022 msgid "No manual intervention is required in the common case." msgstr "" -#: ../../../CHANGELOG.md:2372 +#: ../../../CHANGELOG.md:3024 msgid "The new [matrix-corporal](https://github.com/devture/matrix-corporal) version is also the first one to support Interactive Authentication. If you wish to enable that (hint: you should), you'll need to set up the [REST auth password provider](docs/configuring-playbook-rest-auth.md). There's more information in [our matrix-corporal docs](docs/configuring-playbook-matrix-corporal.md)." msgstr "" -#: ../../../CHANGELOG.md:2375 +#: ../../../CHANGELOG.md:3027 msgid "2021-01-14" msgstr "" -#: ../../../CHANGELOG.md:2377 +#: ../../../CHANGELOG.md:3029 msgid "Moving from cronjobs to systemd timers" msgstr "" -#: ../../../CHANGELOG.md:2379 +#: ../../../CHANGELOG.md:3031 msgid "We no longer use cronjobs for Let's Encrypt SSL renewal and `matrix-nginx-proxy`/`matrix-coturn` reloading. Instead, we've switched to systemd timers." msgstr "" -#: ../../../CHANGELOG.md:2381 +#: ../../../CHANGELOG.md:3033 msgid "The largest benefit of this is that we no longer require you to install a cron daemon, thus simplifying our install procedure." msgstr "" -#: ../../../CHANGELOG.md:2383 +#: ../../../CHANGELOG.md:3035 msgid "The playbook will migrate you from cronjobs to systemd timers automatically. This is just a heads up." msgstr "" -#: ../../../CHANGELOG.md:2386 +#: ../../../CHANGELOG.md:3038 msgid "2021-01-08" msgstr "" -#: ../../../CHANGELOG.md:2388 +#: ../../../CHANGELOG.md:3040 msgid "(Breaking Change) New SSL configuration" msgstr "" -#: ../../../CHANGELOG.md:2390 +#: ../../../CHANGELOG.md:3042 msgid "SSL configuration (protocols, ciphers) can now be more easily controlled thanks to us making use of configuration presets." msgstr "" -#: ../../../CHANGELOG.md:2392 +#: ../../../CHANGELOG.md:3044 msgid "We define a few presets (old, intermediate, modern), following the [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/#server=nginx)." msgstr "" -#: ../../../CHANGELOG.md:2394 +#: ../../../CHANGELOG.md:3046 msgid "A new variable `matrix_nginx_proxy_ssl_preset` controls which preset is used (defaults to `\"intermediate\"`)." msgstr "" -#: ../../../CHANGELOG.md:2396 +#: ../../../CHANGELOG.md:3048 msgid "Compared to before, this changes nginx's `ssl_prefer_server_ciphers` to `off` (used to default to `on`). It also add some more ciphers to the list, giving better performance on mobile devices, and removes some weak ciphers. More information in the [documentation](docs/configuring-playbook-nginx.md)." msgstr "" -#: ../../../CHANGELOG.md:2398 +#: ../../../CHANGELOG.md:3050 msgid "To revert to the old behaviour, set the following variables:" msgstr "" -#: ../../../CHANGELOG.md:2405 +#: ../../../CHANGELOG.md:3057 msgid "Just like before, you can still use your own custom protocols by specifying them in `matrix_nginx_proxy_ssl_protocols`. Doing so overrides the values coming from the preset." msgstr "" -#: ../../../CHANGELOG.md:2408 +#: ../../../CHANGELOG.md:3060 msgid "2021-01-03" msgstr "" -#: ../../../CHANGELOG.md:2410 +#: ../../../CHANGELOG.md:3062 msgid "Signal bridging support via mautrix-signal" msgstr "" -#: ../../../CHANGELOG.md:2412 +#: ../../../CHANGELOG.md:3064 msgid "Thanks to [laszabine](https://github.com/laszabine)'s efforts, the playbook now supports bridging to [Signal](https://www.signal.org/) via the [mautrix-signal](https://github.com/tulir/mautrix-signal) bridge. See our [Setting up Mautrix Signal bridging](docs/configuring-playbook-bridge-mautrix-signal.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:2414 +#: ../../../CHANGELOG.md:3066 msgid "If you had installed the mautrix-signal bridge while its Pull Request was still work-in-progress, you can migrate your data to the new and final setup by referring to [this comment](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/686#issuecomment-753510789)." msgstr "" -#: ../../../CHANGELOG.md:2417 +#: ../../../CHANGELOG.md:3069 msgid "2020-12-23" msgstr "" -#: ../../../CHANGELOG.md:2419 +#: ../../../CHANGELOG.md:3071 msgid "The big move to all-on-Postgres (potentially dangerous)" msgstr "" -#: ../../../CHANGELOG.md:2421 +#: ../../../CHANGELOG.md:3073 msgid "**TLDR**: all your bridges (and other services) will likely be auto-migrated from SQLite/nedb to Postgres, hopefully without trouble. You can opt-out (see how below), if too worried about breakage." msgstr "" -#: ../../../CHANGELOG.md:2423 +#: ../../../CHANGELOG.md:3075 msgid "Until now, we've only used Postgres as a database for Synapse. All other services (bridges, bots, etc.) were kept simple and used a file-based database (SQLite or nedb)." msgstr "" -#: ../../../CHANGELOG.md:2425 +#: ../../../CHANGELOG.md:3077 msgid "Since [this huge pull request](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/740), **all of our services now use Postgres by default**. Thanks to [Johanna Dorothea Reichmann](https://github.com/jdreichmann) for starting the work on it and for providing great input!" msgstr "" -#: ../../../CHANGELOG.md:2427 +#: ../../../CHANGELOG.md:3079 msgid "Moving all services to Postgres brings a few **benefits** to us:" msgstr "" -#: ../../../CHANGELOG.md:2429 +#: ../../../CHANGELOG.md:3081 msgid "**improved performance**" msgstr "" -#: ../../../CHANGELOG.md:2430 +#: ../../../CHANGELOG.md:3082 msgid "**improved compatibility**. Most bridges are deprecating SQLite/nedb support or offer less features when not on Postgres." msgstr "" -#: ../../../CHANGELOG.md:2431 +#: ../../../CHANGELOG.md:3083 msgid "**easier backups**. It's still some effort to take a proper backup (Postgres dump + various files, keys), but a Postgres dump now takes you much further." msgstr "" -#: ../../../CHANGELOG.md:2432 +#: ../../../CHANGELOG.md:3084 msgid "we're now **more prepared to introduce other services** that need a Postgres database — [Dendrite](https://github.com/matrix-org/dendrite), the [mautrix-signal](https://github.com/tulir/mautrix-signal) bridge (existing [pull request](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/686)), etc." msgstr "" -#: ../../../CHANGELOG.md:2434 +#: ../../../CHANGELOG.md:3086 msgid "Key takeway" msgstr "" -#: ../../../CHANGELOG.md:2436 +#: ../../../CHANGELOG.md:3088 msgid "existing installations that use an [external Postgres](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-external-postgres.md) server should be unaffected (they remain on SQLite/nedb for all services, except Synapse)" msgstr "" -#: ../../../CHANGELOG.md:2438 +#: ../../../CHANGELOG.md:3090 msgid "for existing installations which use our integrated Postgres database server (`matrix-postgres`, which is the default), **we automatically migrate data** from SQLite/nedb to Postgres and **archive the database files** (`something.db` -> `something.db.backup`), so you can restore them if you need to go back (see how below)." msgstr "" -#: ../../../CHANGELOG.md:2440 +#: ../../../CHANGELOG.md:3092 msgid "Opting-out of the Postgres migration" msgstr "" -#: ../../../CHANGELOG.md:2442 +#: ../../../CHANGELOG.md:3094 msgid "This is a **very large and somewhat untested change** (potentially dangerous), so **if you're not feeling confident/experimental, opt-out** of it for now. Still, it's the new default and what we (and various bridges) will focus on going forward, so don't stick to old ways for too long." msgstr "" -#: ../../../CHANGELOG.md:2444 +#: ../../../CHANGELOG.md:3096 msgid "You can remain on SQLite/nedb (at least for now) by adding a variable like this to your `vars.yml` file for each service you use: `matrix_COMPONENT_database_engine: sqlite` (e.g. `matrix_mautrix_facebook_database_engine: sqlite`)." msgstr "" -#: ../../../CHANGELOG.md:2446 +#: ../../../CHANGELOG.md:3098 msgid "Some services (like `appservice-irc` and `appservice-slack`) don't use SQLite, so use `nedb`, instead of `sqlite` for them." msgstr "" -#: ../../../CHANGELOG.md:2448 +#: ../../../CHANGELOG.md:3100 msgid "Going back to SQLite/nedb if things went wrong" msgstr "" -#: ../../../CHANGELOG.md:2450 +#: ../../../CHANGELOG.md:3102 msgid "If you went with the Postgres migration and it went badly for you (some bridge not working as expected or not working at all), do this:" msgstr "" -#: ../../../CHANGELOG.md:2452 +#: ../../../CHANGELOG.md:3104 msgid "stop all services (`ansible-playbook -i inventory/hosts setup.yml --tags=stop`)" msgstr "" -#: ../../../CHANGELOG.md:2453 +#: ../../../CHANGELOG.md:3105 msgid "SSH into the server and rename the old database files (`something.db.backup` -> `something.db`). Example: `mv /matrix/mautrix-facebook/data/mautrix-facebook.db.backup /matrix/mautrix-facebook/data/mautrix-facebook.db`" msgstr "" -#: ../../../CHANGELOG.md:2454 +#: ../../../CHANGELOG.md:3106 msgid "switch the affected service back to SQLite (e.g. `matrix_mautrix_facebook_database_engine: sqlite`). Some services (like `appservice-irc` and `appservice-slack`) don't use SQLite, so use `nedb`, instead of `sqlite` for them." msgstr "" -#: ../../../CHANGELOG.md:2455 +#: ../../../CHANGELOG.md:3107 msgid "re-run the playbook (`ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start`)" msgstr "" -#: ../../../CHANGELOG.md:2456 +#: ../../../CHANGELOG.md:3108 msgid "[get in touch](README.md#support) with us" msgstr "" -#: ../../../CHANGELOG.md:2458 +#: ../../../CHANGELOG.md:3110 msgid "2020-12-11" msgstr "" -#: ../../../CHANGELOG.md:2460 +#: ../../../CHANGELOG.md:3112 msgid "synapse-janitor support removed" msgstr "" -#: ../../../CHANGELOG.md:2462 +#: ../../../CHANGELOG.md:3114 msgid "We've removed support for the unmaintained [synapse-janitor](https://github.com/xwiki-labs/synapse_scripts) script. There's been past reports of it corrupting the Synapse database. Since there hasn't been any new development on it and it doesn't seem too useful nowadays, there's no point in including it in the playbook." msgstr "" -#: ../../../CHANGELOG.md:2464 +#: ../../../CHANGELOG.md:3116 msgid "If you need to clean up or compact your database, consider using the Synapse Admin APIs directly. See our [Synapse maintenance](docs/maintenance-synapse.md) and [Postgres maintenance](docs/maintenance-postgres.md) documentation pages for more details." msgstr "" -#: ../../../CHANGELOG.md:2466 +#: ../../../CHANGELOG.md:3118 msgid "Docker 20.10 is here" msgstr "" -#: ../../../CHANGELOG.md:2468 +#: ../../../CHANGELOG.md:3120 msgid "(No need to do anything special in relation to this. Just something to keep in mind)" msgstr "" -#: ../../../CHANGELOG.md:2470 +#: ../../../CHANGELOG.md:3122 msgid "Docker 20.10 got released recently and your server will likely get it the next time you update." msgstr "" -#: ../../../CHANGELOG.md:2472 +#: ../../../CHANGELOG.md:3124 msgid "This is the first major Docker update in a long time and it packs a lot of changes. Some of them introduced some breakage for us initially (see [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/d08b27784f222effcbce2abf924bf07bbe0893be) and [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/7593d969e316cc0144bce378a5be58c76c2c37ee)), but it should be all good now." msgstr "" -#: ../../../CHANGELOG.md:2475 +#: ../../../CHANGELOG.md:3127 msgid "2020-12-08" msgstr "" -#: ../../../CHANGELOG.md:2477 +#: ../../../CHANGELOG.md:3129 msgid "openid APIs exposed by default on the federation port when federation disabled" msgstr "" -#: ../../../CHANGELOG.md:2479 +#: ../../../CHANGELOG.md:3131 msgid "We've changed some defaults. People running with our default configuration (federation enabled), are not affected at all." msgstr "" -#: ../../../CHANGELOG.md:2481 +#: ../../../CHANGELOG.md:3133 msgid "If you are running an unfederated server (`matrix_synapse_federation_enabled: false`), this may be of interest to you." msgstr "" -#: ../../../CHANGELOG.md:2483 +#: ../../../CHANGELOG.md:3135 msgid "When federation is disabled, but ma1sd or Dimension are enabled, we'll now expose the `openid` APIs on the federation port. These APIs are necessary for some ma1sd features to work. If you'd like to prevent this, you can: `matrix_synapse_federation_port_openid_resource_required: false`." msgstr "" -#: ../../../CHANGELOG.md:2486 +#: ../../../CHANGELOG.md:3138 msgid "2020-11-27" msgstr "" -#: ../../../CHANGELOG.md:2488 +#: ../../../CHANGELOG.md:3140 msgid "Recent Jitsi updates may require configuration changes" msgstr "" -#: ../../../CHANGELOG.md:2490 +#: ../../../CHANGELOG.md:3142 msgid "We've recently [updated from Jitsi build 4857 to build 5142](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/719), which brings a lot of configuration changes." msgstr "" -#: ../../../CHANGELOG.md:2492 +#: ../../../CHANGELOG.md:3144 msgid "**If you use our default Jitsi settings, you won't have to do anything.**" msgstr "" -#: ../../../CHANGELOG.md:2494 +#: ../../../CHANGELOG.md:3146 msgid "People who have [fine-tuned Jitsi](docs/configuring-playbook-jitsi.md#optional-fine-tune-jitsi) may find that some options got renamed now, others are gone and yet others still need to be defined in another way." msgstr "" -#: ../../../CHANGELOG.md:2496 +#: ../../../CHANGELOG.md:3148 msgid "The next time you run the playbook [installation](docs/installing.md) command, our validation logic will tell you if you're using some variables like that and will recommend a migration path for each one." msgstr "" -#: ../../../CHANGELOG.md:2498 +#: ../../../CHANGELOG.md:3150 msgid "Additionally, we've recently disabled transcriptions (`jitsi_enable_transcriptions: false`) and recording (`jitsi_enable_recording: false`) by default. These features did not work anyway, because we don't install the required dependencies for them (Jigasi and Jibri, respectively). If you've been somehow pointing your Jitsi installation to some manually installed Jigasi/Jibri service, you may need to toggle these flags back to enabled to have transcriptions and recordings working." msgstr "" -#: ../../../CHANGELOG.md:2501 +#: ../../../CHANGELOG.md:3153 msgid "2020-11-23" msgstr "" -#: ../../../CHANGELOG.md:2503 ../../../CHANGELOG.md:2511 +#: ../../../CHANGELOG.md:3155 ../../../CHANGELOG.md:3163 msgid "Breaking change matrix-sms-bridge" msgstr "" -#: ../../../CHANGELOG.md:2505 +#: ../../../CHANGELOG.md:3157 msgid "Because of many problems using gammu as SMS provider, matrix-sms-bridge now uses (https://github.com/RebekkaMa/android-sms-gateway-server) by default. See (the docs)[./docs/configuring-playbook-bridge-matrix-bridge-sms.md] which new vars you need to add." msgstr "" -#: ../../../CHANGELOG.md:2507 +#: ../../../CHANGELOG.md:3159 msgid "If you are using this playbook to deploy matrix-sms-bridge and still really want to use gammu as SMS provider, we could possibly add support for both android-sms-gateway-server and gammu." msgstr "" -#: ../../../CHANGELOG.md:2509 +#: ../../../CHANGELOG.md:3161 msgid "2020-11-13" msgstr "" -#: ../../../CHANGELOG.md:2513 +#: ../../../CHANGELOG.md:3165 msgid "The new version of [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) changed its database from neo4j to h2. You need to sync the bridge at the first start. Note that this only will sync rooms where the @smsbot:yourServer is member. For rooms without @smsbot:yourServer you need to kick and invite the telephone number **or** invite @smsbot:yourServer." msgstr "" -#: ../../../CHANGELOG.md:2515 +#: ../../../CHANGELOG.md:3167 msgid "Add the following to your `vars.yml` file: `matrix_sms_bridge_container_extra_arguments=['--env SPRING_PROFILES_ACTIVE=initialsync']`" msgstr "" -#: ../../../CHANGELOG.md:2516 +#: ../../../CHANGELOG.md:3168 msgid "Login to your host shell and remove old systemd file from your host: `rm /etc/systemd/system/matrix-sms-bridge-database.service`" msgstr "" -#: ../../../CHANGELOG.md:2517 +#: ../../../CHANGELOG.md:3169 msgid "Run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-matrix-sms-bridge,start`" msgstr "" -#: ../../../CHANGELOG.md:2518 +#: ../../../CHANGELOG.md:3170 msgid "Login to your host shell and check the logs with `journalctl -u matrix-sms-bridge` until the sync finished." msgstr "" -#: ../../../CHANGELOG.md:2519 +#: ../../../CHANGELOG.md:3171 msgid "Remove the var from the first step." msgstr "" -#: ../../../CHANGELOG.md:2520 +#: ../../../CHANGELOG.md:3172 msgid "Run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start`." msgstr "" -#: ../../../CHANGELOG.md:2522 +#: ../../../CHANGELOG.md:3174 msgid "2020-11-10" msgstr "" -#: ../../../CHANGELOG.md:2524 +#: ../../../CHANGELOG.md:3176 msgid "Dynamic DNS support" msgstr "" -#: ../../../CHANGELOG.md:2526 +#: ../../../CHANGELOG.md:3178 msgid "Thanks to [Scott Crossen](https://github.com/scottcrossen), the playbook can now manage Dynamic DNS for you using [ddclient](https://ddclient.net/)." msgstr "" -#: ../../../CHANGELOG.md:2528 +#: ../../../CHANGELOG.md:3180 msgid "To learn more, follow our [Dynamic DNS docs page](docs/configuring-playbook-dynamic-dns.md)." msgstr "" -#: ../../../CHANGELOG.md:2531 +#: ../../../CHANGELOG.md:3183 msgid "2020-10-28" msgstr "" -#: ../../../CHANGELOG.md:2533 +#: ../../../CHANGELOG.md:3185 msgid "(Compatibility Break) https://matrix.example.com/ now redirects to https://element.example.com/" msgstr "" -#: ../../../CHANGELOG.md:2535 +#: ../../../CHANGELOG.md:3187 msgid "Until now, we used to serve a static page coming from Synapse at `https://matrix.example.com/`. This page was not very useful to anyone." msgstr "" -#: ../../../CHANGELOG.md:2537 +#: ../../../CHANGELOG.md:3189 msgid "Since `matrix.example.com` may be accessed by regular users in certain conditions, it's probably better to redirect them to a better place (e.g. to [Element Web](docs/configuring-playbook-client-element-web.md))." msgstr "" -#: ../../../CHANGELOG.md:2539 +#: ../../../CHANGELOG.md:3191 msgid "If Element Web is installed (`matrix_client_element_enabled: true`, which it is by default), we now redirect people to it, instead of showing them a Synapse static page." msgstr "" -#: ../../../CHANGELOG.md:2541 +#: ../../../CHANGELOG.md:3193 msgid "If you'd like to control where the redirect goes, use the `matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain` variable. To restore the old behavior of not redirecting anywhere and serving the Synapse static page, set it to an empty value (`matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain: \"\"`)." msgstr "" -#: ../../../CHANGELOG.md:2544 +#: ../../../CHANGELOG.md:3196 msgid "2020-10-26" msgstr "" -#: ../../../CHANGELOG.md:2546 +#: ../../../CHANGELOG.md:3198 msgid "(Compatibility Break) /_synapse/admin is no longer publicly exposed by default" msgstr "" -#: ../../../CHANGELOG.md:2548 +#: ../../../CHANGELOG.md:3200 msgid "We used to expose the Synapse Admin APIs publicly (at `https://matrix.example.com/_synapse/admin`). These APIs require authentication with a valid access token, so it's not that big a deal to expose them." msgstr "" -#: ../../../CHANGELOG.md:2550 +#: ../../../CHANGELOG.md:3202 msgid "However, following [official Synapse's reverse-proxying recommendations](https://github.com/element-hq/synapse/blob/master/docs/reverse_proxy.md#synapse-administration-endpoints), we're no longer exposing `/_synapse/admin` by default." msgstr "" -#: ../../../CHANGELOG.md:2552 +#: ../../../CHANGELOG.md:3204 msgid "If you'd like to restore restore the old behavior and expose `/_synapse/admin` publicly, you can use the following configuration (in your `vars.yml`):" msgstr "" -#: ../../../CHANGELOG.md:2559 +#: ../../../CHANGELOG.md:3211 msgid "2020-10-02" msgstr "" -#: ../../../CHANGELOG.md:2561 +#: ../../../CHANGELOG.md:3213 msgid "Minimum Ansible version raised to v2.7.0" msgstr "" -#: ../../../CHANGELOG.md:2563 +#: ../../../CHANGELOG.md:3215 msgid "We were claiming to support [Ansible](https://www.ansible.com/) v2.5.2 and higher, but issues like [#662](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/662) demonstrate that we need at least v2.7.0." msgstr "" -#: ../../../CHANGELOG.md:2565 +#: ../../../CHANGELOG.md:3217 msgid "If you've been using the playbook without getting any errors until now, you're probably on a version higher than that already (or you're not using the `matrix-ma1sd` and `matrix-client-element` roles)." msgstr "" -#: ../../../CHANGELOG.md:2567 +#: ../../../CHANGELOG.md:3219 msgid "Our [Ansible docs page](docs/ansible.md) contains information on how to run a more up-to-date version of Ansible." msgstr "" -#: ../../../CHANGELOG.md:2570 +#: ../../../CHANGELOG.md:3222 msgid "2020-10-01" msgstr "" -#: ../../../CHANGELOG.md:2572 +#: ../../../CHANGELOG.md:3224 msgid "Postgres 13 support" msgstr "" -#: ../../../CHANGELOG.md:2574 +#: ../../../CHANGELOG.md:3226 msgid "The playbook now installs [Postgres 13](https://www.postgresql.org/about/news/postgresql-13-released-2077/) by default." msgstr "" -#: ../../../CHANGELOG.md:2576 +#: ../../../CHANGELOG.md:3228 msgid "If you have have an existing setup, it's likely running on an older Postgres version (9.x, 10.x, 11.x or 12.x). You can easily upgrade by following the [upgrading PostgreSQL guide](docs/maintenance-postgres.md#upgrading-postgresql)." msgstr "" -#: ../../../CHANGELOG.md:2578 +#: ../../../CHANGELOG.md:3230 msgid "2020-09-01" msgstr "" -#: ../../../CHANGELOG.md:2580 +#: ../../../CHANGELOG.md:3232 msgid "matrix-registration support" msgstr "" -#: ../../../CHANGELOG.md:2582 +#: ../../../CHANGELOG.md:3234 msgid "The playbook can now help you set up [matrix-registration](https://github.com/ZerataX/matrix-registration) — an application that lets you keep your Matrix server's registration private, but still allow certain users (those having a unique registration link) to register by themselves." msgstr "" -#: ../../../CHANGELOG.md:2584 +#: ../../../CHANGELOG.md:3236 msgid "See our [Setting up matrix-registration](docs/configuring-playbook-matrix-registration.md) documentation page to get started." msgstr "" -#: ../../../CHANGELOG.md:2587 +#: ../../../CHANGELOG.md:3239 msgid "2020-08-21" msgstr "" -#: ../../../CHANGELOG.md:2589 +#: ../../../CHANGELOG.md:3241 msgid "rust-synapse-compress-state support" msgstr "" -#: ../../../CHANGELOG.md:2591 +#: ../../../CHANGELOG.md:3243 msgid "The playbook can now help you use [rust-synapse-compress-state](https://github.com/matrix-org/rust-synapse-compress-state) to compress the state groups in your Synapse database." msgstr "" -#: ../../../CHANGELOG.md:2593 +#: ../../../CHANGELOG.md:3245 msgid "See our [Compressing state with rust-synapse-compress-state](docs/maintenance-synapse.md#compressing-state-with-rust-synapse-compress-state) documentation page to get started." msgstr "" -#: ../../../CHANGELOG.md:2596 +#: ../../../CHANGELOG.md:3248 msgid "2020-07-22" msgstr "" -#: ../../../CHANGELOG.md:2598 +#: ../../../CHANGELOG.md:3250 msgid "Synapse Admin support" msgstr "" -#: ../../../CHANGELOG.md:2600 +#: ../../../CHANGELOG.md:3252 msgid "The playbook can now help you set up [synapse-admin](https://github.com/Awesome-Technologies/synapse-admin)." msgstr "" -#: ../../../CHANGELOG.md:2602 +#: ../../../CHANGELOG.md:3254 msgid "See our [Setting up Synapse Admin](docs/configuring-playbook-synapse-admin.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2605 +#: ../../../CHANGELOG.md:3257 msgid "2020-07-20" msgstr "" -#: ../../../CHANGELOG.md:2607 +#: ../../../CHANGELOG.md:3259 msgid "matrix-reminder-bot support" msgstr "" -#: ../../../CHANGELOG.md:2609 +#: ../../../CHANGELOG.md:3261 msgid "The playbook can now help you set up [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot)." msgstr "" -#: ../../../CHANGELOG.md:2611 +#: ../../../CHANGELOG.md:3263 msgid "See our [Setting up matrix-reminder-bot](docs/configuring-playbook-bot-matrix-reminder-bot.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2614 +#: ../../../CHANGELOG.md:3266 msgid "2020-07-17" msgstr "" -#: ../../../CHANGELOG.md:2616 +#: ../../../CHANGELOG.md:3268 msgid "(Compatibility Break) Riot is now Element" msgstr "" -#: ../../../CHANGELOG.md:2618 +#: ../../../CHANGELOG.md:3270 msgid "As per the official announcement, [Riot has been rebraned to Element](https://element.io/blog/welcome-to-element/)." msgstr "" -#: ../../../CHANGELOG.md:2620 +#: ../../../CHANGELOG.md:3272 msgid "The playbook follows suit. Existing installations have a few options for how to handle this." msgstr "" -#: ../../../CHANGELOG.md:2622 +#: ../../../CHANGELOG.md:3274 msgid "See our [Migrating to Element Web](docs/configuring-playbook-riot-web.md#migrating-to-element) documentation page for more details." msgstr "" -#: ../../../CHANGELOG.md:2625 +#: ../../../CHANGELOG.md:3277 msgid "2020-07-03" msgstr "" -#: ../../../CHANGELOG.md:2627 +#: ../../../CHANGELOG.md:3279 msgid "Steam bridging support via mx-puppet-steam" msgstr "" -#: ../../../CHANGELOG.md:2629 -msgid "Thanks to [Hugues Morisset](https://github.com/izissise)'s efforts, the playbook now supports bridging to [Steam](https://steamapp.com/) via the [mx-puppet-steam](https://github.com/icewind1991/mx-puppet-steam) bridge. See our [Setting up MX Puppet Steam bridging](docs/configuring-playbook-bridge-mx-puppet-steam.md) documentation page for getting started." +#: ../../../CHANGELOG.md:3281 +msgid "Thanks to [Hugues Morisset](https://github.com/izissise)'s efforts, the playbook now supports bridging to [Steam](https://steamapp.com/) via the [mx-puppet-steam](https://codeberg.org/icewind/mx-puppet-steam) bridge. See our [Setting up MX Puppet Steam bridging](docs/configuring-playbook-bridge-mx-puppet-steam.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:2632 +#: ../../../CHANGELOG.md:3284 msgid "2020-07-01" msgstr "" -#: ../../../CHANGELOG.md:2634 +#: ../../../CHANGELOG.md:3286 msgid "Discord bridging support via mx-puppet-discord" msgstr "" -#: ../../../CHANGELOG.md:2636 +#: ../../../CHANGELOG.md:3288 msgid "Thanks to [Hugues Morisset](https://github.com/izissise)'s efforts, the playbook now supports bridging to [Discord](https://discordapp.com/) via the [mx-puppet-discord](https://github.com/Sorunome/mx-puppet-discord) bridge. See our [Setting up MX Puppet Discord bridging](docs/configuring-playbook-bridge-mx-puppet-discord.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:2638 +#: ../../../CHANGELOG.md:3290 msgid "**Note**: this is a new Discord bridge. The playbook still retains Discord bridging via [matrix-appservice-discord](docs/configuring-playbook-bridge-appservice-discord.md). You're free too use the bridge that serves you better, or even both (for different users and use-cases)." msgstr "" -#: ../../../CHANGELOG.md:2641 +#: ../../../CHANGELOG.md:3293 msgid "2020-06-30" msgstr "" -#: ../../../CHANGELOG.md:2643 +#: ../../../CHANGELOG.md:3295 msgid "Instagram and Twitter bridging support" msgstr "" -#: ../../../CHANGELOG.md:2645 +#: ../../../CHANGELOG.md:3297 msgid "Thanks to [Johanna Dorothea Reichmann](https://github.com/jdreichmann)'s efforts, the playbook now supports bridging to [Instagram](https://www.instagram.com/) via the [mx-puppet-instagram](https://github.com/Sorunome/mx-puppet-instagram) bridge. See our [Setting up MX Puppet Instagram bridging](docs/configuring-playbook-bridge-mx-puppet-instagram.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:2647 +#: ../../../CHANGELOG.md:3299 msgid "Thanks to [Tulir Asokan](https://github.com/tulir)'s efforts, the playbook now supports bridging to [Twitter](https://twitter.com/) via the [mx-puppet-twitter](https://github.com/Sorunome/mx-puppet-twitter) bridge. See our [Setting up MX Puppet Twitter bridging](docs/configuring-playbook-bridge-mx-puppet-twitter.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:2650 +#: ../../../CHANGELOG.md:3302 msgid "2020-06-28" msgstr "" -#: ../../../CHANGELOG.md:2652 +#: ../../../CHANGELOG.md:3304 msgid "(Post Mortem / fixed Security Issue) Re-enabling User Directory search powered by the ma1sd Identity Server" msgstr "" -#: ../../../CHANGELOG.md:2654 ../../../CHANGELOG.md:2683 +#: ../../../CHANGELOG.md:3306 ../../../CHANGELOG.md:3335 msgid "User Directory search requests used to go to the ma1sd identity server by default, which queried its own stores and the Synapse database." msgstr "" -#: ../../../CHANGELOG.md:2656 +#: ../../../CHANGELOG.md:3308 msgid "ma1sd's [security issue](https://github.com/ma1uta/ma1sd/issues/44) has been fixed in version `2.4.0`, with [this commit](ma1uta/ma1sd@2bb5a734d11662b06471113cf3d6b4cee5e33a85). `ma1sd 2.4.0` is now the default version for this playbook. For more information on what happened, please check the mentioned issue." msgstr "" -#: ../../../CHANGELOG.md:2658 +#: ../../../CHANGELOG.md:3310 msgid "We are re-enabling user directory search with this update. Those who would like to keep it disabled can use this configuration: `matrix_nginx_proxy_proxy_matrix_user_directory_search_enabled: false`" msgstr "" -#: ../../../CHANGELOG.md:2660 +#: ../../../CHANGELOG.md:3312 msgid "As always, re-running the playbook is enough to get the updated bits." msgstr "" -#: ../../../CHANGELOG.md:2662 +#: ../../../CHANGELOG.md:3314 msgid "2020-06-11" msgstr "" -#: ../../../CHANGELOG.md:2664 +#: ../../../CHANGELOG.md:3316 msgid "SMS bridging requires db reset" msgstr "" -#: ../../../CHANGELOG.md:2666 -msgid "The current version of [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) needs you to delete the database to work as expected. Just remove `/matrix/matrix-sms-bridge/database/*`. It also adds a new requried var `matrix_sms_bridge_default_region`." +#: ../../../CHANGELOG.md:3318 +msgid "The current version of [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) needs you to delete the database to work as expected. Just remove `/matrix/matrix-sms-bridge/database/*`. It also adds a new required var `matrix_sms_bridge_default_region`." msgstr "" -#: ../../../CHANGELOG.md:2668 +#: ../../../CHANGELOG.md:3320 msgid "To reuse your existing rooms, invite `@smsbot:yourServer` to the room or write a message. You are also able to use automated room creation with telephonenumers by writing `sms send -t 01749292923 \"Hello World\"` in a room with `@smsbot:yourServer`. See [the docs](https://github.com/benkuly/matrix-sms-bridge) for more information." msgstr "" -#: ../../../CHANGELOG.md:2670 +#: ../../../CHANGELOG.md:3322 msgid "2020-06-05" msgstr "" -#: ../../../CHANGELOG.md:2672 +#: ../../../CHANGELOG.md:3324 msgid "SMS bridging support" msgstr "" -#: ../../../CHANGELOG.md:2674 +#: ../../../CHANGELOG.md:3326 msgid "Thanks to [benkuly](https://github.com/benkuly)'s efforts, the playbook now supports bridging to SMS (with one telephone number only) via [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge)." msgstr "" -#: ../../../CHANGELOG.md:2676 +#: ../../../CHANGELOG.md:3328 msgid "See our [Setting up Matrix SMS bridging](docs/configuring-playbook-bridge-matrix-bridge-sms.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:2679 +#: ../../../CHANGELOG.md:3331 msgid "2020-05-19" msgstr "" -#: ../../../CHANGELOG.md:2681 +#: ../../../CHANGELOG.md:3333 msgid "(Compatibility Break / Security Issue) Disabling User Directory search powered by the ma1sd Identity Server" msgstr "" -#: ../../../CHANGELOG.md:2685 +#: ../../../CHANGELOG.md:3337 msgid "ma1sd current has [a security issue](https://github.com/ma1uta/ma1sd/issues/44), which made it leak information about all users — including users created by bridges, etc." msgstr "" -#: ../../../CHANGELOG.md:2687 +#: ../../../CHANGELOG.md:3339 msgid "Until the issue gets fixed, we're making User Directory search not go to ma1sd by default. You **need to re-run the playbook and restart services to apply this workaround**." msgstr "" -#: ../../../CHANGELOG.md:2689 +#: ../../../CHANGELOG.md:3341 msgid "*If you insist on restoring the old behavior* (**which has a security issue!**), you *might* use this configuration: `matrix_nginx_proxy_proxy_matrix_user_directory_search_enabled: \"{{ matrix_ma1sd_enabled }}\"`" msgstr "" -#: ../../../CHANGELOG.md:2692 +#: ../../../CHANGELOG.md:3344 msgid "2020-04-28" msgstr "" -#: ../../../CHANGELOG.md:2694 +#: ../../../CHANGELOG.md:3346 msgid "Newer IRC bridge (with potential breaking change)" msgstr "" -#: ../../../CHANGELOG.md:2696 -msgid "This upgrades matrix-appservice-irc from 0.14.1 to 0.16.0. Upstream made a change to how you define manual mappings. If you added a `mapping` to your configuration, you will need to update it accoring to the [upstream instructions](https://github.com/matrix-org/matrix-appservice-irc/blob/master/CHANGELOG.md#0150-2020-02-05). If you did not include `mappings` in your configuration for IRC, no change is necessary. `mappings` is not part of the default configuration." +#: ../../../CHANGELOG.md:3348 +msgid "This upgrades matrix-appservice-irc from 0.14.1 to 0.16.0. Upstream made a change to how you define manual mappings. If you added a `mapping` to your configuration, you will need to update it according to the [upstream instructions](https://github.com/matrix-org/matrix-appservice-irc/blob/master/CHANGELOG.md#0150-2020-02-05). If you did not include `mappings` in your configuration for IRC, no change is necessary. `mappings` is not part of the default configuration." msgstr "" -#: ../../../CHANGELOG.md:2705 +#: ../../../CHANGELOG.md:3357 msgid "2020-04-23" msgstr "" -#: ../../../CHANGELOG.md:2707 ../../../CHANGELOG.md:2938 +#: ../../../CHANGELOG.md:3359 ../../../CHANGELOG.md:3590 msgid "Slack bridging support" msgstr "" -#: ../../../CHANGELOG.md:2709 +#: ../../../CHANGELOG.md:3361 msgid "Thanks to [Rodrigo Belem](https://github.com/rbelem)'s efforts, the playbook now supports bridging to [Slack](https://slack.com) via the [mx-puppet-slack](https://github.com/Sorunome/mx-puppet-slack) bridge." msgstr "" -#: ../../../CHANGELOG.md:2711 +#: ../../../CHANGELOG.md:3363 msgid "See our [Setting up MX Puppet Slack bridging](docs/configuring-playbook-bridge-mx-puppet-slack.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:2714 +#: ../../../CHANGELOG.md:3366 msgid "2020-04-09" msgstr "" -#: ../../../CHANGELOG.md:2716 +#: ../../../CHANGELOG.md:3368 msgid "Skype bridging support" msgstr "" -#: ../../../CHANGELOG.md:2718 +#: ../../../CHANGELOG.md:3370 msgid "Thanks to [Rodrigo Belem](https://github.com/rbelem)'s efforts, the playbook now supports bridging to [Skype](https://www.skype.com) via the [mx-puppet-skype](https://github.com/Sorunome/mx-puppet-skype) bridge." msgstr "" -#: ../../../CHANGELOG.md:2720 +#: ../../../CHANGELOG.md:3372 msgid "See our [Setting up MX Puppet Skype bridging](docs/configuring-playbook-bridge-mx-puppet-skype.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:2723 +#: ../../../CHANGELOG.md:3375 msgid "2020-04-05" msgstr "" -#: ../../../CHANGELOG.md:2725 +#: ../../../CHANGELOG.md:3377 msgid "Private Jitsi support" msgstr "" -#: ../../../CHANGELOG.md:2727 +#: ../../../CHANGELOG.md:3379 msgid "The [Jitsi support](#jitsi-support) we had landed a few weeks ago was working well, but it was always open to the whole world." msgstr "" -#: ../../../CHANGELOG.md:2729 +#: ../../../CHANGELOG.md:3381 msgid "Running such an open instance is not desirable to most people, so [teutat3s](https://github.com/teutat3s) has contributed support for making Jitsi use authentication." msgstr "" -#: ../../../CHANGELOG.md:2731 +#: ../../../CHANGELOG.md:3383 msgid "To make your Jitsi server more private, see the [configure internal Jitsi authentication and guests mode](docs/configuring-playbook-jitsi.md#optional-configure-internal-jitsi-authentication-and-guests-mode) section in our Jitsi documentation." msgstr "" -#: ../../../CHANGELOG.md:2734 +#: ../../../CHANGELOG.md:3386 msgid "2020-04-03" msgstr "" -#: ../../../CHANGELOG.md:2736 +#: ../../../CHANGELOG.md:3388 msgid "(Potential Backward Compatibility Break) ma1sd replaces mxisd" msgstr "" -#: ../../../CHANGELOG.md:2738 +#: ../../../CHANGELOG.md:3390 msgid "Thanks to [Marcel Partap](https://github.com/eMPee584)'s efforts, the [mxisd](https://github.com/kamax-io/mxisd) identity server, which has been deprecated for a long time, has finally been replaced by [ma1sd](https://github.com/ma1uta/ma1sd), a compatible fork." msgstr "" -#: ../../../CHANGELOG.md:2740 +#: ../../../CHANGELOG.md:3392 msgid "**If you're using the default playbook configuration**, you don't need to do anything — your mxisd installation will be replaced with ma1sd and all existing data will be migrated automatically the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:2742 +#: ../../../CHANGELOG.md:3394 msgid "**If you're doing something more special** (defining custom `matrix_mxisd_*` variables), the playbook will ask you to rename them to `matrix_ma1sd_*`. You're also encouraged to test that ma1sd works well for such a more custom setup." msgstr "" -#: ../../../CHANGELOG.md:2745 +#: ../../../CHANGELOG.md:3397 msgid "2020-03-29" msgstr "" -#: ../../../CHANGELOG.md:2747 +#: ../../../CHANGELOG.md:3399 msgid "Archlinux support" msgstr "" -#: ../../../CHANGELOG.md:2749 +#: ../../../CHANGELOG.md:3401 msgid "Thanks to [Christian Lupus](https://github.com/christianlupus)'s efforts, the playbook now supports installing to an [Archlinux](https://www.archlinux.org/) server." msgstr "" -#: ../../../CHANGELOG.md:2752 +#: ../../../CHANGELOG.md:3404 msgid "2020-03-24" msgstr "" -#: ../../../CHANGELOG.md:2754 +#: ../../../CHANGELOG.md:3406 msgid "Jitsi support" msgstr "" -#: ../../../CHANGELOG.md:2756 +#: ../../../CHANGELOG.md:3408 msgid "The playbook can now (optionally) install the [Jitsi](https://jitsi.org/) video-conferencing platform and integrate it with [Riot](docs/configuring-playbook-riot-web.md)." msgstr "" -#: ../../../CHANGELOG.md:2758 +#: ../../../CHANGELOG.md:3410 msgid "See our [Jitsi documentation page](docs/configuring-playbook-jitsi.md) to get started." msgstr "" -#: ../../../CHANGELOG.md:2761 +#: ../../../CHANGELOG.md:3413 msgid "2020-03-15" msgstr "" -#: ../../../CHANGELOG.md:2763 +#: ../../../CHANGELOG.md:3415 msgid "Raspberry Pi support" msgstr "" -#: ../../../CHANGELOG.md:2765 +#: ../../../CHANGELOG.md:3417 msgid "Thanks to [Gergely Horváth](https://github.com/hooger)'s effort, the playbook supports installing to a Raspberry Pi server, for at least some of the services." msgstr "" -#: ../../../CHANGELOG.md:2767 +#: ../../../CHANGELOG.md:3419 msgid "Since most ready-made container images do not support that architecture, we achieve this by building images locally on the device itself. See our [Self-building documentation page](docs/self-building.md) for how to get started." msgstr "" -#: ../../../CHANGELOG.md:2770 +#: ../../../CHANGELOG.md:3422 msgid "2020-02-26" msgstr "" -#: ../../../CHANGELOG.md:2772 +#: ../../../CHANGELOG.md:3424 msgid "Riot-web themes are here" msgstr "" -#: ../../../CHANGELOG.md:2774 +#: ../../../CHANGELOG.md:3426 msgid "The playbook now makes it easy to install custom riot-web themes." msgstr "" -#: ../../../CHANGELOG.md:2776 +#: ../../../CHANGELOG.md:3428 msgid "To learn more, take a look at our [riot-web documentation on Themes](docs/configuring-playbook-riot-web.md#themes)." msgstr "" -#: ../../../CHANGELOG.md:2779 +#: ../../../CHANGELOG.md:3431 msgid "2020-02-24" msgstr "" -#: ../../../CHANGELOG.md:2781 +#: ../../../CHANGELOG.md:3433 msgid "Customize the server name in Riot's login page" msgstr "" -#: ../../../CHANGELOG.md:2783 +#: ../../../CHANGELOG.md:3435 msgid "You can now customize the server name string that Riot-web displays in its login page." msgstr "" -#: ../../../CHANGELOG.md:2785 +#: ../../../CHANGELOG.md:3437 msgid "These playbook variables, with these default values, have been added:" msgstr "" -#: ../../../CHANGELOG.md:2791 +#: ../../../CHANGELOG.md:3443 msgid "The login page previously said \"Sign in to your Matrix account on matrix.example.org\" (the homeserver's domain name). It will now say \"Sign in … on example.org\" (the server name) by default, or \"Sign in … on Our Server\" if you set the variable to \"Our Server\"." msgstr "" -#: ../../../CHANGELOG.md:2793 +#: ../../../CHANGELOG.md:3445 msgid "To support this, the config.json template is changed to use the configuration key `default_server_config` for setting the default HS/IS, and the new configuration key `server_name` is added in there." msgstr "" -#: ../../../CHANGELOG.md:2796 +#: ../../../CHANGELOG.md:3448 msgid "2020-01-30" msgstr "" -#: ../../../CHANGELOG.md:2798 +#: ../../../CHANGELOG.md:3450 msgid "Disabling TLSv1.1" msgstr "" -#: ../../../CHANGELOG.md:2800 +#: ../../../CHANGELOG.md:3452 msgid "To improve security, we've removed TLSv1.1 support from our default matrix-nginx-proxy configuration." msgstr "" -#: ../../../CHANGELOG.md:2802 +#: ../../../CHANGELOG.md:3454 msgid "If you need to support old clients, you can re-enable it with the following configuration: `matrix_nginx_proxy_ssl_protocols: \"TLSv1.1 TLSv1.2 TLSv1.3\"`" msgstr "" -#: ../../../CHANGELOG.md:2805 +#: ../../../CHANGELOG.md:3457 msgid "2020-01-21" msgstr "" -#: ../../../CHANGELOG.md:2807 +#: ../../../CHANGELOG.md:3459 msgid "Postgres collation changes (action required!)" msgstr "" -#: ../../../CHANGELOG.md:2809 +#: ../../../CHANGELOG.md:3461 msgid "By default, we've been using a UTF-8 collation for Postgres. This is known to cause Synapse some troubles (see the [relevant issue](https://github.com/matrix-org/synapse/issues/6722)) on systems that use [glibc](https://www.gnu.org/software/libc/). We run Postgres in an [Alpine Linux](https://alpinelinux.org/) container (which uses [musl](https://www.musl-libc.org/), and not glibc), so our users are likely not affected by the index corruption problem observed by others." msgstr "" -#: ../../../CHANGELOG.md:2811 +#: ../../../CHANGELOG.md:3463 msgid "Still, we might become affected in the future. In any case, it's imminent that Synapse will complain about databases which do not use a C collation." msgstr "" -#: ../../../CHANGELOG.md:2813 +#: ../../../CHANGELOG.md:3465 msgid "To avoid future problems, we recommend that you run the following command:" msgstr "" -#: ../../../CHANGELOG.md:2819 +#: ../../../CHANGELOG.md:3471 msgid "It forces a [Postgres database upgrade](docs/maintenance-postgres.md#upgrading-postgresql), which would recreate your Postgres database using the proper (`C`) collation. If you are low on disk space, or run into trouble, refer to the Postgres database upgrade documentation page." msgstr "" -#: ../../../CHANGELOG.md:2822 +#: ../../../CHANGELOG.md:3474 msgid "2020-01-14" msgstr "" -#: ../../../CHANGELOG.md:2824 +#: ../../../CHANGELOG.md:3476 msgid "Added support for Appservice Webhooks" msgstr "" -#: ../../../CHANGELOG.md:2826 +#: ../../../CHANGELOG.md:3478 msgid "Thanks to a contribution from [Björn Marten](https://github.com/tripleawwy) from [netresearch](https://www.netresearch.de/), the playbook can now install and configure [matrix-appservice-webhooks](https://github.com/turt2live/matrix-appservice-webhooks) for you. This bridge provides support for Slack-compatible webhooks." msgstr "" -#: ../../../CHANGELOG.md:2828 +#: ../../../CHANGELOG.md:3480 msgid "Learn more in [Setting up Appservice Webhooks bridging](docs/configuring-playbook-bridge-appservice-webhooks.md)." msgstr "" -#: ../../../CHANGELOG.md:2831 +#: ../../../CHANGELOG.md:3483 msgid "2020-01-12" msgstr "" -#: ../../../CHANGELOG.md:2833 +#: ../../../CHANGELOG.md:3485 msgid "Added support for automatic Double Puppeting for all Mautrix bridges" msgstr "" -#: ../../../CHANGELOG.md:2835 +#: ../../../CHANGELOG.md:3487 msgid "Double Puppeting can now be easily enabled for all Mautrix bridges supported by the playbook (Facebook, Hangouts, Whatsapp, Telegram)." msgstr "" -#: ../../../CHANGELOG.md:2837 +#: ../../../CHANGELOG.md:3489 msgid "This is possible due to those bridges' integration with [matrix-synapse-shared-secret-auth](https://github.com/devture/matrix-synapse-shared-secret-auth) — yet another component that this playbook can install for you." msgstr "" -#: ../../../CHANGELOG.md:2839 +#: ../../../CHANGELOG.md:3491 msgid "To get started, following the playbook's documentation for the bridge you'd like to configure." msgstr "" -#: ../../../CHANGELOG.md:2842 +#: ../../../CHANGELOG.md:3494 msgid "2019-12-06" msgstr "" -#: ../../../CHANGELOG.md:2844 +#: ../../../CHANGELOG.md:3496 msgid "Added support for an alternative method for using another webserver" msgstr "" -#: ../../../CHANGELOG.md:2846 +#: ../../../CHANGELOG.md:3498 msgid "We have added support for making `matrix-nginx-proxy` not being so invasive, so that it would be easier to [use your own webserver](docs/configuring-playbook-own-webserver.md)." msgstr "" -#: ../../../CHANGELOG.md:2848 +#: ../../../CHANGELOG.md:3500 msgid "The documentation has been updated with a **Method 2**, which might make \"own webserver\" setup easier in some cases (such as [reverse-proxying using Traefik](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/296))." msgstr "" -#: ../../../CHANGELOG.md:2850 +#: ../../../CHANGELOG.md:3502 msgid "**Existing users** are not affected by this and **don't need to change anything**. The defaults are still the same (`matrix-nginx-proxy` obtaining SSL certificates and doing everything for you automatically)." msgstr "" -#: ../../../CHANGELOG.md:2853 +#: ../../../CHANGELOG.md:3505 msgid "2019-11-10" msgstr "" -#: ../../../CHANGELOG.md:2855 +#: ../../../CHANGELOG.md:3507 msgid "Tightened security around room directory publishing" msgstr "" -#: ../../../CHANGELOG.md:2857 +#: ../../../CHANGELOG.md:3509 msgid "As per this [advisory blog post](https://matrix.org/blog/2019/11/09/avoiding-unwelcome-visitors-on-private-matrix-servers), we've decided to change the default publishing rules for the Matrix room directory." msgstr "" -#: ../../../CHANGELOG.md:2859 +#: ../../../CHANGELOG.md:3511 msgid "Our general goal is to favor privacy and security when running personal (family & friends) and corporate homeservers. Both of these likely benefit from having a more secure default of **not showing the room directory without authentication** and **not publishing the room directory over federation**." msgstr "" -#: ../../../CHANGELOG.md:2861 -msgid "As with anything else, these new defaults can be overriden by changing the `matrix_synapse_allow_public_rooms_without_auth` and `matrix_synapse_allow_public_rooms_over_federation` variables, respectively." +#: ../../../CHANGELOG.md:3513 +msgid "As with anything else, these new defaults can be overridden by changing the `matrix_synapse_allow_public_rooms_without_auth` and `matrix_synapse_allow_public_rooms_over_federation` variables, respectively." msgstr "" -#: ../../../CHANGELOG.md:2864 +#: ../../../CHANGELOG.md:3516 msgid "2019-10-05" msgstr "" -#: ../../../CHANGELOG.md:2866 +#: ../../../CHANGELOG.md:3518 msgid "Improved Postgres upgrading/importing" msgstr "" -#: ../../../CHANGELOG.md:2868 +#: ../../../CHANGELOG.md:3520 msgid "Postgres [upgrading](docs/maintenance-postgres.md#upgrading-postgresql) and [importing](docs/importing-postgres.md) have been improved to add support for multiple databases and roles." msgstr "" -#: ../../../CHANGELOG.md:2870 +#: ../../../CHANGELOG.md:3522 msgid "Previously, the playbook would only take care of the `homeserver` database and `synapse` user. We now back up and restore all databases and users on the Postgres server." msgstr "" -#: ../../../CHANGELOG.md:2872 +#: ../../../CHANGELOG.md:3524 msgid "For now, the playbook only uses that one database (`homeserver`) and that one single user (`synapse`), so it's all the same. However, in the future, additional components besides Synapse may also make use the Postgres database server. One such example is the [matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) bridge, which strongly encourages use of Postgres in its v1.0 release. We are yet to upgrade to it." msgstr "" -#: ../../../CHANGELOG.md:2874 +#: ../../../CHANGELOG.md:3526 msgid "Additionally, Postgres [upgrading](docs/maintenance-postgres.md#upgrading-postgresql) now uses gzipped dump files by default, to minimize disk space usage." msgstr "" -#: ../../../CHANGELOG.md:2877 +#: ../../../CHANGELOG.md:3529 msgid "2019-10-04" msgstr "" -#: ../../../CHANGELOG.md:2879 +#: ../../../CHANGELOG.md:3531 msgid "Postgres 12 support" msgstr "" -#: ../../../CHANGELOG.md:2881 +#: ../../../CHANGELOG.md:3533 msgid "The playbook now installs [Postgres 12](https://www.postgresql.org/about/news/1976/) by default." msgstr "" -#: ../../../CHANGELOG.md:2883 +#: ../../../CHANGELOG.md:3535 msgid "If you have have an existing setup, it's likely running on an older Postgres version (9.x, 10.x or 11.x). You can easily upgrade by following the [upgrading PostgreSQL guide](docs/maintenance-postgres.md#upgrading-postgresql)." msgstr "" -#: ../../../CHANGELOG.md:2886 +#: ../../../CHANGELOG.md:3538 msgid "2019-10-03" msgstr "" -#: ../../../CHANGELOG.md:2888 +#: ../../../CHANGELOG.md:3540 msgid "Synapse 1.4.0" msgstr "" -#: ../../../CHANGELOG.md:2890 +#: ../../../CHANGELOG.md:3542 msgid "Synapse 1.4.0 [is out](https://matrix.org/blog/2019/10/03/synapse-1-4-0-released) with lots of changes related to privacy." msgstr "" -#: ../../../CHANGELOG.md:2892 +#: ../../../CHANGELOG.md:3544 msgid "Its new defaults (which we adopt as well) mean that certain old data will automatically get purged after a certain number of days. 1.4.0 automatically garbage collects redacted messages (defaults to 7 days) and removes unused IP and user agent information stored in the user_ips table (defaults to 30 days). If you'd like to preserve this data, we encourage you to look at the `redaction_retention_period` and `user_ips_max_age` options (controllable by the `matrix_synapse_redaction_retention_period` and `matrix_synapse_user_ips_max_age` playbook variables, respectively) before doing the upgrade. If you'd like to keep data indefinitely, set these variables to `null` (e.g. `matrix_synapse_redaction_retention_period: ~`)." msgstr "" -#: ../../../CHANGELOG.md:2894 +#: ../../../CHANGELOG.md:3546 msgid "From now on the `trusted_key_servers` setting for Synapse is configurable. It still defaults to `matrix.org` just like it always has, but in a more explicit way now. If you'd like to use another trusted key server, adjust the `matrix_synapse_trusted_key_servers` playbook variable." msgstr "" -#: ../../../CHANGELOG.md:2896 +#: ../../../CHANGELOG.md:3548 msgid "Synapse 1.4.0 also changes lots of things related to identity server integration. Because Synapse will now by default be responsible for validating email addresses for user accounts, running without an identity server looks more feasible. We still [have concerns](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/275/files#r331104117) over disabling the identity server by default, so for now it remains enabled." msgstr "" -#: ../../../CHANGELOG.md:2899 +#: ../../../CHANGELOG.md:3551 msgid "2019-09-09" msgstr "" -#: ../../../CHANGELOG.md:2901 +#: ../../../CHANGELOG.md:3553 msgid "Synapse Simple Antispam support" msgstr "" -#: ../../../CHANGELOG.md:2903 +#: ../../../CHANGELOG.md:3555 msgid "There have been lots of invite-spam attacks lately and [Travis](https://github.com/t2bot) has created a Synapse module ([synapse-simple-antispam](https://github.com/t2bot/synapse-simple-antispam)) to let people protect themselves." msgstr "" -#: ../../../CHANGELOG.md:2905 +#: ../../../CHANGELOG.md:3557 msgid "From now on, you can easily install and configure this spam checker module through the playbook." msgstr "" -#: ../../../CHANGELOG.md:2907 +#: ../../../CHANGELOG.md:3559 msgid "Learn more in [Setting up Synapse Simple Antispam](docs/configuring-playbook-synapse-simple-antispam.md)." msgstr "" -#: ../../../CHANGELOG.md:2910 +#: ../../../CHANGELOG.md:3562 msgid "2019-08-25" msgstr "" -#: ../../../CHANGELOG.md:2912 +#: ../../../CHANGELOG.md:3564 msgid "Extensible Riot-web configuration" msgstr "" -#: ../../../CHANGELOG.md:2914 +#: ../../../CHANGELOG.md:3566 msgid "Similarly to [Extensible Synapse configuration](#extensible-synapse-configuration) (below), Riot-web configuration is also extensible now." msgstr "" -#: ../../../CHANGELOG.md:2916 +#: ../../../CHANGELOG.md:3568 msgid "From now on, you can extend/override Riot-web's configuration by making use of the `matrix_riot_web_configuration_extension_json` variable. This should be enough for most customization needs." msgstr "" -#: ../../../CHANGELOG.md:2918 +#: ../../../CHANGELOG.md:3570 msgid "If you need even more power, you can now also take full control and override `matrix_riot_web_configuration_default` (or `matrix_riot_web_configuration`) directly." msgstr "" -#: ../../../CHANGELOG.md:2920 +#: ../../../CHANGELOG.md:3572 msgid "Learn more in [Configuring Riot-web](docs/configuring-playbook-riot-web.md)." msgstr "" -#: ../../../CHANGELOG.md:2923 +#: ../../../CHANGELOG.md:3575 msgid "2019-08-22" msgstr "" -#: ../../../CHANGELOG.md:2925 +#: ../../../CHANGELOG.md:3577 msgid "Extensible Synapse configuration" msgstr "" -#: ../../../CHANGELOG.md:2927 +#: ../../../CHANGELOG.md:3579 msgid "Previously, we had to create custom Ansible variables for each and every Synapse setting. This lead to too much effort (and configuration ugliness) to all of Synapse's settings, so naturally, not all features of Synapse could be controlled through the playbook." msgstr "" -#: ../../../CHANGELOG.md:2929 +#: ../../../CHANGELOG.md:3581 msgid "From now on, you can extend/override the Synapse server's configuration by making use of the `matrix_synapse_configuration_extension_yaml` variable. This should be enough for most customization needs." msgstr "" -#: ../../../CHANGELOG.md:2931 +#: ../../../CHANGELOG.md:3583 msgid "If you need even more power, you can now also take full control and override `matrix_synapse_configuration` (or `matrix_synapse_configuration_yaml`) directly." msgstr "" -#: ../../../CHANGELOG.md:2933 +#: ../../../CHANGELOG.md:3585 msgid "Learn more here in [Configuring Synapse](docs/configuring-playbook-synapse.md)." msgstr "" -#: ../../../CHANGELOG.md:2936 +#: ../../../CHANGELOG.md:3588 msgid "2019-08-21" msgstr "" -#: ../../../CHANGELOG.md:2940 +#: ../../../CHANGELOG.md:3592 msgid "Thanks to the [great work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/205) of [kingoftheconnors](https://github.com/kingoftheconnors) and [Stuart Mumford (Cadair)](https://github.com/Cadair), the playbook now supports bridging to [Slack](https://slack.com) via the [appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) bridge." msgstr "" -#: ../../../CHANGELOG.md:2942 +#: ../../../CHANGELOG.md:3594 msgid "Additional details are available in [Setting up Appservice Slack bridging](docs/configuring-playbook-bridge-appservice-slack.md)." msgstr "" -#: ../../../CHANGELOG.md:2944 +#: ../../../CHANGELOG.md:3596 msgid "Google Hangouts bridging support" msgstr "" -#: ../../../CHANGELOG.md:2946 +#: ../../../CHANGELOG.md:3598 msgid "Thanks to the [great work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/251) of [Eduardo Beltrame (Munfred)](https://github.com/Munfred) and [Robbie D (microchipster)](https://github.com/microchipster), the playbook now supports bridging to [Google Hangouts](https://hangouts.google.com/) via the [mautrix-hangouts](https://mau.dev/tulir/mautrix-hangouts) bridge." msgstr "" -#: ../../../CHANGELOG.md:2948 +#: ../../../CHANGELOG.md:3600 msgid "Additional details are available in [Setting up Mautrix Hangouts bridging](docs/configuring-playbook-bridge-mautrix-hangouts.md)." msgstr "" -#: ../../../CHANGELOG.md:2951 +#: ../../../CHANGELOG.md:3603 msgid "2019-08-05" msgstr "" -#: ../../../CHANGELOG.md:2953 +#: ../../../CHANGELOG.md:3605 msgid "Email2Matrix support" msgstr "" -#: ../../../CHANGELOG.md:2955 +#: ../../../CHANGELOG.md:3607 msgid "Support for [Email2Matrix](https://github.com/devture/email2matrix) has been added." msgstr "" -#: ../../../CHANGELOG.md:2957 +#: ../../../CHANGELOG.md:3609 msgid "It's an optional feature that you can enable via the playbook." msgstr "" -#: ../../../CHANGELOG.md:2959 +#: ../../../CHANGELOG.md:3611 msgid "To learn more, see the [playbook's documentation on Email2Matrix](./docs/configuring-playbook-email2matrix.md)." msgstr "" -#: ../../../CHANGELOG.md:2962 +#: ../../../CHANGELOG.md:3614 msgid "2019-08-03" msgstr "" -#: ../../../CHANGELOG.md:2964 +#: ../../../CHANGELOG.md:3616 msgid "Synapse logging level has been reduced to WARNING" msgstr "" -#: ../../../CHANGELOG.md:2966 +#: ../../../CHANGELOG.md:3618 msgid "After [some discussion in our support room](https://matrix.to/#/!PukFFdIcHgtaaHZflT:devture.com/$156476852524179TBeKy:matrix.org?via=devture.com&via=matrix.org&via=librem.one), we've decided to change the default logging level for Synapse from `INFO` to `WARNING`." msgstr "" -#: ../../../CHANGELOG.md:2968 +#: ../../../CHANGELOG.md:3620 msgid "This greatly reduces the number of log messages that are being logged, leading to:" msgstr "" -#: ../../../CHANGELOG.md:2970 +#: ../../../CHANGELOG.md:3622 msgid "much less disk space dedicated to Synapse and thus, logs kept for longer" msgstr "" -#: ../../../CHANGELOG.md:2971 +#: ../../../CHANGELOG.md:3623 msgid "easier to find some important `WARNING`, `ERROR` and `CRITICAL` messages, as they're not longer buried in thousands of non-important `INFO` messages" msgstr "" -#: ../../../CHANGELOG.md:2973 +#: ../../../CHANGELOG.md:3625 msgid "If you'd like to track down an issue, you [can always increase the logging level as described here](./docs/maintenance-and-troubleshooting.md#increasing-synapse-logging)." msgstr "" -#: ../../../CHANGELOG.md:2976 +#: ../../../CHANGELOG.md:3628 msgid "2019-07-08" msgstr "" -#: ../../../CHANGELOG.md:2978 +#: ../../../CHANGELOG.md:3630 msgid "Synapse Maintenance docs and synapse-janitor support are available" msgstr "" -#: ../../../CHANGELOG.md:2980 +#: ../../../CHANGELOG.md:3632 msgid "The playbook can now help you with Synapse's maintenance." msgstr "" -#: ../../../CHANGELOG.md:2982 +#: ../../../CHANGELOG.md:3634 msgid "There's a new documentation page about [Synapse maintenance](./docs/maintenance-synapse.md) and another section on [Postgres vacuuming](./docs/maintenance-postgres.md#vacuuming-postgresql)." msgstr "" -#: ../../../CHANGELOG.md:2984 +#: ../../../CHANGELOG.md:3636 msgid "Among other things, if your Postgres database has grown significantly over time, you may wish to [ask the playbook to purge unused data with synapse-janitor](./docs/maintenance-synapse.md#purging-unused-data-with-synapse-janitor) for you." msgstr "" -#: ../../../CHANGELOG.md:2986 +#: ../../../CHANGELOG.md:3638 msgid "(BC Break) Rename run control variables" msgstr "" -#: ../../../CHANGELOG.md:2988 +#: ../../../CHANGELOG.md:3640 msgid "Some internal playbook control variables have been renamed." msgstr "" -#: ../../../CHANGELOG.md:2990 +#: ../../../CHANGELOG.md:3642 msgid "This change **only affects people who run this playbook's roles from another playbook**. If you're using this playbook as-is, you're not affected and don't need to do anything." msgstr "" -#: ../../../CHANGELOG.md:2992 +#: ../../../CHANGELOG.md:3644 msgid "The following variables have been renamed:" msgstr "" -#: ../../../CHANGELOG.md:2994 +#: ../../../CHANGELOG.md:3646 msgid "from `run_import_postgres` to `run_postgres_import`" msgstr "" -#: ../../../CHANGELOG.md:2995 +#: ../../../CHANGELOG.md:3647 msgid "from `run_import_sqlite_db` to `run_postgres_import_sqlite_db`" msgstr "" -#: ../../../CHANGELOG.md:2996 +#: ../../../CHANGELOG.md:3648 msgid "from `run_upgrade_postgres` to `run_postgres_upgrade`" msgstr "" -#: ../../../CHANGELOG.md:2997 +#: ../../../CHANGELOG.md:3649 msgid "from `run_import_media_store` to `run_synapse_import_media_store`" msgstr "" -#: ../../../CHANGELOG.md:2998 +#: ../../../CHANGELOG.md:3650 msgid "from `run_register_user` to `run_synapse_register_user`" msgstr "" -#: ../../../CHANGELOG.md:2999 +#: ../../../CHANGELOG.md:3651 msgid "from `run_update_user_password` to `run_synapse_update_user_password`" msgstr "" -#: ../../../CHANGELOG.md:3002 +#: ../../../CHANGELOG.md:3654 msgid "2019-07-04" msgstr "" -#: ../../../CHANGELOG.md:3004 +#: ../../../CHANGELOG.md:3656 msgid "Synapse no longer logs to text files" msgstr "" -#: ../../../CHANGELOG.md:3006 +#: ../../../CHANGELOG.md:3658 msgid "Following what the official Synapse Docker image is doing ([#5565](https://github.com/matrix-org/synapse/pull/5565)) and what we've been doing for mostly everything installed by this playbook, **Synapse no longer logs to text files** (`/matrix/synapse/run/homeserver.log*`)." msgstr "" -#: ../../../CHANGELOG.md:3008 +#: ../../../CHANGELOG.md:3660 msgid "From now on, Synapse would only log to console, which goes to systemd's journald. To see Synapse's logs, execute: `journalctl -fu matrix-synapse`" msgstr "" -#: ../../../CHANGELOG.md:3010 +#: ../../../CHANGELOG.md:3662 msgid "Because of this, the following variables have become obsolete and were removed:" msgstr "" -#: ../../../CHANGELOG.md:3012 +#: ../../../CHANGELOG.md:3664 msgid "`matrix_synapse_max_log_file_size_mb`" msgstr "" -#: ../../../CHANGELOG.md:3013 +#: ../../../CHANGELOG.md:3665 msgid "`matrix_synapse_max_log_files_count`" msgstr "" -#: ../../../CHANGELOG.md:3015 +#: ../../../CHANGELOG.md:3667 msgid "To prevent confusion, it'd be better if you delete all old files manually after you've upgraded (`rm -f /matrix/synapse/run/homeserver.log*`)." msgstr "" -#: ../../../CHANGELOG.md:3017 +#: ../../../CHANGELOG.md:3669 msgid "Because Synapse is incredibly chatty when it comes to logging (here's [one such issue](https://github.com/matrix-org/synapse/issues/4751) describing the problem), if you're running an ancient distribution (like CentOS 7.0), be advised that systemd's journald default logging restrictions may not be high enough to capture all log messages generated by Synapse. This is especially true if you've got a busy (Synapse) server. We advise that you manually add `RateLimitInterval=0` and `RateLimitBurst=0` under `[Storage]` in the `/etc/systemd/journald.conf` file, followed by restarting the logging service (`systemctl restart systemd-journald`)." msgstr "" -#: ../../../CHANGELOG.md:3020 +#: ../../../CHANGELOG.md:3672 msgid "2019-06-27" msgstr "" -#: ../../../CHANGELOG.md:3022 +#: ../../../CHANGELOG.md:3674 msgid "(BC Break) Discord bridge configuration is now entirely managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:3024 +#: ../../../CHANGELOG.md:3676 msgid "Until now, the `config.yaml` file for the [Discord bridge](docs/configuring-playbook-bridge-appservice-discord.md) was managed by the playbook, but the `registration.yaml` file was not." msgstr "" -#: ../../../CHANGELOG.md:3026 +#: ../../../CHANGELOG.md:3678 msgid "From now on, the playbook will keep both configuration files sync for you." msgstr "" -#: ../../../CHANGELOG.md:3028 +#: ../../../CHANGELOG.md:3680 msgid "This means that if you were making manual changes to the `/matrix/appservice-discord/discord-registration.yaml` configuration file, those would be lost the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3030 +#: ../../../CHANGELOG.md:3682 msgid "The bridge now stores configuration in a subdirectory (`/matrix/appservice-discord/config`)." msgstr "" -#: ../../../CHANGELOG.md:3032 +#: ../../../CHANGELOG.md:3684 msgid "Likewise, data is now also stored in a subdirectory (`/matrix/appservice-discord/data`). When you run the playbook with an existing database file (`/matrix/appservice-discord/discord.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3034 +#: ../../../CHANGELOG.md:3686 msgid "The main directory (`/matrix/appservice-discord`) may contain some leftover files (`user-store.db`, `room-store.db`, `config.yaml`, `discord-registration.yaml`, `invite_link`). These are no longer necessary and can be deleted manually." msgstr "" -#: ../../../CHANGELOG.md:3036 +#: ../../../CHANGELOG.md:3688 msgid "We're now following the default sample configuration for the Discord bridge. If you need to override some values, define them in `matrix_appservice_discord_configuration_extension_yaml`." msgstr "" -#: ../../../CHANGELOG.md:3039 +#: ../../../CHANGELOG.md:3691 msgid "2019-06-24" msgstr "" -#: ../../../CHANGELOG.md:3041 +#: ../../../CHANGELOG.md:3693 msgid "(BC Break) WhatsApp bridge configuration is now entirely managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:3043 +#: ../../../CHANGELOG.md:3695 msgid "Until now, configuration files for the [WhatsApp bridge](docs/configuring-playbook-bridge-mautrix-whatsapp.md) were created by the playbook initially, but never modified later on." msgstr "" -#: ../../../CHANGELOG.md:3045 ../../../CHANGELOG.md:3062 -#: ../../../CHANGELOG.md:3081 ../../../CHANGELOG.md:3120 +#: ../../../CHANGELOG.md:3697 ../../../CHANGELOG.md:3714 +#: ../../../CHANGELOG.md:3733 ../../../CHANGELOG.md:3772 msgid "From now on, the playbook will keep the configuration in sync for you." msgstr "" -#: ../../../CHANGELOG.md:3047 +#: ../../../CHANGELOG.md:3699 msgid "This means that if you were making manual changes to the `/matrix/mautrix-whatsapp/config.yaml` or `/matrix/mautrix-whatsapp/registration.yaml` configuration files, those would be lost the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3049 +#: ../../../CHANGELOG.md:3701 msgid "The bridge now stores configuration in a subdirectory (`/matrix/mautrix-whatsapp/config`), so your old configuration remains in the base directory (`/matrix/mautrix-whatsapp`). You need to migrate any manual changes over to the new `matrix_mautrix_whatsapp_configuration_extension_yaml` variable, so that the playbook would apply them for you." msgstr "" -#: ../../../CHANGELOG.md:3051 +#: ../../../CHANGELOG.md:3703 msgid "Likewise, data is now also stored in a subdirectory (`/matrix/mautrix-whatsapp/data`). When you run the playbook with an existing database file (`/matrix/mautrix-whatsapp/mautrix-whatsapp.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3053 +#: ../../../CHANGELOG.md:3705 msgid "We're now following the default configuration for the WhatsApp bridge." msgstr "" -#: ../../../CHANGELOG.md:3056 +#: ../../../CHANGELOG.md:3708 msgid "2019-06-20" msgstr "" -#: ../../../CHANGELOG.md:3058 +#: ../../../CHANGELOG.md:3710 msgid "(BC Break) IRC bridge configuration is now entirely managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:3060 +#: ../../../CHANGELOG.md:3712 msgid "Until now, configuration files for the [IRC bridge](docs/configuring-playbook-bridge-appservice-irc.md) were created by the playbook initially, but never modified later on." msgstr "" -#: ../../../CHANGELOG.md:3064 +#: ../../../CHANGELOG.md:3716 msgid "This means that if you were making manual changes to the `/matrix/appservice-irc/config.yaml` or `/matrix/appservice-irc/registration.yaml` configuration files, those would be lost the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3066 +#: ../../../CHANGELOG.md:3718 msgid "The bridge now stores configuration in a subdirectory (`/matrix/appservice-irc/config`), so your old configuration remains in the base directory (`/matrix/appservice-irc`)." msgstr "" -#: ../../../CHANGELOG.md:3068 +#: ../../../CHANGELOG.md:3720 msgid "Previously, we asked people to configure bridged IRC servers by extending the bridge configuration (`matrix_appservice_irc_configuration_extension_yaml`). While this is still possible and will continue working forever, **we now recommend defining IRC servers in the easier to use `matrix_appservice_irc_ircService_servers` variable**. See [our IRC bridge documentation page](docs/configuring-playbook-bridge-appservice-irc.md) for an example." msgstr "" -#: ../../../CHANGELOG.md:3070 +#: ../../../CHANGELOG.md:3722 msgid "If you decide to continue using `matrix_appservice_irc_configuration_extension_yaml`, you might be interested to know that `ircService.databaseUri` and a few other keys now have default values in the base configuration (`matrix_appservice_irc_configuration_yaml`). You may wish to stop redefining those keys, unless you really intend to override them. You most likely only need to override `ircService.servers`." msgstr "" -#: ../../../CHANGELOG.md:3072 +#: ../../../CHANGELOG.md:3724 msgid "Bridge data (`passkey.pem` and database files) is now also stored in a subdirectory (`/matrix/appservice-irc/data`). When you run the playbook with an existing `/matrix/appservice-irc/passkey.pem` file, the playbook will stop the bridge and relocate the passkey and database files (`rooms.db` and `users.db`) to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3075 +#: ../../../CHANGELOG.md:3727 msgid "2019-06-15" msgstr "" -#: ../../../CHANGELOG.md:3077 +#: ../../../CHANGELOG.md:3729 msgid "(BC Break) Telegram bridge configuration is now entirely managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:3079 +#: ../../../CHANGELOG.md:3731 msgid "Until now, configuration files for the [Telegram bridge](docs/configuring-playbook-bridge-mautrix-telegram.md) were created by the playbook initially, but never modified later on." msgstr "" -#: ../../../CHANGELOG.md:3083 +#: ../../../CHANGELOG.md:3735 msgid "This means that if you were making manual changes to the `/matrix/mautrix-telegram/config.yaml` or `/matrix/mautrix-telegram/registration.yaml` configuration files, those would be lost the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3085 +#: ../../../CHANGELOG.md:3737 msgid "The bridge now stores configuration in a subdirectory (`/matrix/mautrix-telegram/config`), so your old configuration remains in the base directory (`/matrix/mautrix-telegram`). You need to migrate any manual changes over to the new `matrix_mautrix_telegram_configuration_extension_yaml` variable, so that the playbook would apply them for you." msgstr "" -#: ../../../CHANGELOG.md:3087 +#: ../../../CHANGELOG.md:3739 msgid "Likewise, data is now also stored in a subdirectory (`/matrix/mautrix-telegram/data`). When you run the playbook with an existing database file (`/matrix/mautrix-telegram/mautrix-telegram.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3089 +#: ../../../CHANGELOG.md:3741 msgid "Also, we're now following the default configuration for the Telegram bridge, so some default configuration values are different:" msgstr "" -#: ../../../CHANGELOG.md:3091 +#: ../../../CHANGELOG.md:3743 msgid "`edits_as_replies` (used to be `false`, now `true`) — previously replies were not sent over to Matrix at all; ow they are sent over as a reply to the original message" msgstr "" -#: ../../../CHANGELOG.md:3092 +#: ../../../CHANGELOG.md:3744 msgid "`inline_images` (used to be `true`, now `false`) — this has to do with captioned images. Inline-image (included caption) are said to exhibit troubles on Riot iOS. When `false`, the caption arrives on the Matrix side as a separate message." msgstr "" -#: ../../../CHANGELOG.md:3093 +#: ../../../CHANGELOG.md:3745 msgid "`authless_portals` (used to be `false`, now `true`) — creating portals from the Telegram side is now possible" msgstr "" -#: ../../../CHANGELOG.md:3094 +#: ../../../CHANGELOG.md:3746 msgid "`whitelist_group_admins` (used to be `false`, now `true`) — allows Telegram group admins to use the bot commands" msgstr "" -#: ../../../CHANGELOG.md:3096 +#: ../../../CHANGELOG.md:3748 msgid "If the new values are not to your liking, use `matrix_mautrix_telegram_configuration_extension_yaml` to specify an override (refer to `matrix_mautrix_telegram_configuration_yaml` to figure out which variable goes where)." msgstr "" -#: ../../../CHANGELOG.md:3099 +#: ../../../CHANGELOG.md:3751 msgid "2019-06-12" msgstr "" -#: ../../../CHANGELOG.md:3101 +#: ../../../CHANGELOG.md:3753 msgid "Synapse v1.0" msgstr "" -#: ../../../CHANGELOG.md:3103 +#: ../../../CHANGELOG.md:3755 msgid "With [Synapse v1.0 now available](https://matrix.org/blog/2019/06/11/introducing-matrix-1-0-and-the-matrix-org-foundation) and most people being on at least Synapse v0.99, it's time to remove the `_matrix._tcp` DNS SRV record that we've been keeping for compatibility with old Synapse versions (<= 0.34)." msgstr "" -#: ../../../CHANGELOG.md:3105 +#: ../../../CHANGELOG.md:3757 msgid "According to the [Server Discovery specification](https://matrix.org/docs/spec/server_server/r0.1.2.html#server-discovery), it's no harm to keep the DNS SRV record. But since it's not necessary for federating with the larger Matrix network anymore, you should be safe to get rid of it." msgstr "" -#: ../../../CHANGELOG.md:3107 +#: ../../../CHANGELOG.md:3759 msgid "**Note**: don't confuse the `_matrix._tcp` and `_matrix-identity._tcp` DNS SRV records. The latter, **must not** be removed." msgstr "" -#: ../../../CHANGELOG.md:3109 +#: ../../../CHANGELOG.md:3761 msgid "For completeness, we must say that using a `_matrix._tcp` [SRV record for Server Delegation](docs/howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced) is still valid and useful for certain deployments. It's just that our guide recommends the [`/.well-known/matrix/server` Server Delegation method](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), due to its easier implementation when using this playbook." msgstr "" -#: ../../../CHANGELOG.md:3111 +#: ../../../CHANGELOG.md:3763 msgid "Besides this optional/non-urgent DNS change, assuming you're already on Synapse v0.99, upgrading to Synapse v1.0 should be as simple as [re-running the playbook](docs/maintenance-upgrading-services.md)." msgstr "" -#: ../../../CHANGELOG.md:3114 +#: ../../../CHANGELOG.md:3766 msgid "2019-06-07" msgstr "" -#: ../../../CHANGELOG.md:3116 +#: ../../../CHANGELOG.md:3768 msgid "(BC Break) Facebook bridge configuration is now entirely managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:3118 +#: ../../../CHANGELOG.md:3770 msgid "Until now, configuration files for the [Facebook bridge](docs/configuring-playbook-bridge-mautrix-facebook.md) were created by the playbook initially, but never modified later on." msgstr "" -#: ../../../CHANGELOG.md:3122 +#: ../../../CHANGELOG.md:3774 msgid "This means that if you were making manual changes to the `/matrix/mautrix-facebook/config.yaml` or `/matrix/mautrix-facebook/registration.yaml` configuration files, those would be lost the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3124 +#: ../../../CHANGELOG.md:3776 msgid "The bridge now stores configuration in a subdirectory (`/matrix/mautrix-facebook/config`), so your old configuration remains in the base directory (`/matrix/mautrix-facebook`). You need to migrate any manual changes over to the new `matrix_mautrix_facebook_configuration_extension_yaml` variable, so that the playbook would apply them for you." msgstr "" -#: ../../../CHANGELOG.md:3126 +#: ../../../CHANGELOG.md:3778 msgid "Likewise, data is now also stored in a subdirectory (`/matrix/mautrix-facebook/data`). When you run the playbook with an existing database file (`/matrix/mautrix-facebook/mautrix-facebook.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3129 +#: ../../../CHANGELOG.md:3781 msgid "2019-05-25" msgstr "" -#: ../../../CHANGELOG.md:3131 +#: ../../../CHANGELOG.md:3783 msgid "Support for exposing container ports publicly (not just to the host)" msgstr "" -#: ../../../CHANGELOG.md:3133 +#: ../../../CHANGELOG.md:3785 msgid "Until now, various roles supported a `matrix_*_expose_port` variable, which would expose their container's port to the host. This was mostly useful for reverse-proxying manually (in case `matrix-nginx-proxy` was disabled). It could also be used for installing some playbook services (e.g. bridges, etc.) and wiring them to a separate (manual) Matrix setup." msgstr "" -#: ../../../CHANGELOG.md:3135 +#: ../../../CHANGELOG.md:3787 msgid "`matrix_*_expose_port` variables were not granular enough — sometimes they would expose one port, other times multiple. They also didn't provide control over **where** to expose (to which port number and to which network interface), because they would usually hardcode something like `127.0.0.1:8080`." msgstr "" -#: ../../../CHANGELOG.md:3137 +#: ../../../CHANGELOG.md:3789 msgid "All such variables have been superseded by a better (more flexible) way to do it." msgstr "" -#: ../../../CHANGELOG.md:3139 +#: ../../../CHANGELOG.md:3791 msgid "**Most** people (including those not using `matrix-nginx-proxy`), **don't need** to bother with this." msgstr "" -#: ../../../CHANGELOG.md:3141 +#: ../../../CHANGELOG.md:3793 msgid "Porting examples follow for people having more customized setups:" msgstr "" -#: ../../../CHANGELOG.md:3143 +#: ../../../CHANGELOG.md:3795 msgid "**from** `matrix_synapse_container_expose_client_api_port: true` **to** `matrix_synapse_container_client_api_host_bind_port: '127.0.0.1:8008'`" msgstr "" -#: ../../../CHANGELOG.md:3145 +#: ../../../CHANGELOG.md:3797 msgid "**from** `matrix_synapse_container_expose_federation_api_port: true` **to** `matrix_synapse_container_federation_api_plain_host_bind_port: '127.0.0.1:8048'` and possibly `matrix_synapse_container_federation_api_tls_host_bind_port: '8448'`" msgstr "" -#: ../../../CHANGELOG.md:3147 +#: ../../../CHANGELOG.md:3799 msgid "**from** `matrix_synapse_container_expose_metrics_port: true` **to** `matrix_synapse_container_metrics_api_host_bind_port: '127.0.0.1:9100'`" msgstr "" -#: ../../../CHANGELOG.md:3149 +#: ../../../CHANGELOG.md:3801 msgid "**from** `matrix_riot_web_container_expose_port: true` **to** `matrix_riot_web_container_http_host_bind_port: '127.0.0.1:8765'`" msgstr "" -#: ../../../CHANGELOG.md:3151 +#: ../../../CHANGELOG.md:3803 msgid "**from** `matrix_mxisd_container_expose_port: true` **to** `matrix_mxisd_container_http_host_bind_port: '127.0.0.1:8090'`" msgstr "" -#: ../../../CHANGELOG.md:3153 +#: ../../../CHANGELOG.md:3805 msgid "**from** `matrix_dimension_container_expose_port: true` **to** `matrix_dimension_container_http_host_bind_port: '127.0.0.1:8184'`" msgstr "" -#: ../../../CHANGELOG.md:3155 +#: ../../../CHANGELOG.md:3807 msgid "**from** `matrix_corporal_container_expose_ports: true` **to** `matrix_corporal_container_http_gateway_host_bind_port: '127.0.0.1:41080'` and possibly `matrix_corporal_container_http_api_host_bind_port: '127.0.0.1:41081'`" msgstr "" -#: ../../../CHANGELOG.md:3157 +#: ../../../CHANGELOG.md:3809 msgid "**from** `matrix_appservice_irc_container_expose_client_server_api_port: true` **to** `matrix_appservice_irc_container_http_host_bind_port: '127.0.0.1:9999'`" msgstr "" -#: ../../../CHANGELOG.md:3159 +#: ../../../CHANGELOG.md:3811 msgid "**from** `matrix_appservice_discord_container_expose_client_server_api_port: true` **to** `matrix_appservice_discord_container_http_host_bind_port: '127.0.0.1:9005'`" msgstr "" -#: ../../../CHANGELOG.md:3161 +#: ../../../CHANGELOG.md:3813 msgid "As always, if you forget to remove usage of some outdated variable, the playbook will warn you." msgstr "" -#: ../../../CHANGELOG.md:3164 +#: ../../../CHANGELOG.md:3816 msgid "2019-05-23" msgstr "" -#: ../../../CHANGELOG.md:3166 +#: ../../../CHANGELOG.md:3818 msgid "(BC Break) Ansible 2.8 compatibility" msgstr "" -#: ../../../CHANGELOG.md:3168 +#: ../../../CHANGELOG.md:3820 msgid "Thanks to [@danbob](https://github.com/danbob), the playbook now [supports the new Ansible 2.8](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/187)." msgstr "" -#: ../../../CHANGELOG.md:3170 +#: ../../../CHANGELOG.md:3822 msgid "A manual change is required to the `inventory/hosts` file, changing the group name from `matrix-servers` to `matrix_servers` (dash to underscore)." msgstr "" -#: ../../../CHANGELOG.md:3172 +#: ../../../CHANGELOG.md:3824 msgid "To avoid doing it manually, run this:" msgstr "" -#: ../../../CHANGELOG.md:3173 +#: ../../../CHANGELOG.md:3825 msgid "Linux: `sed -i 's/matrix-servers/matrix_servers/g' inventory/hosts`" msgstr "" -#: ../../../CHANGELOG.md:3174 +#: ../../../CHANGELOG.md:3826 msgid "Mac: `sed -i '' 's/matrix-servers/matrix_servers/g' inventory/hosts`" msgstr "" -#: ../../../CHANGELOG.md:3177 +#: ../../../CHANGELOG.md:3829 msgid "2019-05-21" msgstr "" -#: ../../../CHANGELOG.md:3179 +#: ../../../CHANGELOG.md:3831 msgid "Synapse no longer required" msgstr "" -#: ../../../CHANGELOG.md:3181 +#: ../../../CHANGELOG.md:3833 msgid "The playbook no longer insists on installing [Synapse](https://github.com/element-hq/synapse) via the `matrix-synapse` role." msgstr "" -#: ../../../CHANGELOG.md:3183 +#: ../../../CHANGELOG.md:3835 msgid "If you would prefer to install Synapse another way and just use the playbook to install other services, it should be possible (`matrix_synapse_enabled: false`)." msgstr "" -#: ../../../CHANGELOG.md:3185 +#: ../../../CHANGELOG.md:3837 msgid "Note that it won't necessarily be the best experience, since the playbook wires things to Synapse by default. If you're using your own Synapse instance (especially one not running in a container), you may have to override many variables to point them to the correct place." msgstr "" -#: ../../../CHANGELOG.md:3187 +#: ../../../CHANGELOG.md:3839 msgid "Having Synapse not be a required component potentially opens the door for installing alternative Matrix homeservers." msgstr "" -#: ../../../CHANGELOG.md:3189 +#: ../../../CHANGELOG.md:3841 msgid "Bridges are now separate from the Synapse role" msgstr "" -#: ../../../CHANGELOG.md:3191 +#: ../../../CHANGELOG.md:3843 msgid "Bridges are no longer part of the `matrix-synapse` role. Each bridge now lives in its own separate role (`roles/custom/matrix-bridge-*`)." msgstr "" -#: ../../../CHANGELOG.md:3193 +#: ../../../CHANGELOG.md:3845 msgid "These bridge roles are independent of the `matrix-synapse` role, so it should be possible to use them with a Synapse instance installed another way (not through the playbook)." msgstr "" -#: ../../../CHANGELOG.md:3195 +#: ../../../CHANGELOG.md:3847 msgid "Renaming inconsistently-named Synapse variables" msgstr "" -#: ../../../CHANGELOG.md:3197 +#: ../../../CHANGELOG.md:3849 msgid "For better consistency, the following variables have been renamed:" msgstr "" -#: ../../../CHANGELOG.md:3199 +#: ../../../CHANGELOG.md:3851 msgid "`matrix_enable_room_list_search` was renamed to `matrix_synapse_enable_room_list_search`" msgstr "" -#: ../../../CHANGELOG.md:3200 +#: ../../../CHANGELOG.md:3852 msgid "`matrix_alias_creation_rules` was renamed to `matrix_synapse_alias_creation_rules`" msgstr "" -#: ../../../CHANGELOG.md:3201 +#: ../../../CHANGELOG.md:3853 msgid "`matrix_nginx_proxy_matrix_room_list_publication_rulesdata_path` was renamed to `matrix_synapse_room_list_publication_rules`" msgstr "" -#: ../../../CHANGELOG.md:3204 +#: ../../../CHANGELOG.md:3856 msgid "2019-05-09" msgstr "" -#: ../../../CHANGELOG.md:3206 +#: ../../../CHANGELOG.md:3858 msgid "Besides a myriad of bug fixes and minor improvements, here are the more notable (bigger) features we can announce today." msgstr "" -#: ../../../CHANGELOG.md:3208 +#: ../../../CHANGELOG.md:3860 msgid "Mautrix Facebook/Messenger bridging support" msgstr "" -#: ../../../CHANGELOG.md:3210 +#: ../../../CHANGELOG.md:3862 msgid "The playbook now supports bridging with [Facebook](https://www.facebook.com/) by installing the [mautrix-facebook](https://github.com/tulir/mautrix-facebook) bridge. This playbook functionality is available thanks to [@izissise](https://github.com/izissise)." msgstr "" -#: ../../../CHANGELOG.md:3212 +#: ../../../CHANGELOG.md:3864 msgid "Additional details are available in [Setting up Mautrix Facebook bridging](docs/configuring-playbook-bridge-mautrix-facebook.md)." msgstr "" -#: ../../../CHANGELOG.md:3214 +#: ../../../CHANGELOG.md:3866 msgid "mxisd Registration feature integration" msgstr "" -#: ../../../CHANGELOG.md:3216 +#: ../../../CHANGELOG.md:3868 msgid "The playbook can now help you integrate with mxisd's [Registration](https://github.com/kamax-matrix/mxisd/blob/master/docs/features/registration.md) feature." msgstr "" -#: ../../../CHANGELOG.md:3218 +#: ../../../CHANGELOG.md:3870 msgid "Learn more in [mxisd-controlled Registration](docs/configuring-playbook-mxisd.md#mxisd-controlled-registration)." msgstr "" -#: ../../../CHANGELOG.md:3221 +#: ../../../CHANGELOG.md:3873 msgid "2019-04-16" msgstr "" -#: ../../../CHANGELOG.md:3223 +#: ../../../CHANGELOG.md:3875 msgid "Caddy webserver examples" msgstr "" -#: ../../../CHANGELOG.md:3225 +#: ../../../CHANGELOG.md:3877 msgid "If you prefer using the [Caddy](https://caddyserver.com/) webserver instead of our own integrated nginx, we now have examples for it in the [`examples/caddy`](examples/caddy) directory" msgstr "" -#: ../../../CHANGELOG.md:3227 +#: ../../../CHANGELOG.md:3879 msgid "2019-04-10" msgstr "" -#: ../../../CHANGELOG.md:3229 +#: ../../../CHANGELOG.md:3881 msgid "Goofys support for other S3-compatible object stores" msgstr "" -#: ../../../CHANGELOG.md:3231 +#: ../../../CHANGELOG.md:3883 msgid "Until now, you could optionally host Synapse's media repository on Amazon S3, but we now also support [using other S3-compatible object stores](docs/configuring-playbook-s3.md)," msgstr "" -#: ../../../CHANGELOG.md:3234 +#: ../../../CHANGELOG.md:3886 msgid "2019-04-03" msgstr "" -#: ../../../CHANGELOG.md:3236 +#: ../../../CHANGELOG.md:3888 msgid "Ansible >= 2.5 is required" msgstr "" -#: ../../../CHANGELOG.md:3238 +#: ../../../CHANGELOG.md:3890 msgid "Due to recent playbook improvements and the fact that the world keeps turning, we're bumping the [version requirement for Ansible](docs/ansible.md#supported-ansible-versions) (2.4 -> 2.5)." msgstr "" -#: ../../../CHANGELOG.md:3240 +#: ../../../CHANGELOG.md:3892 msgid "We've also started building our own Docker image of Ansible ([devture/ansible](https://hub.docker.com/r/devture/ansible/)), which is useful for people who can't upgrade their local Ansible installation (see [Using Ansible via Docker](docs/ansible.md#using-ansible-via-docker))." msgstr "" -#: ../../../CHANGELOG.md:3243 +#: ../../../CHANGELOG.md:3895 msgid "2019-03-19" msgstr "" -#: ../../../CHANGELOG.md:3245 +#: ../../../CHANGELOG.md:3897 msgid "TLS support for coturn" msgstr "" -#: ../../../CHANGELOG.md:3247 +#: ../../../CHANGELOG.md:3899 msgid "We've added TLS support to the coturn TURN server installed by the playbook by default. The certificates from the Matrix domain will be used for the coturn server." msgstr "" -#: ../../../CHANGELOG.md:3249 +#: ../../../CHANGELOG.md:3901 msgid "This feature is enabled by default for new installations. To make use of TLS support for your existing Matrix server's coturn, make sure to rebuild both coturn and Synapse:" msgstr "" -#: ../../../CHANGELOG.md:3255 +#: ../../../CHANGELOG.md:3907 msgid "People who have an extra firewall (besides the iptables firewall, which Docker manages automatically), will need to open these additional firewall ports: `5349/tcp` (TURN over TCP) and `5349/udp` (TURN over UDP)." msgstr "" -#: ../../../CHANGELOG.md:3257 +#: ../../../CHANGELOG.md:3909 msgid "People who build their own custom playbook from our roles should be aware that:" msgstr "" -#: ../../../CHANGELOG.md:3259 +#: ../../../CHANGELOG.md:3911 msgid "the `matrix-coturn` role and actually starting coturn (e.g. `--tags=start`), requires that certificates are already put in place. For this reason, it's usually a good idea to have the `matrix-coturn` role execute after `matrix-nginx-proxy` (which retrieves the certificates)." msgstr "" -#: ../../../CHANGELOG.md:3261 +#: ../../../CHANGELOG.md:3913 msgid "there are a few variables that can help you enable TLS support for coturn. See the `matrix-coturn` section in [group_vars/matrix-servers](./group_vars/matrix-servers)." msgstr "" -#: ../../../CHANGELOG.md:3264 +#: ../../../CHANGELOG.md:3916 msgid "2019-03-12" msgstr "" -#: ../../../CHANGELOG.md:3266 +#: ../../../CHANGELOG.md:3918 msgid "matrix-nginx-proxy support for serving the base domain" msgstr "" -#: ../../../CHANGELOG.md:3268 +#: ../../../CHANGELOG.md:3920 msgid "If you don't have a dedicated server for your base domain and want to set up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), the playbook has got you covered now." msgstr "" -#: ../../../CHANGELOG.md:3270 +#: ../../../CHANGELOG.md:3922 msgid "It's now possible for the playbook to obtain an SSL certificate and serve the necessary files for Matrix Server Delegation on your base domain. Take a look at the new [Serving the base domain](docs/configuring-playbook-base-domain-serving.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:3272 +#: ../../../CHANGELOG.md:3924 msgid "(BC break) matrix-nginx-proxy data variable renamed" msgstr "" -#: ../../../CHANGELOG.md:3274 +#: ../../../CHANGELOG.md:3926 msgid "`matrix_nginx_proxy_data_path` was renamed to `matrix_nginx_proxy_base_path`." msgstr "" -#: ../../../CHANGELOG.md:3276 +#: ../../../CHANGELOG.md:3928 msgid "There's a new `matrix_nginx_proxy_data_path` variable, which has a different use-purpose now (it's a subdirectory of `matrix_nginx_proxy_base_path` and is meant for storing various data files)." msgstr "" -#: ../../../CHANGELOG.md:3279 +#: ../../../CHANGELOG.md:3931 msgid "2019-03-10" msgstr "" -#: ../../../CHANGELOG.md:3281 +#: ../../../CHANGELOG.md:3933 msgid "Dimension integration manager support" msgstr "" -#: ../../../CHANGELOG.md:3283 +#: ../../../CHANGELOG.md:3935 msgid "Thanks to [NullIsNot0](https://github.com/NullIsNot0), the playbook can now (optionally) install the [Dimension](https://dimension.t2bot.io/) integration manager. To learn more, see the [Setting up Dimension](docs/configuring-playbook-dimension.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:3286 +#: ../../../CHANGELOG.md:3938 msgid "2019-03-07" msgstr "" -#: ../../../CHANGELOG.md:3288 +#: ../../../CHANGELOG.md:3940 msgid "Ability to customize mxisd's email templates" msgstr "" -#: ../../../CHANGELOG.md:3290 +#: ../../../CHANGELOG.md:3942 msgid "Thanks to [Sylvia van Os](https://github.com/TheLastProject), mxisd's email templates can now be customized easily. To learn more, see the [Customizing email templates](docs/configuring-playbook-mxisd.md#customizing-email-templates) documentation page." msgstr "" -#: ../../../CHANGELOG.md:3293 +#: ../../../CHANGELOG.md:3945 msgid "2019-03-05" msgstr "" -#: ../../../CHANGELOG.md:3295 +#: ../../../CHANGELOG.md:3947 msgid "Discord bridging support" msgstr "" -#: ../../../CHANGELOG.md:3297 +#: ../../../CHANGELOG.md:3949 msgid "[@Lionstiger](https://github.com/Lionstiger) has done some great work adding Discord bridging support via [matrix-appservice-discord](https://github.com/matrix-org/matrix-appservice-discord). To learn more, see the [Setting up Appservice Discord bridging](docs/configuring-playbook-bridge-appservice-discord.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:3300 +#: ../../../CHANGELOG.md:3952 msgid "2019-02-19" msgstr "" -#: ../../../CHANGELOG.md:3302 +#: ../../../CHANGELOG.md:3954 msgid "Renaming variables" msgstr "" -#: ../../../CHANGELOG.md:3304 ../../../CHANGELOG.md:3621 -#: ../../../CHANGELOG.md:3706 ../../../CHANGELOG.md:3826 +#: ../../../CHANGELOG.md:3956 ../../../CHANGELOG.md:4273 +#: ../../../CHANGELOG.md:4358 ../../../CHANGELOG.md:4478 msgid "The following playbook variables were renamed:" msgstr "" -#: ../../../CHANGELOG.md:3306 +#: ../../../CHANGELOG.md:3958 msgid "from `host_specific_hostname_identity` to `matrix_domain`" msgstr "" -#: ../../../CHANGELOG.md:3307 +#: ../../../CHANGELOG.md:3959 msgid "from `hostname_identity` to `matrix_domain`" msgstr "" -#: ../../../CHANGELOG.md:3308 +#: ../../../CHANGELOG.md:3960 msgid "from `hostname_matrix` to `matrix_server_fqn_matrix`" msgstr "" -#: ../../../CHANGELOG.md:3309 +#: ../../../CHANGELOG.md:3961 msgid "from `hostname_riot` to `matrix_server_fqn_riot`" msgstr "" -#: ../../../CHANGELOG.md:3310 +#: ../../../CHANGELOG.md:3962 msgid "from `host_specific_matrix_ssl_lets_encrypt_support_email` to `matrix_ssl_lets_encrypt_support_email`" msgstr "" -#: ../../../CHANGELOG.md:3312 +#: ../../../CHANGELOG.md:3964 msgid "Doing that, we've simplified things, made names less confusing (hopefully) and moved all variable names under the `matrix_` prefix." msgstr "" -#: ../../../CHANGELOG.md:3315 +#: ../../../CHANGELOG.md:3967 msgid "2019-02-16" msgstr "" -#: ../../../CHANGELOG.md:3317 +#: ../../../CHANGELOG.md:3969 msgid "Riot v1.0.1 support" msgstr "" -#: ../../../CHANGELOG.md:3319 +#: ../../../CHANGELOG.md:3971 msgid "You can now use the brand new and redesigned Riot." msgstr "" -#: ../../../CHANGELOG.md:3321 +#: ../../../CHANGELOG.md:3973 msgid "The new version no longer has a homepage by default, so we've also removed the custom homepage that we've been installing." msgstr "" -#: ../../../CHANGELOG.md:3323 +#: ../../../CHANGELOG.md:3975 msgid "However, we still provide you with hooks to install your own `home.html` file by specifying the `matrix_riot_web_embedded_pages_home_path` variable (used to be called `matrix_riot_web_homepage_template` before)." msgstr "" -#: ../../../CHANGELOG.md:3326 +#: ../../../CHANGELOG.md:3978 msgid "2019-02-14" msgstr "" -#: ../../../CHANGELOG.md:3328 +#: ../../../CHANGELOG.md:3980 msgid "Synapse v0.99.1" msgstr "" -#: ../../../CHANGELOG.md:3330 +#: ../../../CHANGELOG.md:3982 msgid "As we're moving toward Synapse v1.0, things are beginning to stabilize. Upgrading from v0.99.0 to v0.99.1 should be painless." msgstr "" -#: ../../../CHANGELOG.md:3332 +#: ../../../CHANGELOG.md:3984 msgid "If you've been overriding the default configuration so that you can terminate TLS at the Synapse side (`matrix_synapse_no_tls: false`), you'll now have to replace this custom configuration with `matrix_synapse_tls_federation_listener_enabled: true`. The `matrix_synapse_no_tls` variable is no more." msgstr "" -#: ../../../CHANGELOG.md:3335 +#: ../../../CHANGELOG.md:3987 msgid "2019-02-06" msgstr "" -#: ../../../CHANGELOG.md:3337 +#: ../../../CHANGELOG.md:3989 msgid "Synapse v0.99 support and preparation for Synapse v1.0" msgstr "" -#: ../../../CHANGELOG.md:3339 +#: ../../../CHANGELOG.md:3991 msgid "Matrix is undergoing a lot of changes as it matures towards Synapse v1.0. The first step is the Synapse v0.99 transitional release, which this playbook now supports." msgstr "" -#: ../../../CHANGELOG.md:3341 +#: ../../../CHANGELOG.md:3993 msgid "If you've been using this playbook successfully until now, you'd be aware that we've been doing [Server Delegation](docs/howto-server-delegation.md) using a `_matrix._tcp` DNS SRV record (as per [Configuring DNS](docs/configuring-dns.md))." msgstr "" -#: ../../../CHANGELOG.md:3343 +#: ../../../CHANGELOG.md:3995 msgid "Due to changes related to certificate file requirements that will affect us at Synapse v1.0, we'll have to stop using a **`_matrix._tcp` DNS SRV record in the future** (when Synapse goes to v1.0 — around 5th of March 2019). We **still need to keep the SRV record for now**, for backward compatibility with older Synapse versions (lower than v0.99)." msgstr "" -#: ../../../CHANGELOG.md:3345 +#: ../../../CHANGELOG.md:3997 msgid "**What you need to do now** is make use of this transitional Synapse v0.99 release to **prepare your federation settings for the future**. You have 2 choices to prepare yourself for compatibility with the future Synapse v1.0:" msgstr "" -#: ../../../CHANGELOG.md:3347 -msgid "(recommended) set up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), unless you are affected by the [Downsides of well-known-based Server Delegation](docs/howto-server-delegation.md#downsides-of-well-known-based-server-delegation). If you had previously set up the well-known `client` file, depending on how you've done it, it may be that there is nothing new required of you (besides [upgrading](docs/maintenance-upgrading-services.md)). After upgrading, you can [run a self-check](docs/maintenance-checking-services.md), which will tell you if you need to do anything extra with regard to setting up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file). After some time, when most people have upgraded to Synapse v0.99 and older releases have disappeared, be prepared to drop your `_matrix._tcp` SRV record." +#: ../../../CHANGELOG.md:3999 +msgid "(recommended) set up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), unless you are affected by the [Downsides of well-known-based Server Delegation](docs/howto-server-delegation.md#downsides-of-well-known-based-server-delegation). If you had previously set up the well-known `client` file, depending on how you've done it, it may be that there is nothing new required of you (besides [upgrading](docs/maintenance-upgrading-services.md)). After upgrading, you can [run a self-check](docs/maintenance-and-troubleshooting.md#how-to-check-if-services-work), which will tell you if you need to do anything extra with regard to setting up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file). After some time, when most people have upgraded to Synapse v0.99 and older releases have disappeared, be prepared to drop your `_matrix._tcp` SRV record." msgstr "" -#: ../../../CHANGELOG.md:3349 +#: ../../../CHANGELOG.md:4001 msgid "(more advanced) if the [Downsides of well-known-based Server Delegation](docs/howto-server-delegation.md#downsides-of-well-known-based-server-delegation) are not to your liking, **as an alternative**, you can set up [Server Delegation via a DNS SRV record](docs/howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced). In such a case, you get to keep using your existing `_matrix._tcp` DNS SRV record forever and need to NOT set up a `/.well-known/matrix/server` file. Don't forget that you need to do certificate changes though. Follow the guide at [Server Delegation via a DNS SRV record](docs/howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced)." msgstr "" -#: ../../../CHANGELOG.md:3352 +#: ../../../CHANGELOG.md:4004 msgid "2019-02-01" msgstr "" -#: ../../../CHANGELOG.md:3354 +#: ../../../CHANGELOG.md:4006 msgid "TLS v1.3 support" msgstr "" -#: ../../../CHANGELOG.md:3356 +#: ../../../CHANGELOG.md:4008 msgid "Now that the [nginx Docker image](https://hub.docker.com/_/nginx) has [added support for TLS v1.3](https://github.com/nginxinc/docker-nginx/issues/190), we have enabled that protocol by default." msgstr "" -#: ../../../CHANGELOG.md:3358 +#: ../../../CHANGELOG.md:4010 msgid "When using:" msgstr "" -#: ../../../CHANGELOG.md:3360 +#: ../../../CHANGELOG.md:4012 msgid "the **integrated nginx server**: TLS v1.3 support might not kick in immediately, because the nginx version hasn't been bumped and you may have an older build of the nginx Docker image (currently `nginx:1.15.8-alpine`). Typically, we do not re-pull images that you already have. When the nginx version gets bumped in the future, everyone will get the update. Until then, you could manually force-pull the rebuilt Docker image by running this on the server: `docker pull nginx:1.15.8-alpine`." msgstr "" -#: ../../../CHANGELOG.md:3362 +#: ../../../CHANGELOG.md:4014 msgid "**your own external nginx server**: if your external nginx server is too old, the new configuration we generate for you in `/matrix/nginx-proxy/conf.d/` might not work anymore, because it mentions `TLSv1.3` and your nginx version might not support that. You can adjust the SSL protocol list by overriding the `matrix_nginx_proxy_ssl_protocols` variable. Learn more in the documentation page for [Using your own webserver, instead of this playbook's nginx proxy](docs/configuring-playbook-own-webserver.md)" msgstr "" -#: ../../../CHANGELOG.md:3364 +#: ../../../CHANGELOG.md:4016 msgid "**another web server**: you don't need to do anything to accommodate this change" msgstr "" -#: ../../../CHANGELOG.md:3367 +#: ../../../CHANGELOG.md:4019 msgid "2019-01-31" msgstr "" -#: ../../../CHANGELOG.md:3369 +#: ../../../CHANGELOG.md:4021 msgid "IRC bridging support" msgstr "" -#: ../../../CHANGELOG.md:3371 +#: ../../../CHANGELOG.md:4023 msgid "[Devon Maloney (@Plailect)](https://github.com/Plailect) has done some great work bringing IRC bridging support via [matrix-appservice-irc](https://github.com/TeDomum/matrix-appservice-irc). To learn more, see the [Setting up Appservice IRC bridging](docs/configuring-playbook-bridge-appservice-irc.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:3374 +#: ../../../CHANGELOG.md:4026 msgid "2019-01-29" msgstr "" -#: ../../../CHANGELOG.md:3376 +#: ../../../CHANGELOG.md:4028 msgid "Running container processes as non-root, without capabilities and read-only" msgstr "" -#: ../../../CHANGELOG.md:3378 +#: ../../../CHANGELOG.md:4030 msgid "To improve security, this playbook no longer starts container processes as the `root` user. Most containers were dropping privileges anyway, but we were trusting them with `root` privileges until they would do that. Not anymore — container processes now start as a non-root user (usually `matrix`) from the get-go." msgstr "" -#: ../../../CHANGELOG.md:3380 +#: ../../../CHANGELOG.md:4032 msgid "For additional security, various capabilities are also dropped (see [why it's important](https://github.com/projectatomic/atomic-site/issues/203)) for all containers." msgstr "" -#: ../../../CHANGELOG.md:3382 +#: ../../../CHANGELOG.md:4034 msgid "Additionally, most containers now use a read-only filesystem (see [why it's important](https://www.projectatomic.io/blog/2015/12/making-docker-images-write-only-in-production/)). Containers are given write access only to the directories they need to write to." msgstr "" -#: ../../../CHANGELOG.md:3384 +#: ../../../CHANGELOG.md:4036 msgid "A minor breaking change is the `matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size` variable having being renamed to `matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb` (note the `_mb` suffix). The new variable expects a number value (e.g. `25M` -> `25`). If you weren't customizing this variable, this wouldn't affect you." msgstr "" -#: ../../../CHANGELOG.md:3386 +#: ../../../CHANGELOG.md:4038 msgid "matrix-mailer is now based on Exim, not Postfix" msgstr "" -#: ../../../CHANGELOG.md:3388 +#: ../../../CHANGELOG.md:4040 msgid "While we would have preferred to stay with [Postfix](http://www.postfix.org/), we found out that it cannot run as a non-root user. We've had to replace it with [Exim](https://www.exim.org/) (via the [devture/exim-relay](https://hub.docker.com/r/devture/exim-relay) container image)." msgstr "" -#: ../../../CHANGELOG.md:3390 +#: ../../../CHANGELOG.md:4042 msgid "The internal `matrix-mailer` service (running in a container) now listens on port `8025` (used to be `587` before). The playbook will update your Synapse and mxisd email settings to match (`matrix-mailer:587` -> `matrix-mailer:8025`)." msgstr "" -#: ../../../CHANGELOG.md:3392 +#: ../../../CHANGELOG.md:4044 msgid "Using the [devture/exim-relay](https://hub.docker.com/r/devture/exim-relay) container image instead of [panubo/postfix](https://hub.docker.com/r/panubo/postfix/) also gives us a nice disk usage reduction (~200MB -> 8MB)." msgstr "" -#: ../../../CHANGELOG.md:3395 +#: ../../../CHANGELOG.md:4047 msgid "2019-01-17" msgstr "" -#: ../../../CHANGELOG.md:3397 +#: ../../../CHANGELOG.md:4049 msgid "(BC Break) Making the playbook's roles more independent of one another" msgstr "" -#: ../../../CHANGELOG.md:3399 +#: ../../../CHANGELOG.md:4051 msgid "The following change **affects people running a more non-standard setup** — external Postgres or using our roles in their own other playbook. **Most users don't need to do anything**, besides becoming aware of the new glue variables file [`group_vars/matrix-servers`](group_vars/matrix-servers)." msgstr "" -#: ../../../CHANGELOG.md:3402 +#: ../../../CHANGELOG.md:4054 msgid "Because people like using the playbook's components independently (outside of this playbook) and because it's much better for maintainability, we've continued working on separating them. Still, we'd like to offer a turnkey solution for running a fully-featured Matrix server, so this playbook remains important for wiring up the various components." msgstr "" -#: ../../../CHANGELOG.md:3404 +#: ../../../CHANGELOG.md:4056 msgid "With the new changes, **all roles are now only dependent on the minimal `matrix-base` role**. They are no longer dependent among themselves." msgstr "" -#: ../../../CHANGELOG.md:3406 +#: ../../../CHANGELOG.md:4058 msgid "In addition, the following components can now be completely disabled (for those who want/need to):" msgstr "" -#: ../../../CHANGELOG.md:3407 -msgid "`matrix-coturn` by using `matrix_coturn_enabled: false`" +#: ../../../CHANGELOG.md:4059 +msgid "`matrix-coturn` by using `coturn_enabled: false`" msgstr "" -#: ../../../CHANGELOG.md:3408 +#: ../../../CHANGELOG.md:4060 msgid "`matrix-mailer` by using `matrix_mailer_enabled: false`" msgstr "" -#: ../../../CHANGELOG.md:3409 +#: ../../../CHANGELOG.md:4061 msgid "`matrix-postgres` by using `matrix_postgres_enabled: false`" msgstr "" -#: ../../../CHANGELOG.md:3411 +#: ../../../CHANGELOG.md:4063 msgid "The following changes had to be done:" msgstr "" -#: ../../../CHANGELOG.md:3413 +#: ../../../CHANGELOG.md:4065 msgid "glue variables had to be introduced to the playbook, so it can wire together the various components. Those glue vars are stored in the [`group_vars/matrix-servers`](group_vars/matrix-servers) file. When overriding variables for a given component (role), you need to be aware of both the role defaults (`role/ROLE/defaults/main.yml`) and the role's corresponding section in the [`group_vars/matrix-servers`](group_vars/matrix-servers) file." msgstr "" -#: ../../../CHANGELOG.md:3415 -msgid "`matrix_postgres_use_external` has been superceeded by the more consistently named `matrix_postgres_enabled` variable and a few other `matrix_synapse_database_` variables. See the [Using an external PostgreSQL server (optional)](docs/configuring-playbook-external-postgres.md) documentation page for an up-to-date replacement." +#: ../../../CHANGELOG.md:4067 +msgid "`matrix_postgres_use_external` has been superseded by the more consistently named `matrix_postgres_enabled` variable and a few other `matrix_synapse_database_` variables. See the [Using an external PostgreSQL server (optional)](docs/configuring-playbook-external-postgres.md) documentation page for an up-to-date replacement." msgstr "" -#: ../../../CHANGELOG.md:3417 +#: ../../../CHANGELOG.md:4069 msgid "Postgres tools (`matrix-postgres-cli` and `matrix-make-user-admin`) are no longer installed if you're not enabling the `matrix-postgres` role (`matrix_postgres_enabled: false`)" msgstr "" -#: ../../../CHANGELOG.md:3419 +#: ../../../CHANGELOG.md:4071 msgid "roles, being more independent now, are more minimal and do not do so much magic for you. People that are building their own playbook using our roles will definitely need to take a look at the [`group_vars/matrix-servers`](group_vars/matrix-servers) file and adapt their playbooks with the same (or similar) wiring logic." msgstr "" -#: ../../../CHANGELOG.md:3422 +#: ../../../CHANGELOG.md:4074 msgid "2019-01-16" msgstr "" -#: ../../../CHANGELOG.md:3424 +#: ../../../CHANGELOG.md:4076 msgid "Splitting the playbook into multiple roles" msgstr "" -#: ../../../CHANGELOG.md:3426 +#: ../../../CHANGELOG.md:4078 msgid "For better maintainability, the playbook logic (which all used to reside in a single `matrix-server` role) has been split out into a number of different roles: `matrix-synapse`, `matrix-postgres`, `matrix-riot-web`, `matrix-mxisd`, etc. (see the `roles/` directory)." msgstr "" -#: ../../../CHANGELOG.md:3429 +#: ../../../CHANGELOG.md:4081 msgid "To keep the filesystem more consistent with this separation, the **Postgres data had to be relocated**." msgstr "" -#: ../../../CHANGELOG.md:3431 +#: ../../../CHANGELOG.md:4083 msgid "The default value of `matrix_postgres_data_path` was changed from `/matrix/postgres` to `/matrix/postgres/data`. The `/matrix/postgres` directory is what we consider a base path now (new variable `matrix_postgres_base_path`). **Your Postgres data files will automatically be relocated by the playbook** (`/matrix/postgres/*` -> `/matrix/postgres/data/`) when you run with `--tags=setup-all` (or `--tags=setup-postgres`). While this shouldn't cause data-loss, **it's better if you do a Postgres backup just in case**. You'd need to restart all services after this migration (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3434 +#: ../../../CHANGELOG.md:4086 msgid "2019-01-11" msgstr "" -#: ../../../CHANGELOG.md:3436 +#: ../../../CHANGELOG.md:4088 msgid "(BC Break) mxisd configuration changes" msgstr "" -#: ../../../CHANGELOG.md:3438 +#: ../../../CHANGELOG.md:4090 msgid "To be more flexible and to support the upcoming [mxisd](https://github.com/kamax-io/mxisd) 1.3.0 (when it gets released), we've had to redo how mxisd gets configured." msgstr "" -#: ../../../CHANGELOG.md:3441 +#: ../../../CHANGELOG.md:4093 msgid "The following variables are no longer supported by this playbook:" msgstr "" -#: ../../../CHANGELOG.md:3443 +#: ../../../CHANGELOG.md:4095 msgid "`matrix_mxisd_ldap_enabled`" msgstr "" -#: ../../../CHANGELOG.md:3444 +#: ../../../CHANGELOG.md:4096 msgid "`matrix_mxisd_ldap_connection_host`" msgstr "" -#: ../../../CHANGELOG.md:3445 +#: ../../../CHANGELOG.md:4097 msgid "`matrix_mxisd_ldap_connection_tls`" msgstr "" -#: ../../../CHANGELOG.md:3446 +#: ../../../CHANGELOG.md:4098 msgid "`matrix_mxisd_ldap_connection_port`" msgstr "" -#: ../../../CHANGELOG.md:3447 +#: ../../../CHANGELOG.md:4099 msgid "`matrix_mxisd_ldap_connection_baseDn`" msgstr "" -#: ../../../CHANGELOG.md:3448 +#: ../../../CHANGELOG.md:4100 msgid "`matrix_mxisd_ldap_connection_baseDns`" msgstr "" -#: ../../../CHANGELOG.md:3449 ../../../CHANGELOG.md:3450 +#: ../../../CHANGELOG.md:4101 ../../../CHANGELOG.md:4102 msgid "`matrix_mxisd_ldap_connection_bindDn`" msgstr "" -#: ../../../CHANGELOG.md:3451 ../../../CHANGELOG.md:3455 +#: ../../../CHANGELOG.md:4103 ../../../CHANGELOG.md:4107 msgid "`matrix_mxisd_ldap_connection_bindPassword`" msgstr "" -#: ../../../CHANGELOG.md:3452 +#: ../../../CHANGELOG.md:4104 msgid "`matrix_mxisd_ldap_filter`" msgstr "" -#: ../../../CHANGELOG.md:3453 +#: ../../../CHANGELOG.md:4105 msgid "`matrix_mxisd_ldap_attribute_uid_type`" msgstr "" -#: ../../../CHANGELOG.md:3454 +#: ../../../CHANGELOG.md:4106 msgid "`matrix_mxisd_ldap_attribute_uid_value`" msgstr "" -#: ../../../CHANGELOG.md:3456 +#: ../../../CHANGELOG.md:4108 msgid "`matrix_mxisd_ldap_attribute_name`" msgstr "" -#: ../../../CHANGELOG.md:3457 +#: ../../../CHANGELOG.md:4109 msgid "`matrix_mxisd_ldap_attribute_threepid_email`" msgstr "" -#: ../../../CHANGELOG.md:3458 +#: ../../../CHANGELOG.md:4110 msgid "`matrix_mxisd_ldap_attribute_threepid_msisdn`" msgstr "" -#: ../../../CHANGELOG.md:3459 +#: ../../../CHANGELOG.md:4111 msgid "`matrix_mxisd_ldap_identity_filter`" msgstr "" -#: ../../../CHANGELOG.md:3460 +#: ../../../CHANGELOG.md:4112 msgid "`matrix_mxisd_ldap_identity_medium`" msgstr "" -#: ../../../CHANGELOG.md:3461 +#: ../../../CHANGELOG.md:4113 msgid "`matrix_mxisd_ldap_auth_filter`" msgstr "" -#: ../../../CHANGELOG.md:3462 +#: ../../../CHANGELOG.md:4114 msgid "`matrix_mxisd_ldap_directory_filter`" msgstr "" -#: ../../../CHANGELOG.md:3463 +#: ../../../CHANGELOG.md:4115 msgid "`matrix_mxisd_template_config`" msgstr "" -#: ../../../CHANGELOG.md:3465 +#: ../../../CHANGELOG.md:4117 msgid "You are encouraged to use the `matrix_mxisd_configuration_extension_yaml` variable to define your own mxisd configuration additions and overrides. Refer to the [default variables file](roles/custom/matrix-mxisd/defaults/main.yml) for more information." msgstr "" -#: ../../../CHANGELOG.md:3467 +#: ../../../CHANGELOG.md:4119 msgid "This new way of configuring mxisd is beneficial because:" msgstr "" -#: ../../../CHANGELOG.md:3469 +#: ../../../CHANGELOG.md:4121 msgid "it lets us support all mxisd configuration options, as the playbook simply forwards them to mxisd without needing to care or understand them" msgstr "" -#: ../../../CHANGELOG.md:3470 +#: ../../../CHANGELOG.md:4122 msgid "it lets you upgrade to newer mxisd versions and make use of their features, without us having to add support for them explicitly" msgstr "" -#: ../../../CHANGELOG.md:3473 +#: ../../../CHANGELOG.md:4125 msgid "2019-01-08" msgstr "" -#: ../../../CHANGELOG.md:3475 +#: ../../../CHANGELOG.md:4127 msgid "(BC Break) Cronjob schedule no longer configurable" msgstr "" -#: ../../../CHANGELOG.md:3477 +#: ../../../CHANGELOG.md:4129 msgid "Due to the way we manage cronjobs now, you can no longer configure the schedule they're invoked at." msgstr "" -#: ../../../CHANGELOG.md:3479 +#: ../../../CHANGELOG.md:4131 msgid "If you were previously using `matrix_ssl_lets_encrypt_renew_cron_time_definition` or `matrix_nginx_proxy_reload_cron_time_definition` to set a custom schedule, you should note that these variables don't affect anything anymore." msgstr "" -#: ../../../CHANGELOG.md:3482 +#: ../../../CHANGELOG.md:4134 msgid "If you miss this functionality, please [open an Issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/new) and let us know about your use case!" msgstr "" -#: ../../../CHANGELOG.md:3485 +#: ../../../CHANGELOG.md:4137 msgid "2018-12-23" msgstr "" -#: ../../../CHANGELOG.md:3487 +#: ../../../CHANGELOG.md:4139 msgid "(BC Break) More SSL certificate retrieval methods" msgstr "" -#: ../../../CHANGELOG.md:3489 +#: ../../../CHANGELOG.md:4141 msgid "The playbook now lets you decide between 3 different SSL certificate retrieval methods:" msgstr "" -#: ../../../CHANGELOG.md:3490 +#: ../../../CHANGELOG.md:4142 msgid "(default) obtaining free SSL certificates from Let's Encrypt" msgstr "" -#: ../../../CHANGELOG.md:3491 +#: ../../../CHANGELOG.md:4143 msgid "generating self-signed SSL certificates" msgstr "" -#: ../../../CHANGELOG.md:3492 +#: ../../../CHANGELOG.md:4144 msgid "managing SSL certificates manually" msgstr "" -#: ../../../CHANGELOG.md:3494 +#: ../../../CHANGELOG.md:4146 msgid "Learn more in [Adjusting SSL certificate retrieval](docs/configuring-playbook-ssl-certificates.md)." msgstr "" -#: ../../../CHANGELOG.md:3496 +#: ../../../CHANGELOG.md:4148 msgid "For people who use Let's Encrypt (mostly everyone, since it's the default), you'll also have to rename a variable in your configuration:" msgstr "" -#: ../../../CHANGELOG.md:3498 +#: ../../../CHANGELOG.md:4150 msgid "before: `host_specific_matrix_ssl_support_email`" msgstr "" -#: ../../../CHANGELOG.md:3499 +#: ../../../CHANGELOG.md:4151 msgid "after: `host_specific_matrix_ssl_lets_encrypt_support_email`" msgstr "" -#: ../../../CHANGELOG.md:3501 +#: ../../../CHANGELOG.md:4153 msgid "(BC Break) mxisd upgrade with multiple base DN support" msgstr "" -#: ../../../CHANGELOG.md:3503 +#: ../../../CHANGELOG.md:4155 msgid "mxisd has bee upgraded to [version 1.2.2](https://github.com/kamax-matrix/mxisd/releases/tag/v1.2.2), which supports [multiple base DNs](https://github.com/kamax-matrix/mxisd/blob/v1.2.2/docs/stores/ldap.md#base)." msgstr "" -#: ../../../CHANGELOG.md:3505 +#: ../../../CHANGELOG.md:4157 msgid "If you were configuring this playbook's `matrix_mxisd_ldap_connection_baseDn` variable until now (a string containing a single base DN), you'll need to change to configuring the `matrix_mxisd_ldap_connection_baseDns` variable (an array containing multiple base DNs)." msgstr "" -#: ../../../CHANGELOG.md:3507 +#: ../../../CHANGELOG.md:4159 msgid "Example change:" msgstr "" -#: ../../../CHANGELOG.md:3509 +#: ../../../CHANGELOG.md:4161 msgid "before: `matrix_mxisd_ldap_connection_baseDn: OU=Users,DC=example,DC=org`" msgstr "" -#: ../../../CHANGELOG.md:3510 +#: ../../../CHANGELOG.md:4162 msgid "after: `matrix_mxisd_ldap_connection_baseDns: ['OU=Users,DC=example,DC=org']`" msgstr "" -#: ../../../CHANGELOG.md:3513 +#: ../../../CHANGELOG.md:4165 msgid "2018-12-21" msgstr "" -#: ../../../CHANGELOG.md:3515 +#: ../../../CHANGELOG.md:4167 msgid "Synapse 0.34.0 and Python 3" msgstr "" -#: ../../../CHANGELOG.md:3517 +#: ../../../CHANGELOG.md:4169 msgid "Synapse has been upgraded to 0.34.0 and now uses Python 3. Based on feedback from others, running Synapse on Python 3 is supposed to decrease memory usage significantly (~2x)." msgstr "" -#: ../../../CHANGELOG.md:3520 +#: ../../../CHANGELOG.md:4172 msgid "2018-12-12" msgstr "" -#: ../../../CHANGELOG.md:3522 +#: ../../../CHANGELOG.md:4174 msgid "Riot homepage customization" msgstr "" -#: ../../../CHANGELOG.md:3524 +#: ../../../CHANGELOG.md:4176 msgid "You can now customize some parts of the Riot homepage (or even completely replace it with your own custom page). See the `matrix_riot_web_homepage_` variables in `roles/custom/matrix-riot-web/defaults/main.yml`." msgstr "" -#: ../../../CHANGELOG.md:3527 +#: ../../../CHANGELOG.md:4179 msgid "2018-12-04" msgstr "" -#: ../../../CHANGELOG.md:3529 +#: ../../../CHANGELOG.md:4181 msgid "mxisd extensibility" msgstr "" -#: ../../../CHANGELOG.md:3531 +#: ../../../CHANGELOG.md:4183 msgid "The [LDAP identity store for mxisd](https://github.com/kamax-matrix/mxisd/blob/master/docs/stores/ldap.md) can now be configured easily using playbook variables (see the `matrix_mxisd_ldap_` variables in `roles/custom/matrix-server/defaults/main.yml`)." msgstr "" -#: ../../../CHANGELOG.md:3534 +#: ../../../CHANGELOG.md:4186 msgid "2018-11-28" msgstr "" -#: ../../../CHANGELOG.md:3536 +#: ../../../CHANGELOG.md:4188 msgid "More scripts" msgstr "" -#: ../../../CHANGELOG.md:3538 +#: ../../../CHANGELOG.md:4190 msgid "matrix-remove-all allows to uninstall everything with a single command" msgstr "" -#: ../../../CHANGELOG.md:3539 +#: ../../../CHANGELOG.md:4191 msgid "matrix-make-user-admin allows to upgrade a user's privileges" msgstr "" -#: ../../../CHANGELOG.md:3541 +#: ../../../CHANGELOG.md:4193 msgid "LDAP auth support via matrix-synapse-ldap3" msgstr "" -#: ../../../CHANGELOG.md:3543 +#: ../../../CHANGELOG.md:4195 msgid "The playbook can now install and configure [LDAP auth support](https://github.com/matrix-org/matrix-synapse-ldap3) for you." msgstr "" -#: ../../../CHANGELOG.md:3545 +#: ../../../CHANGELOG.md:4197 msgid "Additional details are available in [Setting up the LDAP authentication password provider module](docs/configuring-playbook-ldap-auth.md)." msgstr "" -#: ../../../CHANGELOG.md:3548 +#: ../../../CHANGELOG.md:4200 msgid "2018-11-23" msgstr "" -#: ../../../CHANGELOG.md:3550 +#: ../../../CHANGELOG.md:4202 msgid "Support for controlling public registration and room auto-join" msgstr "" -#: ../../../CHANGELOG.md:3552 +#: ../../../CHANGELOG.md:4204 msgid "The playbook now lets you enable public registration for users (controlled via `matrix_synapse_enable_registration`). By default, public registration is forbidden." msgstr "" -#: ../../../CHANGELOG.md:3554 +#: ../../../CHANGELOG.md:4206 msgid "You can also make people automatically get auto-joined to rooms (controlled via `matrix_synapse_auto_join_rooms`)." msgstr "" -#: ../../../CHANGELOG.md:3556 +#: ../../../CHANGELOG.md:4208 msgid "Support for changing the welcome user ID (welcome bot)" msgstr "" -#: ../../../CHANGELOG.md:3558 +#: ../../../CHANGELOG.md:4210 msgid "By default, `@riot-bot:matrix.org` is used to welcome newly registered users. This can be changed to something else (or disabled) via the new `matrix_riot_web_welcome_user_id` variable." msgstr "" -#: ../../../CHANGELOG.md:3561 +#: ../../../CHANGELOG.md:4213 msgid "2018-11-14" msgstr "" -#: ../../../CHANGELOG.md:3563 +#: ../../../CHANGELOG.md:4215 msgid "Ability to set Synapse log levels" msgstr "" -#: ../../../CHANGELOG.md:3565 +#: ../../../CHANGELOG.md:4217 msgid "The playbook now allows you to set the log levels used by Synapse. The default logging levels remain the same." msgstr "" -#: ../../../CHANGELOG.md:3567 +#: ../../../CHANGELOG.md:4219 msgid "You can now override following variables with any of the supported log levels listed here: https://docs.python.org/3/library/logging.html#logging-levels" msgstr "" -#: ../../../CHANGELOG.md:3576 +#: ../../../CHANGELOG.md:4228 msgid "2018-11-03" msgstr "" -#: ../../../CHANGELOG.md:3578 +#: ../../../CHANGELOG.md:4230 msgid "Customize parts of Riot's config" msgstr "" -#: ../../../CHANGELOG.md:3580 +#: ../../../CHANGELOG.md:4232 msgid "You can now customize some parts of Riot's `config.json`. These playbook variables, with these default values, have been added:" msgstr "" -#: ../../../CHANGELOG.md:3591 +#: ../../../CHANGELOG.md:4243 msgid "This now allows you use a custom integration manager like [Dimension](https://dimension.t2bot.io). For example, if you wish to use the Dimension instance hosted at dimension.t2bot.io, you can set the following in your vars.yml file:" msgstr "" -#: ../../../CHANGELOG.md:3600 +#: ../../../CHANGELOG.md:4252 msgid "SSL protocols used to serve Riot and Synapse" msgstr "" -#: ../../../CHANGELOG.md:3602 +#: ../../../CHANGELOG.md:4254 msgid "There's now a new `matrix_nginx_proxy_ssl_protocols` playbook variable, which controls the SSL protocols used to serve Riot and Synapse. Its default value is `TLSv1.1 TLSv1.2`. This playbook previously used `TLSv1 TLSv1.1 TLSv1.2` to serve Riot and Synapse." msgstr "" -#: ../../../CHANGELOG.md:3604 -msgid "You may wish to reenable TLSv1 if you need to access Riot in older browsers." +#: ../../../CHANGELOG.md:4256 +msgid "You may wish to re-enable TLSv1 if you need to access Riot in older browsers." msgstr "" -#: ../../../CHANGELOG.md:3606 +#: ../../../CHANGELOG.md:4258 msgid "Note: Currently the dockerized nginx doesn't support TLSv1.3. See https://github.com/nginxinc/docker-nginx/issues/190 for more details." msgstr "" -#: ../../../CHANGELOG.md:3609 +#: ../../../CHANGELOG.md:4261 msgid "2018-11-01" msgstr "" -#: ../../../CHANGELOG.md:3611 +#: ../../../CHANGELOG.md:4263 msgid "Postgres 11 support" msgstr "" -#: ../../../CHANGELOG.md:3613 +#: ../../../CHANGELOG.md:4265 msgid "The playbook now installs [Postgres 11](https://www.postgresql.org/about/news/1894/) by default." msgstr "" -#: ../../../CHANGELOG.md:3615 +#: ../../../CHANGELOG.md:4267 msgid "If you have have an existing setup, it's likely running on an older Postgres version (9.x or 10.x). You can easily upgrade by following the [upgrading PostgreSQL guide](docs/maintenance-postgres.md#upgrading-postgresql)." msgstr "" -#: ../../../CHANGELOG.md:3617 ../../../CHANGELOG.md:3704 -#: ../../../CHANGELOG.md:3824 +#: ../../../CHANGELOG.md:4269 ../../../CHANGELOG.md:4356 +#: ../../../CHANGELOG.md:4476 msgid "(BC Break) Renaming playbook variables" msgstr "" -#: ../../../CHANGELOG.md:3619 +#: ../../../CHANGELOG.md:4271 msgid "Due to the large amount of features added to this playbook lately, to keep things manageable we've had to reorganize its configuration variables a bit." msgstr "" -#: ../../../CHANGELOG.md:3623 +#: ../../../CHANGELOG.md:4275 msgid "from `matrix_docker_image_mxisd` to `matrix_mxisd_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:3624 +#: ../../../CHANGELOG.md:4276 msgid "from `matrix_docker_image_mautrix_telegram` to `matrix_mautrix_telegram_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:3625 +#: ../../../CHANGELOG.md:4277 msgid "from `matrix_docker_image_mautrix_whatsapp` to `matrix_mautrix_whatsapp_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:3626 +#: ../../../CHANGELOG.md:4278 msgid "from `matrix_docker_image_mailer` to `matrix_mailer_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:3627 -msgid "from `matrix_docker_image_coturn` to `matrix_coturn_docker_image`" +#: ../../../CHANGELOG.md:4279 +msgid "from `matrix_docker_image_coturn` to `coturn_container_image`" msgstr "" -#: ../../../CHANGELOG.md:3628 +#: ../../../CHANGELOG.md:4280 msgid "from `matrix_docker_image_goofys` to `matrix_s3_goofys_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:3629 +#: ../../../CHANGELOG.md:4281 msgid "from `matrix_docker_image_riot` to `matrix_riot_web_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:3630 +#: ../../../CHANGELOG.md:4282 msgid "from `matrix_docker_image_nginx` to `matrix_nginx_proxy_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:3631 +#: ../../../CHANGELOG.md:4283 msgid "from `matrix_docker_image_synapse` to `matrix_synapse_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:3632 +#: ../../../CHANGELOG.md:4284 msgid "from `matrix_docker_image_postgres_v9` to `matrix_postgres_docker_image_v9`" msgstr "" -#: ../../../CHANGELOG.md:3633 +#: ../../../CHANGELOG.md:4285 msgid "from `matrix_docker_image_postgres_v10` to `matrix_postgres_docker_image_v10`" msgstr "" -#: ../../../CHANGELOG.md:3634 +#: ../../../CHANGELOG.md:4286 msgid "from `matrix_docker_image_postgres_latest` to `matrix_postgres_docker_image_latest`" msgstr "" -#: ../../../CHANGELOG.md:3637 +#: ../../../CHANGELOG.md:4289 msgid "2018-10-26" msgstr "" -#: ../../../CHANGELOG.md:3639 +#: ../../../CHANGELOG.md:4291 msgid "Mautrix Whatsapp bridging support" msgstr "" -#: ../../../CHANGELOG.md:3641 +#: ../../../CHANGELOG.md:4293 msgid "The playbook now supports bridging with [Whatsapp](https://www.whatsapp.com/) by installing the [mautrix-whatsapp](https://github.com/tulir/mautrix-whatsapp) bridge. This playbook functionality is available thanks to [@izissise](https://github.com/izissise)." msgstr "" -#: ../../../CHANGELOG.md:3643 +#: ../../../CHANGELOG.md:4295 msgid "Additional details are available in [Setting up Mautrix Whatsapp bridging](docs/configuring-playbook-bridge-mautrix-whatsapp.md)." msgstr "" -#: ../../../CHANGELOG.md:3646 +#: ../../../CHANGELOG.md:4298 msgid "2018-10-25" msgstr "" -#: ../../../CHANGELOG.md:3648 +#: ../../../CHANGELOG.md:4300 msgid "Support for controlling Matrix federation" msgstr "" -#: ../../../CHANGELOG.md:3650 +#: ../../../CHANGELOG.md:4302 msgid "The playbook can now help you with [Controlling Matrix federation](docs/configuring-playbook-federation), should you wish to run a more private (isolated) server." msgstr "" -#: ../../../CHANGELOG.md:3653 +#: ../../../CHANGELOG.md:4305 msgid "2018-10-24" msgstr "" -#: ../../../CHANGELOG.md:3655 +#: ../../../CHANGELOG.md:4307 msgid "Disabling riot-web guests" msgstr "" -#: ../../../CHANGELOG.md:3657 +#: ../../../CHANGELOG.md:4309 msgid "From now on, Riot's configuration setting `disable_guests` would be set to `true`. The homeserver was rejecting guests anyway, so this is just a cosmetic change affecting Riot's UI." msgstr "" -#: ../../../CHANGELOG.md:3660 +#: ../../../CHANGELOG.md:4312 msgid "2018-10-21" msgstr "" -#: ../../../CHANGELOG.md:3662 +#: ../../../CHANGELOG.md:4314 msgid "Self-check maintenance command" msgstr "" -#: ../../../CHANGELOG.md:3664 -msgid "The playbook can now [check if services are configured correctly](docs/maintenance-checking-services.md)." +#: ../../../CHANGELOG.md:4316 +msgid "The playbook can now [check if services are configured correctly](docs/maintenance-and-troubleshooting.md#how-to-check-if-services-work)." msgstr "" -#: ../../../CHANGELOG.md:3667 +#: ../../../CHANGELOG.md:4319 msgid "2018-10-05" msgstr "" -#: ../../../CHANGELOG.md:3669 +#: ../../../CHANGELOG.md:4321 msgid "Presence tracking made configurable" msgstr "" -#: ../../../CHANGELOG.md:3671 +#: ../../../CHANGELOG.md:4323 msgid "The playbook can now enable/disable user presence-status tracking in Synapse, through the playbook's `matrix_synapse_use_presence` variable (having a default value of `true` — enabled)." msgstr "" -#: ../../../CHANGELOG.md:3673 +#: ../../../CHANGELOG.md:4325 msgid "If users participate in large rooms with many other servers, disabling presence will decrease server load significantly." msgstr "" -#: ../../../CHANGELOG.md:3676 +#: ../../../CHANGELOG.md:4328 msgid "2018-09-27" msgstr "" -#: ../../../CHANGELOG.md:3678 +#: ../../../CHANGELOG.md:4330 msgid "Synapse Cache Factor made configurable" msgstr "" -#: ../../../CHANGELOG.md:3680 +#: ../../../CHANGELOG.md:4332 msgid "The playbook now makes the Synapse cache factor configurable, through the playbook's `matrix_synapse_cache_factor` variable (having a default value of `0.5`)." msgstr "" -#: ../../../CHANGELOG.md:3682 +#: ../../../CHANGELOG.md:4334 msgid "Changing that value allows you to potentially decrease RAM usage or to increase performance by caching more stuff. Some information on it is available here: https://github.com/element-hq/synapse#help-synapse-eats-all-my-ram" msgstr "" -#: ../../../CHANGELOG.md:3685 +#: ../../../CHANGELOG.md:4337 msgid "2018-09-26" msgstr "" -#: ../../../CHANGELOG.md:3687 +#: ../../../CHANGELOG.md:4339 msgid "Disabling Docker container logging" msgstr "" -#: ../../../CHANGELOG.md:3689 +#: ../../../CHANGELOG.md:4341 msgid "`--log-driver=none` is used for all Docker containers now." msgstr "" -#: ../../../CHANGELOG.md:3691 +#: ../../../CHANGELOG.md:4343 msgid "All these containers are started through systemd anyway and get logged in journald, so there's no need for Docker to be logging the same thing using the default `json-file` driver. Doing that was growing `/var/lib/docker/containers/…` infinitely until service/container restart." msgstr "" -#: ../../../CHANGELOG.md:3693 +#: ../../../CHANGELOG.md:4345 msgid "As a result of this, things like `docker logs matrix-synapse` won't work anymore. `journalctl -u matrix-synapse` is how one can see the logs." msgstr "" -#: ../../../CHANGELOG.md:3696 +#: ../../../CHANGELOG.md:4348 msgid "2018-09-17" msgstr "" -#: ../../../CHANGELOG.md:3698 +#: ../../../CHANGELOG.md:4350 msgid "Service discovery support" msgstr "" -#: ../../../CHANGELOG.md:3700 +#: ../../../CHANGELOG.md:4352 msgid "The playbook now helps you set up [service discovery](https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery) using a `/.well-known/matrix/client` file." msgstr "" -#: ../../../CHANGELOG.md:3702 +#: ../../../CHANGELOG.md:4354 msgid "Additional details are available in [Configuring service discovery via .well-known](docs/configuring-well-known.md)." msgstr "" -#: ../../../CHANGELOG.md:3708 +#: ../../../CHANGELOG.md:4360 msgid "from `matrix_nginx_riot_web_data_path` to `matrix_riot_web_data_path`" msgstr "" -#: ../../../CHANGELOG.md:3709 +#: ../../../CHANGELOG.md:4361 msgid "from `matrix_riot_web_default_identity_server_url` to `matrix_identity_server_url`" msgstr "" -#: ../../../CHANGELOG.md:3712 +#: ../../../CHANGELOG.md:4364 msgid "2018-09-07" msgstr "" -#: ../../../CHANGELOG.md:3714 +#: ../../../CHANGELOG.md:4366 msgid "Mautrix Telegram bridging support" msgstr "" -#: ../../../CHANGELOG.md:3716 +#: ../../../CHANGELOG.md:4368 msgid "The playbook now supports bridging with [Telegram](https://telegram.org/) by installing the [mautrix-telegram](https://github.com/tulir/mautrix-telegram) bridge. This playbook functionality is available thanks to [@izissise](https://github.com/izissise)." msgstr "" -#: ../../../CHANGELOG.md:3718 +#: ../../../CHANGELOG.md:4370 msgid "Additional details are available in [Setting up Mautrix Telegram bridging](docs/configuring-playbook-bridge-mautrix-telegram.md)." msgstr "" -#: ../../../CHANGELOG.md:3720 +#: ../../../CHANGELOG.md:4372 msgid "Events cache size increase and configurability for Matrix Synapse" msgstr "" -#: ../../../CHANGELOG.md:3722 +#: ../../../CHANGELOG.md:4374 msgid "The playbook now lets you configure Matrix Synapse's `event_cache_size` configuration via the `matrix_synapse_event_cache_size` playbook variable." msgstr "" -#: ../../../CHANGELOG.md:3724 +#: ../../../CHANGELOG.md:4376 msgid "Previously, this value was hardcoded to `\"10K\"`. From now on, a more reasonable default of `\"100K\"` is used." msgstr "" -#: ../../../CHANGELOG.md:3726 +#: ../../../CHANGELOG.md:4378 msgid "Password-peppering support for Matrix Synapse" msgstr "" -#: ../../../CHANGELOG.md:3728 +#: ../../../CHANGELOG.md:4380 msgid "The playbook now supports enabling password-peppering for increased security in Matrix Synapse via the `matrix_synapse_password_config_pepper` playbook variable. Using a password pepper is disabled by default (just like it used to be before this playbook variable got introduced) and is not to be enabled/disabled after initial setup, as that would invalidate all existing passwords." msgstr "" -#: ../../../CHANGELOG.md:3730 +#: ../../../CHANGELOG.md:4382 msgid "Statistics-reporting support for Matrix Synapse" msgstr "" -#: ../../../CHANGELOG.md:3732 +#: ../../../CHANGELOG.md:4384 msgid "There's now a new `matrix_synapse_report_stats` playbook variable, which controls the `report_stats` configuration option for Matrix Synapse. It defaults to `false`, so no change is required to retain your privacy." msgstr "" -#: ../../../CHANGELOG.md:3734 +#: ../../../CHANGELOG.md:4386 msgid "If you'd like to start reporting statistics about your homeserver (things like number of users, number of messages sent, uptime, load, etc.) to matrix.org, you can turn on stats reporting." msgstr "" -#: ../../../CHANGELOG.md:3737 +#: ../../../CHANGELOG.md:4389 msgid "2018-08-29" msgstr "" -#: ../../../CHANGELOG.md:3739 +#: ../../../CHANGELOG.md:4391 msgid "Changing the way SSL certificates are retrieved" msgstr "" -#: ../../../CHANGELOG.md:3741 +#: ../../../CHANGELOG.md:4393 msgid "We've been using [acmetool](https://github.com/hlandau/acme) (with the [willwill/acme-docker](https://hub.docker.com/r/willwill/acme-docker/) Docker image) until now." msgstr "" -#: ../../../CHANGELOG.md:3743 +#: ../../../CHANGELOG.md:4395 msgid "Due to the Docker image being deprecated, and things looking bleak for acmetool's support of the newer ACME v2 API endpoint, we've switched to using [certbot](https://certbot.eff.org/) (with the [certbot/certbot](https://hub.docker.com/r/certbot/certbot/) Docker image)." msgstr "" -#: ../../../CHANGELOG.md:3745 +#: ../../../CHANGELOG.md:4397 msgid "Simply re-running the playbook will retrieve new certificates (via certbot) for you. To ensure you don't leave any old files behind, though, you'd better do this:" msgstr "" -#: ../../../CHANGELOG.md:3747 +#: ../../../CHANGELOG.md:4399 msgid "`systemctl stop 'matrix*'`" msgstr "" -#: ../../../CHANGELOG.md:3748 +#: ../../../CHANGELOG.md:4400 msgid "stop your custom webserver, if you're running one (only affects you if you've installed with `matrix_nginx_proxy_enabled: false`)" msgstr "" -#: ../../../CHANGELOG.md:3749 +#: ../../../CHANGELOG.md:4401 msgid "`mv /matrix/ssl /matrix/ssl-acmetool-delete-later`" msgstr "" -#: ../../../CHANGELOG.md:3750 +#: ../../../CHANGELOG.md:4402 msgid "re-run the playbook's [installation](docs/installing.md)" msgstr "" -#: ../../../CHANGELOG.md:3751 +#: ../../../CHANGELOG.md:4403 msgid "possibly delete `/matrix/ssl-acmetool-delete-later`" msgstr "" -#: ../../../CHANGELOG.md:3754 +#: ../../../CHANGELOG.md:4406 msgid "2018-08-21" msgstr "" -#: ../../../CHANGELOG.md:3756 +#: ../../../CHANGELOG.md:4408 msgid "Matrix Corporal support" msgstr "" -#: ../../../CHANGELOG.md:3758 +#: ../../../CHANGELOG.md:4410 msgid "The playbook can now install and configure [matrix-corporal](https://github.com/devture/matrix-corporal) for you." msgstr "" -#: ../../../CHANGELOG.md:3760 +#: ../../../CHANGELOG.md:4412 msgid "Additional details are available in [Setting up Matrix Corporal](docs/configuring-playbook-matrix-corporal.md)." msgstr "" -#: ../../../CHANGELOG.md:3763 +#: ../../../CHANGELOG.md:4415 msgid "2018-08-20" msgstr "" -#: ../../../CHANGELOG.md:3765 +#: ../../../CHANGELOG.md:4417 msgid "Matrix Synapse rate limit control variables" msgstr "" -#: ../../../CHANGELOG.md:3767 +#: ../../../CHANGELOG.md:4419 msgid "The following new variables can now be configured to control Matrix Synapse's rate-limiting (default values are shown below)." msgstr "" -#: ../../../CHANGELOG.md:3774 +#: ../../../CHANGELOG.md:4426 msgid "Shared Secret Auth support via matrix-synapse-shared-secret-auth" msgstr "" -#: ../../../CHANGELOG.md:3776 +#: ../../../CHANGELOG.md:4428 msgid "The playbook can now install and configure [matrix-synapse-shared-secret-auth](https://github.com/devture/matrix-synapse-shared-secret-auth) for you." msgstr "" -#: ../../../CHANGELOG.md:3778 +#: ../../../CHANGELOG.md:4430 msgid "Additional details are available in [Setting up the Shared Secret Auth password provider module](docs/configuring-playbook-shared-secret-auth.md)." msgstr "" -#: ../../../CHANGELOG.md:3781 +#: ../../../CHANGELOG.md:4433 msgid "2018-08-17" msgstr "" -#: ../../../CHANGELOG.md:3783 +#: ../../../CHANGELOG.md:4435 msgid "REST auth support via matrix-synapse-rest-auth" msgstr "" -#: ../../../CHANGELOG.md:3785 +#: ../../../CHANGELOG.md:4437 msgid "The playbook can now install and configure [matrix-synapse-rest-auth](https://github.com/kamax-io/matrix-synapse-rest-auth) for you." msgstr "" -#: ../../../CHANGELOG.md:3787 +#: ../../../CHANGELOG.md:4439 msgid "Additional details are available in [Setting up the REST authentication password provider module](docs/configuring-playbook-rest-auth.md)." msgstr "" -#: ../../../CHANGELOG.md:3789 +#: ../../../CHANGELOG.md:4441 msgid "Compression improvements" msgstr "" -#: ../../../CHANGELOG.md:3791 +#: ../../../CHANGELOG.md:4443 msgid "Shifted Matrix Synapse compression from happening in the Matrix Synapse, to happening in the nginx proxy that's in front of it." msgstr "" -#: ../../../CHANGELOG.md:3794 +#: ../../../CHANGELOG.md:4446 msgid "Additionally, `riot-web` also gets compressed now (in the nginx proxy), which drops the initial page load's size from 5.31MB to 1.86MB." msgstr "" -#: ../../../CHANGELOG.md:3797 +#: ../../../CHANGELOG.md:4449 msgid "Disabling some unnecessary Synapse services" msgstr "" -#: ../../../CHANGELOG.md:3799 +#: ../../../CHANGELOG.md:4451 msgid "The following services are not necessary, so they have been disabled:" msgstr "" -#: ../../../CHANGELOG.md:3800 +#: ../../../CHANGELOG.md:4452 msgid "on the federation port (8448): the `client` service" msgstr "" -#: ../../../CHANGELOG.md:3801 +#: ../../../CHANGELOG.md:4453 msgid "on the http port (8008, exposed over 443): the old Angular `webclient` and the `federation` service" msgstr "" -#: ../../../CHANGELOG.md:3803 +#: ../../../CHANGELOG.md:4455 msgid "Federation runs only on the federation port (8448) now. The Client APIs run only on the http port (8008) now." msgstr "" -#: ../../../CHANGELOG.md:3806 +#: ../../../CHANGELOG.md:4458 msgid "2018-08-15" msgstr "" -#: ../../../CHANGELOG.md:3808 +#: ../../../CHANGELOG.md:4460 msgid "mxisd Identity Server support" msgstr "" -#: ../../../CHANGELOG.md:3810 +#: ../../../CHANGELOG.md:4462 msgid "The playbook now sets up an [mxisd](https://github.com/kamax-io/mxisd) Identity Server for you by default. Additional details are available in [Setting up ma1sd Identity Server](docs/configuring-playbook-mxisd.md)." msgstr "" -#: ../../../CHANGELOG.md:3813 +#: ../../../CHANGELOG.md:4465 msgid "2018-08-14" msgstr "" -#: ../../../CHANGELOG.md:3815 +#: ../../../CHANGELOG.md:4467 msgid "Email-sending support" msgstr "" -#: ../../../CHANGELOG.md:3817 +#: ../../../CHANGELOG.md:4469 msgid "The playbook now configures an email-sending service (postfix) by default. Additional details are available in [Adjusting email-sending settings](docs/configuring-playbook-email.md)." msgstr "" -#: ../../../CHANGELOG.md:3819 +#: ../../../CHANGELOG.md:4471 msgid "With this, Matrix Synapse is able to send email notifications for missed messages, etc." msgstr "" -#: ../../../CHANGELOG.md:3822 +#: ../../../CHANGELOG.md:4474 msgid "2018-08-08" msgstr "" -#: ../../../CHANGELOG.md:3828 +#: ../../../CHANGELOG.md:4480 msgid "from `matrix_max_upload_size_mb` to `matrix_synapse_max_upload_size_mb`" msgstr "" -#: ../../../CHANGELOG.md:3829 +#: ../../../CHANGELOG.md:4481 msgid "from `matrix_max_log_file_size_mb` to `matrix_synapse_max_log_file_size_mb`" msgstr "" -#: ../../../CHANGELOG.md:3830 +#: ../../../CHANGELOG.md:4482 msgid "from `matrix_max_log_files_count` to `matrix_synapse_max_log_files_count`" msgstr "" -#: ../../../CHANGELOG.md:3831 +#: ../../../CHANGELOG.md:4483 msgid "from `docker_matrix_image` to `matrix_docker_image_synapse`" msgstr "" -#: ../../../CHANGELOG.md:3832 +#: ../../../CHANGELOG.md:4484 msgid "from `docker_nginx_image` to `matrix_docker_image_nginx`" msgstr "" -#: ../../../CHANGELOG.md:3833 +#: ../../../CHANGELOG.md:4485 msgid "from `docker_riot_image` to `matrix_docker_image_riot`" msgstr "" -#: ../../../CHANGELOG.md:3834 +#: ../../../CHANGELOG.md:4486 msgid "from `docker_goofys_image` to `matrix_docker_image_goofys`" msgstr "" -#: ../../../CHANGELOG.md:3835 +#: ../../../CHANGELOG.md:4487 msgid "from `docker_coturn_image` to `matrix_docker_image_coturn`" msgstr "" -#: ../../../CHANGELOG.md:3837 +#: ../../../CHANGELOG.md:4489 msgid "If you're overriding any of them in your `vars.yml` file, you'd need to change to the new names." msgstr "" -#: ../../../CHANGELOG.md:3839 +#: ../../../CHANGELOG.md:4491 msgid "Renaming Ansible playbook tag" msgstr "" -#: ../../../CHANGELOG.md:3841 +#: ../../../CHANGELOG.md:4493 msgid "The command for executing the whole playbook has changed. The `setup-main` tag got renamed to `setup-all`." msgstr "" -#: ../../../CHANGELOG.md:3843 +#: ../../../CHANGELOG.md:4495 msgid "Docker container linking" msgstr "" -#: ../../../CHANGELOG.md:3845 +#: ../../../CHANGELOG.md:4497 msgid "Changed the way the Docker containers are linked together. The ones that need to communicate with others operate in a `matrix` network now and not in the default bridge network." msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/README.po b/i18n/locales/jp/LC_MESSAGES/README.po index 8faa4b11d..5bfed6e9b 100644 --- a/i18n/locales/jp/LC_MESSAGES/README.po +++ b/i18n/locales/jp/LC_MESSAGES/README.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,10 +18,10 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" #: ../../../README.md:1 -msgid "[![Support room on Matrix](https://img.shields.io/matrix/matrix-docker-ansible-deploy:devture.com.svg?label=%23matrix-docker-ansible-deploy%3Adevture.com&logo=matrix&style=for-the-badge&server_fqdn=matrix.devture.com)](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com) [![donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/s.pantaleev/donate)" +msgid "[![Support room on Matrix](https://img.shields.io/matrix/matrix-docker-ansible-deploy:devture.com.svg?label=%23matrix-docker-ansible-deploy%3Adevture.com&logo=matrix&style=for-the-badge&server_fqdn=matrix.devture.com&fetchMode=summary)](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com) [![donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/s.pantaleev/donate) [![REUSE status](https://api.reuse.software/badge/github.com/spantaleev/matrix-docker-ansible-deploy)](https://api.reuse.software/info/github.com/spantaleev/matrix-docker-ansible-deploy)" msgstr "" #: ../../../README.md:1 @@ -32,6 +32,10 @@ msgstr "" msgid "donate" msgstr "" +#: ../../../README.md:1 +msgid "REUSE status" +msgstr "" + #: ../../../README.md:3 msgid "Matrix (An open network for secure, decentralized communication) server setup using Ansible and Docker" msgstr "" @@ -177,15 +181,15 @@ msgid "[Link](docs/configuring-playbook-conduit.md)" msgstr "" #: ../../../README.md -msgid "[conduwuit](https://conduwuit.puppyirl.gay/)" +msgid "[continuwuity](https://continuwuity.org)" msgstr "" #: ../../../README.md -msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. conduwuit is a fork of Conduit." +msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network." msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-conduwuit.md)" +msgid "[Link](docs/configuring-playbook-continuwuity.md)" msgstr "" #: ../../../README.md @@ -244,6 +248,14 @@ msgstr "" msgid "[Link](docs/configuring-playbook-client-cinny.md)" msgstr "" +#: ../../../README.md +msgid "[Sable](https://github.com/7w1/sable)" +msgstr "" + +#: ../../../README.md +msgid "[Link](docs/configuring-playbook-client-sable.md)" +msgstr "" + #: ../../../README.md msgid "[SchildiChat Web](https://schildi.chat/)" msgstr "" @@ -256,36 +268,36 @@ msgstr "" msgid "[Link](docs/configuring-playbook-client-schildichat-web.md)" msgstr "" -#: ../../../README.md:69 -msgid "Server Components" +#: ../../../README.md +msgid "[FluffyChat Web](https://fluffychat.im/)" msgstr "" -#: ../../../README.md:71 -msgid "Services that run on the server to make the various parts of your installation work." +#: ../../../README.md +msgid "The cutest messenger in Matrix" msgstr "" #: ../../../README.md -msgid "[PostgreSQL](https://www.postgresql.org/)" +msgid "[Link](docs/configuring-playbook-client-fluffychat-web.md)" msgstr "" -#: ../../../README.md -msgid "Database for Synapse. [Using an external PostgreSQL server](docs/configuring-playbook-external-postgres.md) is also possible." +#: ../../../README.md:71 +msgid "Server Components" msgstr "" -#: ../../../README.md -msgid "[Link](docs/configuring-playbook-external-postgres.md)" +#: ../../../README.md:73 +msgid "Services that run on the server to make the various parts of your installation work." msgstr "" #: ../../../README.md -msgid "[coturn](https://github.com/coturn/coturn)" +msgid "[PostgreSQL](https://www.postgresql.org/)" msgstr "" #: ../../../README.md -msgid "STUN/TURN server for WebRTC audio/video calls" +msgid "Database for Synapse. [Using an external PostgreSQL server](docs/configuring-playbook-external-postgres.md) is also possible." msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-turn.md)" +msgid "[Link](docs/configuring-playbook-external-postgres.md)" msgstr "" #: ../../../README.md @@ -293,7 +305,7 @@ msgid "[Traefik](https://doc.traefik.io/traefik/)" msgstr "" #: ../../../README.md -msgid "Web server, listening on ports 80, 443 and 8448 - standing in front of all the other services. Using your own webserver [is possible](docs/configuring-playbook-own-webserver.md)" +msgid "Web server, listening on ports 80, 443 and 8448 - standing in front of all the other services. [Using your own webserver](docs/configuring-playbook-own-webserver.md) is also possible." msgstr "" #: ../../../README.md @@ -325,15 +337,15 @@ msgid "[Link](docs/configuring-playbook-email.md)" msgstr "" #: ../../../README.md -msgid "[ma1sd](https://github.com/ma1uta/ma1sd)" +msgid "[coturn](https://github.com/coturn/coturn)" msgstr "" #: ../../../README.md -msgid "Matrix Identity Server" +msgid "STUN/TURN server for WebRTC audio/video calls" msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-ma1sd.md)" +msgid "[Link](docs/configuring-playbook-turn.md)" msgstr "" #: ../../../README.md @@ -348,11 +360,23 @@ msgstr "" msgid "[Link](docs/configuring-playbook-dynamic-dns.md)" msgstr "" -#: ../../../README.md:83 -msgid "Authentication" +#: ../../../README.md +msgid "Matrix RTC stack" +msgstr "" + +#: ../../../README.md +msgid "Supporting components ([LiveKit Server](docs/configuring-playbook-livekit-server.md) and [LiveKit JWT Service](docs/configuring-playbook-livekit-jwt-service.md)) for in-app audio/video calls for Matrix clients" +msgstr "" + +#: ../../../README.md +msgid "[Link](docs/configuring-playbook-matrix-rtc.md)" msgstr "" #: ../../../README.md:85 +msgid "Authentication" +msgstr "" + +#: ../../../README.md:87 msgid "Extend and modify how users are authenticated on your homeserver." msgstr "" @@ -397,7 +421,7 @@ msgid "[matrix-ldap-registration-proxy](https://gitlab.com/activism.internationa msgstr "" #: ../../../README.md -msgid "A proxy that handles Matrix registration requests and forwards them to LDAP." +msgid "Proxy that handles Matrix registration requests and forwards them to LDAP" msgstr "" #: ../../../README.md @@ -409,7 +433,7 @@ msgid "[matrix-registration](https://github.com/ZerataX/matrix-registration)" msgstr "" #: ../../../README.md -msgid "A simple python application to have a token based Matrix registration" +msgid "Simple python application to have a token based Matrix registration" msgstr "" #: ../../../README.md @@ -417,7 +441,7 @@ msgid "[Link](docs/configuring-playbook-matrix-registration.md)" msgstr "" #: ../../../README.md -msgid "[Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service) (UVS)" +msgid "[Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service)" msgstr "" #: ../../../README.md @@ -433,18 +457,18 @@ msgid "[synapse-simple-antispam](https://github.com/t2bot/synapse-simple-antispa msgstr "" #: ../../../README.md -msgid "A spam checker module" +msgid "Spam checker module" msgstr "" #: ../../../README.md msgid "[Link](docs/configuring-playbook-synapse-simple-antispam.md)" msgstr "" -#: ../../../README.md:97 +#: ../../../README.md:99 msgid "File Storage" msgstr "" -#: ../../../README.md:99 +#: ../../../README.md:101 msgid "Use alternative file storage to the default `media_store` folder." msgstr "" @@ -473,18 +497,18 @@ msgid "[matrix-media-repo](https://github.com/turt2live/matrix-media-repo)" msgstr "" #: ../../../README.md -msgid "matrix-media-repo is a highly customizable multi-domain media repository for Matrix. Intended for medium to large deployments, this media repo de-duplicates media while being fully compliant with the specification." +msgid "Highly customizable multi-domain media repository for Matrix. Intended for medium to large deployments, this media repo de-duplicates media while being fully compliant with the specification." msgstr "" #: ../../../README.md msgid "[Link](docs/configuring-playbook-matrix-media-repo.md)" msgstr "" -#: ../../../README.md:107 +#: ../../../README.md:109 msgid "Bridges" msgstr "" -#: ../../../README.md:109 +#: ../../../README.md:111 msgid "Bridges can be used to connect your Matrix installation with third-party communication networks." msgstr "" @@ -560,6 +584,18 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bridge-mautrix-wsproxy.md)" msgstr "" +#: ../../../README.md +msgid "[mautrix-bluesky](https://github.com/mautrix/bluesky)" +msgstr "" + +#: ../../../README.md +msgid "Bridge to [Bluesky](https://bsky.social/)" +msgstr "" + +#: ../../../README.md +msgid "[Link](docs/configuring-playbook-bridge-mautrix-bluesky.md)" +msgstr "" + #: ../../../README.md msgid "[mautrix-twitter](https://github.com/mautrix/twitter)" msgstr "" @@ -656,14 +692,6 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bridge-appservice-discord.md)" msgstr "" -#: ../../../README.md -msgid "[matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack)" -msgstr "" - -#: ../../../README.md -msgid "[Link](docs/configuring-playbook-bridge-appservice-slack.md)" -msgstr "" - #: ../../../README.md msgid "[matrix-hookshot](https://github.com/matrix-org/matrix-hookshot)" msgstr "" @@ -689,83 +717,39 @@ msgid "[Link](docs/configuring-playbook-bridge-matrix-bridge-sms.md)" msgstr "" #: ../../../README.md -msgid "[matrix-wechat](https://github.com/duo/matrix-wechat)" -msgstr "" - -#: ../../../README.md -msgid "Bridge to [WeChat](https://www.wechat.com/)" -msgstr "" - -#: ../../../README.md -msgid "[Link](docs/configuring-playbook-bridge-wechat.md)" -msgstr "" - -#: ../../../README.md -msgid "[Heisenbridge](https://github.com/hifi/heisenbridge)" -msgstr "" - -#: ../../../README.md -msgid "Bouncer-style bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat)" -msgstr "" - -#: ../../../README.md -msgid "[Link](docs/configuring-playbook-bridge-heisenbridge.md)" -msgstr "" - -#: ../../../README.md -msgid "[go-skype-bridge](https://github.com/kelaresg/go-skype-bridge)" -msgstr "" - -#: ../../../README.md -msgid "Bridge to [Skype](https://www.skype.com)" +msgid "[matrix-steam-bridge](https://github.com/jasonlaguidice/matrix-steam-bridge)" msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-bridge-go-skype-bridge.md)" +msgid "Bridge to [Steam](https://steampowered.com/)" msgstr "" #: ../../../README.md -msgid "[mx-puppet-slack](https://gitlab.com/mx-puppet/slack/mx-puppet-slack)" +msgid "[Link](docs/configuring-playbook-bridge-steam.md)" msgstr "" #: ../../../README.md -msgid "Bridge to [Slack](https://slack.com)" -msgstr "" - -#: ../../../README.md -msgid "[Link](docs/configuring-playbook-bridge-mx-puppet-slack.md)" -msgstr "" - -#: ../../../README.md -msgid "[mx-puppet-instagram](https://github.com/Sorunome/mx-puppet-instagram)" -msgstr "" - -#: ../../../README.md -msgid "Bridge for Instagram-DMs ([Instagram](https://www.instagram.com/))" -msgstr "" - -#: ../../../README.md -msgid "[Link](docs/configuring-playbook-bridge-mx-puppet-instagram.md)" +msgid "[matrix-wechat](https://github.com/duo/matrix-wechat)" msgstr "" #: ../../../README.md -msgid "[mx-puppet-twitter](https://github.com/Sorunome/mx-puppet-twitter)" +msgid "Bridge to [WeChat](https://www.wechat.com/)" msgstr "" #: ../../../README.md -msgid "Bridge for Twitter-DMs ([Twitter](https://twitter.com/))" +msgid "[Link](docs/configuring-playbook-bridge-wechat.md)" msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-bridge-mx-puppet-twitter.md)" +msgid "[Heisenbridge](https://github.com/hifi/heisenbridge)" msgstr "" #: ../../../README.md -msgid "[mx-puppet-discord](https://gitlab.com/mx-puppet/discord/mx-puppet-discord)" +msgid "Bouncer-style bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat)" msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-bridge-mx-puppet-discord.md)" +msgid "[Link](docs/configuring-playbook-bridge-heisenbridge.md)" msgstr "" #: ../../../README.md @@ -781,7 +765,7 @@ msgid "[Link](docs/configuring-playbook-bridge-mx-puppet-groupme.md)" msgstr "" #: ../../../README.md -msgid "[mx-puppet-steam](https://github.com/icewind1991/mx-puppet-steam)" +msgid "[mx-puppet-steam](https://codeberg.org/icewind/mx-puppet-steam)" msgstr "" #: ../../../README.md @@ -804,11 +788,11 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bridge-postmoogle.md)" msgstr "" -#: ../../../README.md:141 +#: ../../../README.md:139 msgid "Bots" msgstr "" -#: ../../../README.md:143 +#: ../../../README.md:141 msgid "Bots provide various additional functionality to your installation." msgstr "" @@ -817,7 +801,7 @@ msgid "[baibot](https://github.com/etkecc/baibot)" msgstr "" #: ../../../README.md -msgid "A bot that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you" +msgid "Bot that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you" msgstr "" #: ../../../README.md @@ -853,7 +837,7 @@ msgid "[maubot](https://github.com/maubot/maubot)" msgstr "" #: ../../../README.md -msgid "A plugin-based Matrix bot system" +msgid "Plugin-based Matrix bot system" msgstr "" #: ../../../README.md @@ -865,7 +849,7 @@ msgid "[Honoroit](https://github.com/etkecc/honoroit)" msgstr "" #: ../../../README.md -msgid "A helpdesk bot" +msgid "Helpdesk bot" msgstr "" #: ../../../README.md @@ -877,7 +861,7 @@ msgid "[Mjolnir](https://github.com/matrix-org/mjolnir)" msgstr "" #: ../../../README.md -msgid "A moderation tool for Matrix" +msgid "Moderation tool for Matrix" msgstr "" #: ../../../README.md @@ -889,7 +873,7 @@ msgid "[Draupnir](https://github.com/the-draupnir-project/Draupnir)" msgstr "" #: ../../../README.md -msgid "A moderation tool for Matrix (Fork of Mjolnir)" +msgid "Moderation tool for Matrix (Fork of Mjolnir)" msgstr "" #: ../../../README.md @@ -908,11 +892,11 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bot-buscarron.md)" msgstr "" -#: ../../../README.md:156 +#: ../../../README.md:154 msgid "Administration" msgstr "" -#: ../../../README.md:158 +#: ../../../README.md:156 msgid "Services that help you in administrating and monitoring your Matrix installation." msgstr "" @@ -941,15 +925,15 @@ msgid "[Link](docs/configuring-playbook-matrix-authentication-service.md)" msgstr "" #: ../../../README.md -msgid "[synapse-admin](https://github.com/etkecc/synapse-admin)" +msgid "[Ketesa](https://github.com/etkecc/ketesa)" msgstr "" #: ../../../README.md -msgid "A web UI tool for administrating users and rooms on your Matrix server" +msgid "Fully-featured web UI for administrating your Matrix homeserver — users, rooms, media, sessions, and more" msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-synapse-admin.md)" +msgid "[Link](docs/configuring-playbook-ketesa.md)" msgstr "" #: ../../../README.md @@ -961,7 +945,7 @@ msgid "Consists of the [Prometheus](https://prometheus.io) time-series database msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-prometheus-grafana.md) (for [prometheus-nginxlog-exporter](docs/configuring-playbook-prometheus-nginxlog.md))" +msgid "[Link](docs/configuring-playbook-prometheus-grafana.md) (for [prometheus-nginxlog-exporter](docs/configuring-playbook-prometheus-grafana.md#enable-metrics-and-graphs-for-nginx-logs-optional))" msgstr "" #: ../../../README.md @@ -1000,60 +984,48 @@ msgstr "" msgid "[Link](docs/configuring-playbook-synapse-usage-exporter.md)" msgstr "" -#: ../../../README.md:170 +#: ../../../README.md:168 msgid "Misc" msgstr "" -#: ../../../README.md:172 +#: ../../../README.md:170 msgid "Various services that don't fit any other categories." msgstr "" #: ../../../README.md -msgid "[sliding-sync](https://github.com/matrix-org/sliding-sync)" -msgstr "" - -#: ../../../README.md -msgid "(Superseded by Simplified Sliding Sync integrated into Synapse > `1.114` and Conduit > `0.6.0`) Sliding Sync support for clients which require it (e.g. old Element X versions before Simplified Sliding Sync was developed)" -msgstr "" - -#: ../../../README.md -msgid "[Link](docs/configuring-playbook-sliding-sync-proxy.md)" -msgstr "" - -#: ../../../README.md -msgid "[synapse_auto_accept_invite](https://github.com/matrix-org/synapse-auto-accept-invite)" +msgid "[synapse_auto_compressor](https://github.com/matrix-org/rust-synapse-compress-state/#automated-tool-synapse_auto_compressor)" msgstr "" #: ../../../README.md -msgid "A Synapse module to automatically accept invites." +msgid "Cli tool that automatically compresses `state_groups` database table in background" msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-synapse-auto-accept-invite.md)" +msgid "[Link](docs/configuring-playbook-synapse-auto-compressor.md)" msgstr "" #: ../../../README.md -msgid "[synapse_auto_compressor](https://github.com/matrix-org/rust-synapse-compress-state/#automated-tool-synapse_auto_compressor)" +msgid "[Matrix Corporal](https://github.com/devture/matrix-corporal) (advanced)" msgstr "" #: ../../../README.md -msgid "A cli tool that automatically compresses `state_groups` database table in background." +msgid "Reconciliator and gateway for a managed Matrix server" msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-synapse-auto-compressor.md)" +msgid "[Link](docs/configuring-playbook-matrix-corporal.md)" msgstr "" #: ../../../README.md -msgid "[Matrix Corporal](https://github.com/devture/matrix-corporal) (advanced)" +msgid "[Matrix.to](https://github.com/matrix-org/matrix.to)" msgstr "" #: ../../../README.md -msgid "Reconciliator and gateway for a managed Matrix server" +msgid "Simple URL redirection service for the Matrix ecosystem" msgstr "" #: ../../../README.md -msgid "[Link](docs/configuring-playbook-matrix-corporal.md)" +msgid "[Link](docs/configuring-playbook-matrixto.md)" msgstr "" #: ../../../README.md @@ -1061,7 +1033,7 @@ msgid "[Etherpad](https://etherpad.org)" msgstr "" #: ../../../README.md -msgid "An open source collaborative text editor" +msgid "Open source collaborative text editor" msgstr "" #: ../../../README.md @@ -1073,7 +1045,7 @@ msgid "[Jitsi](https://jitsi.org/)" msgstr "" #: ../../../README.md -msgid "An open source video-conferencing platform" +msgid "Open source video-conferencing platform" msgstr "" #: ../../../README.md @@ -1085,7 +1057,7 @@ msgid "[Cactus Comments](https://cactus.chat)" msgstr "" #: ../../../README.md -msgid "A federated comment system built on Matrix" +msgid "Federated comment system built on Matrix" msgstr "" #: ../../../README.md @@ -1097,7 +1069,7 @@ msgid "[Pantalaimon](https://github.com/matrix-org/pantalaimon)" msgstr "" #: ../../../README.md -msgid "An E2EE aware proxy daemon" +msgid "E2EE aware proxy daemon" msgstr "" #: ../../../README.md @@ -1128,54 +1100,66 @@ msgstr "" msgid "[Link](docs/configuring-playbook-ntfy.md)" msgstr "" -#: ../../../README.md:187 +#: ../../../README.md +msgid "[Element Call](https://github.com/element-hq/element-call)" +msgstr "" + +#: ../../../README.md +msgid "A native Matrix video conferencing application" +msgstr "" + +#: ../../../README.md +msgid "[Link](docs/configuring-playbook-element-call.md)" +msgstr "" + +#: ../../../README.md:185 msgid "🆕 Changes" msgstr "" -#: ../../../README.md:189 +#: ../../../README.md:187 msgid "This playbook evolves over time, sometimes with backward-incompatible changes." msgstr "" -#: ../../../README.md:191 +#: ../../../README.md:189 msgid "When updating the playbook, refer to [the changelog](CHANGELOG.md) to catch up with what's new." msgstr "" -#: ../../../README.md:193 +#: ../../../README.md:191 msgid "🆘 Support" msgstr "" -#: ../../../README.md:195 +#: ../../../README.md:193 msgid "Matrix room: [#matrix-docker-ansible-deploy:devture.com](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com)" msgstr "" -#: ../../../README.md:197 +#: ../../../README.md:195 msgid "IRC channel: `#matrix-docker-ansible-deploy` on the [Libera Chat](https://libera.chat/) IRC network (irc.libera.chat:6697)" msgstr "" -#: ../../../README.md:199 +#: ../../../README.md:197 msgid "GitHub issues: [spantaleev/matrix-docker-ansible-deploy/issues](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues)" msgstr "" -#: ../../../README.md:201 +#: ../../../README.md:199 msgid "🌐 Translation" msgstr "" -#: ../../../README.md:203 +#: ../../../README.md:201 msgid "See the [i18n/README.md](i18n/README.md) file for more information about translation." msgstr "" -#: ../../../README.md:205 +#: ../../../README.md:203 msgid "Translations are still work in progress." msgstr "" -#: ../../../README.md:207 +#: ../../../README.md:205 msgid "🤝 Related" msgstr "" -#: ../../../README.md:209 +#: ../../../README.md:207 msgid "You may also be interested in [mash-playbook](https://github.com/mother-of-all-self-hosting/mash-playbook) - another Ansible playbook for self-hosting non-Matrix services (see its [List of supported services](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md))." msgstr "" -#: ../../../README.md:211 +#: ../../../README.md:209 msgid "mash-playbook also makes use of [Traefik](./docs/configuring-playbook-traefik.md) as its reverse-proxy, so with minor [interoperability adjustments](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/interoperability.md), you can make matrix-docker-ansible-deploy and mash-playbook co-exist and host Matrix and non-Matrix services on the same server." msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/README.po b/i18n/locales/jp/LC_MESSAGES/docs/README.po index e12323e2f..53645fce6 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/README.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/README.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-02-13 10:32+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,156 +18,156 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/README.md:1 +#: ../../../docs/README.md:10 msgid "Table of Contents" msgstr "" -#: ../../../docs/README.md:3 -msgid "⬇️ Installaton guides " +#: ../../../docs/README.md:12 +msgid "⬇️ Installation guides " msgstr "" -#: ../../../docs/README.md:5 +#: ../../../docs/README.md:14 msgid "There are two installation guides available for beginners and advanced users." msgstr "" -#: ../../../docs/README.md:7 +#: ../../../docs/README.md:16 msgid "⚡ **[Quick start](quick-start.md) (for beginners)**: this is recommended for those who do not have an existing Matrix server and want to start quickly with \"opinionated defaults\"." msgstr "" -#: ../../../docs/README.md:9 +#: ../../../docs/README.md:18 msgid "**Full installation guide (for advanced users)**: if you need to import an existing Matrix server's data into the new server or want to learn more while setting up the server, follow this guide." msgstr "" -#: ../../../docs/README.md:11 +#: ../../../docs/README.md:20 msgid "[Prerequisites](prerequisites.md)" msgstr "" -#: ../../../docs/README.md:13 -msgid "[Configuring your DNS settings](configuring-dns.md)" +#: ../../../docs/README.md:22 +msgid "[Configuring DNS settings](configuring-dns.md)" msgstr "" -#: ../../../docs/README.md:15 +#: ../../../docs/README.md:24 msgid "[Getting the playbook](getting-the-playbook.md)" msgstr "" -#: ../../../docs/README.md:17 +#: ../../../docs/README.md:26 msgid "[Configuring the playbook](configuring-playbook.md)" msgstr "" -#: ../../../docs/README.md:19 +#: ../../../docs/README.md:28 msgid "[Installing](installing.md)" msgstr "" -#: ../../../docs/README.md:21 +#: ../../../docs/README.md:30 msgid "🛠️ Configuration options" msgstr "" -#: ../../../docs/README.md:28 +#: ../../../docs/README.md:37 msgid "You can check useful documentation for configuring components here: [Configuring the playbook](configuring-playbook.md)" msgstr "" -#: ../../../docs/README.md:30 +#: ../../../docs/README.md:39 msgid "[Administration](configuring-playbook.md#administration) — services that help you in administrating and monitoring your Matrix installation" msgstr "" -#: ../../../docs/README.md:32 +#: ../../../docs/README.md:41 msgid "[Authentication and user-related](configuring-playbook.md#authentication-and-user-related) — extend and modify how users are authenticated on your homeserver" msgstr "" -#: ../../../docs/README.md:34 +#: ../../../docs/README.md:43 msgid "[Bots](configuring-playbook.md#bots) — bots provide various additional functionality to your installation" msgstr "" -#: ../../../docs/README.md:36 +#: ../../../docs/README.md:45 msgid "[Bridges](configuring-playbook.md#bridging-other-networks) — bridges can be used to connect your Matrix installation with third-party communication networks" msgstr "" -#: ../../../docs/README.md:38 +#: ../../../docs/README.md:47 msgid "[Clients](configuring-playbook.md#clients) — web clients for Matrix that you can host on your own domains" msgstr "" -#: ../../../docs/README.md:40 +#: ../../../docs/README.md:49 msgid "[Core service adjustments](configuring-playbook.md#core-service-adjustments) — backbone of your Matrix system" msgstr "" -#: ../../../docs/README.md:42 +#: ../../../docs/README.md:51 msgid "[File Storage](configuring-playbook.md#file-storage) — use alternative file storage to the default `media_store` folder" msgstr "" -#: ../../../docs/README.md:46 +#: ../../../docs/README.md:55 msgid "[Other specialized services](configuring-playbook.md#other-specialized-services) — various services that don't fit any other categories" msgstr "" -#: ../../../docs/README.md:48 +#: ../../../docs/README.md:57 msgid "👨‍🔧 Maintenance" msgstr "" -#: ../../../docs/README.md:50 +#: ../../../docs/README.md:59 msgid "If your server and services experience issues, feel free to come to [our support room](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com) and ask for help." msgstr "" -#: ../../../docs/README.md:54 -msgid "[Checking if services work](maintenance-checking-services.md)" -msgstr "" - -#: ../../../docs/README.md:56 +#: ../../../docs/README.md:63 msgid "[Maintenance and Troubleshooting](maintenance-and-troubleshooting.md)" msgstr "" -#: ../../../docs/README.md:58 +#: ../../../docs/README.md:65 msgid "[PostgreSQL maintenance](maintenance-postgres.md)" msgstr "" -#: ../../../docs/README.md:60 +#: ../../../docs/README.md:67 msgid "[Synapse maintenance](maintenance-synapse.md)" msgstr "" -#: ../../../docs/README.md:62 +#: ../../../docs/README.md:69 msgid "[Upgrading services](maintenance-upgrading-services.md)" msgstr "" -#: ../../../docs/README.md:64 +#: ../../../docs/README.md:71 msgid "Other documentation pages " msgstr "" -#: ../../../docs/README.md:66 +#: ../../../docs/README.md:73 msgid "ℹ️ **[FAQ](faq.md)** — various Frequently Asked Questions about Matrix, with a focus on this Ansible playbook" msgstr "" -#: ../../../docs/README.md:70 +#: ../../../docs/README.md:77 msgid "[Alternative architectures](alternative-architectures.md)" msgstr "" -#: ../../../docs/README.md:72 +#: ../../../docs/README.md:79 msgid "[Container images used by the playbook](container-images.md)" msgstr "" -#: ../../../docs/README.md:74 +#: ../../../docs/README.md:81 msgid "[Obtaining an Access Token](obtaining-access-tokens.md)" msgstr "" -#: ../../../docs/README.md:76 +#: ../../../docs/README.md:83 msgid "[Playbook tags](playbook-tags.md)" msgstr "" -#: ../../../docs/README.md:78 +#: ../../../docs/README.md:85 msgid "[Registering users](registering-users.md)" msgstr "" -#: ../../../docs/README.md:80 +#: ../../../docs/README.md:87 msgid "[Running `just` commands](just.md)" msgstr "" -#: ../../../docs/README.md:82 +#: ../../../docs/README.md:89 msgid "[Self-building](self-building.md)" msgstr "" -#: ../../../docs/README.md:84 +#: ../../../docs/README.md:91 msgid "[Uninstalling](uninstalling.md)" msgstr "" -#: ../../../docs/README.md:86 +#: ../../../docs/README.md:93 msgid "[Updating users passwords](updating-users-passwords.md)" msgstr "" + +#: ../../../docs/README.md:95 +msgid "[Using Ansible for the playbook](ansible.md)" +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-appservice-draupnir-for-all.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-appservice-draupnir-for-all.po index 6aa8af195..7e8355a4a 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-appservice-draupnir-for-all.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-appservice-draupnir-for-all.po @@ -162,7 +162,7 @@ msgid "Granting Users the ability to use D4A" msgstr "" #: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:97 -msgid "Draupnir for all includes several security measures like that it only allows users that are on its allow list to ask for a bot. To add a user to this list we have 2 primary options. Using the chat to tell Draupnir to do this for us or if you want to automatically do it by sending `m.policy.rule.user` events that target the subject you want to allow provisioning for with the `org.matrix.mjolnir.allow` recomendation. Using the chat is recomended." +msgid "Draupnir for all includes several security measures like that it only allows users that are on its allow list to ask for a bot. To add a user to this list we have 2 primary options. Using the chat to tell Draupnir to do this for us or if you want to automatically do it by sending `m.policy.rule.user` events that target the subject you want to allow provisioning for with the `org.matrix.mjolnir.allow` recomendation. Using the chat is recommended." msgstr "" #: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:99 diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-baibot.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-baibot.po index 95f72acba..a96b8ea14 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-baibot.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-baibot.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,431 +18,459 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-baibot.md:1 +#: ../../../docs/configuring-playbook-bot-baibot.md:8 msgid "Setting up baibot (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:8 +#: ../../../docs/configuring-playbook-bot-baibot.md:15 msgid "🤖 [baibot](https://github.com/etkecc/baibot) (pronounced bye-bot) is a [Matrix](https://matrix.org/) bot developed by [etke.cc](https://etke.cc/) that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you. 🤖" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:10 +#: ../../../docs/configuring-playbook-bot-baibot.md:17 msgid "It supports [OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/) models, as many well as other [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:12 +#: ../../../docs/configuring-playbook-bot-baibot.md:19 msgid "It's designed as a more private and [✨ featureful](https://github.com/etkecc/baibot/?tab=readme-ov-file#-features) alternative to [matrix-chatgpt-bot](./configuring-playbook-bot-chatgpt.md). See the [baibot](https://github.com/etkecc/baibot) project and its documentation for more information." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:14 +#: ../../../docs/configuring-playbook-bot-baibot.md:21 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:16 +#: ../../../docs/configuring-playbook-bot-baibot.md:23 msgid "API access to one or more LLM [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:18 +#: ../../../docs/configuring-playbook-bot-baibot.md:25 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:20 +#: ../../../docs/configuring-playbook-bot-baibot.md:27 msgid "There are **a lot of configuration options** (some required, some possibly required, some optional), so they're **split into multiple sections below**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:23 +#: ../../../docs/configuring-playbook-bot-baibot.md:30 msgid "[Base configuration](#base-configuration)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:24 +#: ../../../docs/configuring-playbook-bot-baibot.md:31 msgid "[👮‍♂️ Administrator configuration](#️-administrator-configuration)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:25 +#: ../../../docs/configuring-playbook-bot-baibot.md:32 msgid "[👥 Initial users configuration](#-initial-users-configuration)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:26 +#: ../../../docs/configuring-playbook-bot-baibot.md:33 msgid "[🤖 Configuring agents via Ansible](#-configuring-agents-via-ansible)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:27 +#: ../../../docs/configuring-playbook-bot-baibot.md:34 msgid "[🤝 Configuring initial default handlers](#-configuring-initial-default-handlers)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:29 +#: ../../../docs/configuring-playbook-bot-baibot.md:36 msgid "Depending on your current `vars.yml` file and desired configuration, **you may require more than just the [base configuration](#base-configuration)**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:31 +#: ../../../docs/configuring-playbook-bot-baibot.md:38 msgid "Base configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:33 +#: ../../../docs/configuring-playbook-bot-baibot.md:40 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:71 +#: ../../../docs/configuring-playbook-bot-baibot.md:42 +msgid "Authentication can be configured in one of two mutually-exclusive ways:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:44 +msgid "**Password authentication** (`matrix_bot_baibot_config_user_password`) - recommended for most playbook-managed setups, because it integrates with automatic user creation flow used by the playbook, and auto-creates the bot account" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:45 +msgid "**Access-token authentication** (`matrix_bot_baibot_config_user_access_token` + `matrix_bot_baibot_config_user_device_id`) - useful for specific [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md)/OIDC setups where password authentication is not available or not desired" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:47 +msgid "Even when [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) is enabled, password authentication is still typically the best fit for baibot if you're using a playbook-managed bot account." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:49 +msgid "For upstream details, see baibot's [🔐 Authentication](https://github.com/etkecc/baibot/blob/main/docs/configuration/authentication.md) documentation." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:97 msgid "As mentioned above, **this may not be enough**. Continue with the configuration sections below." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:73 +#: ../../../docs/configuring-playbook-bot-baibot.md:99 msgid "👮‍♂️ Administrator configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:75 -#: ../../../docs/configuring-playbook-bot-baibot.md:99 +#: ../../../docs/configuring-playbook-bot-baibot.md:101 +#: ../../../docs/configuring-playbook-bot-baibot.md:125 msgid "This is an addition to the [base configuration](#base-configuration)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:77 +#: ../../../docs/configuring-playbook-bot-baibot.md:103 msgid "To specify who is considered a bot [👮‍♂️ Administrator](https://github.com/etkecc/baibot/blob/main/docs/access.md#administrators), you either need to specify `matrix_bot_baibot_config_access_admin_patterns` or `matrix_admin`. The latter is a single variable which affects all bridges and bots." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:79 +#: ../../../docs/configuring-playbook-bot-baibot.md:105 msgid "If `matrix_admin` is already configured in your `vars.yml` configuration, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:81 -#: ../../../docs/configuring-playbook-bot-baibot.md:110 +#: ../../../docs/configuring-playbook-bot-baibot.md:107 +#: ../../../docs/configuring-playbook-bot-baibot.md:136 msgid "**If necessary**, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:95 +#: ../../../docs/configuring-playbook-bot-baibot.md:121 msgid "👥 Initial users configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:97 +#: ../../../docs/configuring-playbook-bot-baibot.md:123 msgid "By default, **all users on your homeserver are considered allowed users**. If that's OK, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:101 +#: ../../../docs/configuring-playbook-bot-baibot.md:127 msgid "To specify who is considered a bot [👥 User](https://github.com/etkecc/baibot/blob/main/docs/access.md#user), you may:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:103 +#: ../../../docs/configuring-playbook-bot-baibot.md:129 msgid "define an **initial** value for `matrix_bot_baibot_config_initial_global_config_user_patterns` Ansible variable, as shown below" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:104 +#: ../../../docs/configuring-playbook-bot-baibot.md:130 msgid "configure the list at runtime via the bot's `!bai access set-users SPACE_SEPARATED_PATTERNS` command" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:106 +#: ../../../docs/configuring-playbook-bot-baibot.md:132 msgid "Configuring `matrix_bot_baibot_config_initial_global_config_user_patterns` is optional, but it can be useful to pre-configure the bot with a list of users who should have access to the bot's features." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:108 +#: ../../../docs/configuring-playbook-bot-baibot.md:134 msgid "**Note**: Once initially configured, the allowed users list **cannot be managed via Ansible anymore**. It can only be managed subsequently via bot commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:122 +#: ../../../docs/configuring-playbook-bot-baibot.md:148 msgid "🤖 Configuring agents via Ansible" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:124 +#: ../../../docs/configuring-playbook-bot-baibot.md:150 msgid "You are **not required** to define agents [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration) via Ansible. **To get started quickly**, you can **skip this section and define agents at runtime via chat commands** (following the bot's guidance)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:126 +#: ../../../docs/configuring-playbook-bot-baibot.md:152 msgid "Privileged users (like the [👮‍♂️ Administrator](#️-administrator-configuration), but potentially others too — see the upstream [🔒 access](https://github.com/etkecc/baibot/blob/main/docs/access.md) documentation) can **define agents dynamically at any time** via chat commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:128 +#: ../../../docs/configuring-playbook-bot-baibot.md:154 msgid "The Ansible role includes preset variables for easily enabling some [🤖 agents](https://github.com/etkecc/baibot/blob/main/docs/agents.md) on various [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md) (e.g. OpenAI, etc)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:130 +#: ../../../docs/configuring-playbook-bot-baibot.md:156 msgid "Besides the presets, the Ansible role also includes support for configuring additional statically-defined agents via the `matrix_bot_baibot_config_agents_static_definitions_custom` Ansible variable." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:132 +#: ../../../docs/configuring-playbook-bot-baibot.md:158 msgid "Agents defined statically and those created dynamically (via chat) are named differently, so **conflict cannot arise**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:134 +#: ../../../docs/configuring-playbook-bot-baibot.md:160 msgid "Depending on your propensity for [GitOps](https://en.wikipedia.org/wiki/DevOps#GitOps), you may prefer to define agents statically via Ansible, or you may wish to do it dynamically via chat." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:136 +#: ../../../docs/configuring-playbook-bot-baibot.md:162 msgid "Before proceeding, we recommend reading the upstream documentation on [How to choose a provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#how-to-choose-a-provider). In short, it's probably best to go with [OpenAI](#openai)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:138 +#: ../../../docs/configuring-playbook-bot-baibot.md:164 msgid "Anthropic" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:140 +#: ../../../docs/configuring-playbook-bot-baibot.md:166 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [Anthropic provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#anthropic) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:142 -#: ../../../docs/configuring-playbook-bot-baibot.md:166 -#: ../../../docs/configuring-playbook-bot-baibot.md:197 -#: ../../../docs/configuring-playbook-bot-baibot.md:225 +#: ../../../docs/configuring-playbook-bot-baibot.md:168 +#: ../../../docs/configuring-playbook-bot-baibot.md:192 +#: ../../../docs/configuring-playbook-bot-baibot.md:223 +#: ../../../docs/configuring-playbook-bot-baibot.md:251 msgid "Here's an example **addition** to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:158 -#: ../../../docs/configuring-playbook-bot-baibot.md:189 +#: ../../../docs/configuring-playbook-bot-baibot.md:184 #: ../../../docs/configuring-playbook-bot-baibot.md:215 -#: ../../../docs/configuring-playbook-bot-baibot.md:243 +#: ../../../docs/configuring-playbook-bot-baibot.md:241 +#: ../../../docs/configuring-playbook-bot-baibot.md:275 msgid "If you'd like to use more than one model, take a look at the [Configuring additional agents (without a preset)](#configuring-additional-agents-without-a-preset) section below." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:160 -#: ../../../docs/configuring-playbook-bot-baibot.md:191 +#: ../../../docs/configuring-playbook-bot-baibot.md:186 #: ../../../docs/configuring-playbook-bot-baibot.md:217 -#: ../../../docs/configuring-playbook-bot-baibot.md:245 +#: ../../../docs/configuring-playbook-bot-baibot.md:243 +#: ../../../docs/configuring-playbook-bot-baibot.md:277 msgid "💡 You may also wish to use this new agent for [🤝 Configuring initial default handlers](#-configuring-initial-default-handlers)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:162 +#: ../../../docs/configuring-playbook-bot-baibot.md:188 msgid "Groq" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:164 +#: ../../../docs/configuring-playbook-bot-baibot.md:190 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [Groq provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#groq) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:187 +#: ../../../docs/configuring-playbook-bot-baibot.md:213 msgid "Because this is a [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agent, it will be given a `static/` ID prefix and will be named `static/groq`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:193 +#: ../../../docs/configuring-playbook-bot-baibot.md:219 msgid "Mistral" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:195 +#: ../../../docs/configuring-playbook-bot-baibot.md:221 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [🇫🇷 Mistral provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#mistral) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:213 +#: ../../../docs/configuring-playbook-bot-baibot.md:239 msgid "Because this is a [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agent, it will be given a `static/` ID prefix and will be named `static/mistral`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:219 +#: ../../../docs/configuring-playbook-bot-baibot.md:245 msgid "OpenAI" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:221 +#: ../../../docs/configuring-playbook-bot-baibot.md:247 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [OpenAI provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openai) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:223 +#: ../../../docs/configuring-playbook-bot-baibot.md:249 msgid "The OpenAI provider is **only meant to be used with OpenAI's official API** and compatibility with other services (which do not fully adhere to the OpenAI API spec completely) is limited. **If you're targeting an OpenAI-compatible service**, use the [OpenAI Compatible](#openai-compatible) provider instead." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:241 +#: ../../../docs/configuring-playbook-bot-baibot.md:273 msgid "Because this is a [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agent, it will be given a `static/` ID prefix and will be named `static/openai`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:247 +#: ../../../docs/configuring-playbook-bot-baibot.md:279 msgid "OpenAI Compatible" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:249 +#: ../../../docs/configuring-playbook-bot-baibot.md:281 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [OpenAI Compatible provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openai-compatible) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:251 +#: ../../../docs/configuring-playbook-bot-baibot.md:283 msgid "This provider allows you to use OpenAI-compatible API services like [OpenRouter](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openrouter), [Together AI](https://github.com/etkecc/baibot/blob/main/docs/providers.md#together-ai), etc." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:253 +#: ../../../docs/configuring-playbook-bot-baibot.md:285 msgid "Some of these popular services already have **shortcut** providers (see [supported providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md#supported-providers) leading to this one behind the scenes — this make it easier to get started." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:255 +#: ../../../docs/configuring-playbook-bot-baibot.md:287 msgid "As of this moment, the playbook does not include presets for any of these services, so you'll need to [Configuring additional agents (without a preset)](#configuring-additional-agents-without-a-preset)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:257 +#: ../../../docs/configuring-playbook-bot-baibot.md:289 msgid "Configuring additional agents (without a preset)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:259 +#: ../../../docs/configuring-playbook-bot-baibot.md:291 msgid "The Ansible role may be lacking preset variables for some [☁️ provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md), or you may wish to statically-define an agent on the same provider twice (or more) with different configuration." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:261 +#: ../../../docs/configuring-playbook-bot-baibot.md:293 msgid "It's possible to inject your own agent configuration using the `matrix_bot_baibot_config_agents_static_definitions_custom` Ansible variable." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:263 +#: ../../../docs/configuring-playbook-bot-baibot.md:295 msgid "You can also define providers at runtime, by chatting with the bot, so using Ansible is not a requirement." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:265 +#: ../../../docs/configuring-playbook-bot-baibot.md:297 msgid "Below is an an **example** demonstrating **statically-defining agents via Ansible without using presets**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:304 +#: ../../../docs/configuring-playbook-bot-baibot.md:336 msgid "Because these are [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agents, they will be given a `static/` ID prefix and will be named `static/my-openai-gpt-3.5-turbo-agent` and `static/my-ollama-agent`, respectively." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:306 +#: ../../../docs/configuring-playbook-bot-baibot.md:338 msgid "💡 To figure out what to put in the `config` section, refer to the [☁️ provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md) page, which contains **sample configuration YAML for each provider**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:308 +#: ../../../docs/configuring-playbook-bot-baibot.md:340 msgid "As with any [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md), defining them means they exist. To actually make use of them, they need to be configured as handlers globally or in a specific room — see [Mixing & matching models](https://github.com/etkecc/baibot/blob/main/docs/features.md#mixing--matching-models)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:310 +#: ../../../docs/configuring-playbook-bot-baibot.md:342 msgid "💡 You may also wish to use these new agents for [🤝 Configuring initial default handlers](#-configuring-initial-default-handlers)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:312 +#: ../../../docs/configuring-playbook-bot-baibot.md:344 msgid "🤝 Configuring initial default handlers" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:314 +#: ../../../docs/configuring-playbook-bot-baibot.md:346 msgid "This section is only useful if you're [🤖 Configuring agents via Ansible](#-configuring-agents-via-ansible), as it lets you put these agents to use as soon as the bot starts (by adjusting the bot's **initial global configuration**)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:316 +#: ../../../docs/configuring-playbook-bot-baibot.md:348 msgid "If you're not configuring agents via Ansible, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:318 +#: ../../../docs/configuring-playbook-bot-baibot.md:350 msgid "This section is only useful the first time around. **Once initially configured the global configuration cannot be managed Ansible**, but only via bot commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:320 +#: ../../../docs/configuring-playbook-bot-baibot.md:352 msgid "baibot supports [various purposes](https://github.com/etkecc/baibot/blob/main/docs/features.md):" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:322 +#: ../../../docs/configuring-playbook-bot-baibot.md:354 msgid "[💬 text-generation](https://github.com/etkecc/baibot/blob/main/docs/features.md#-text-generation): communicating with you via text" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:324 +#: ../../../docs/configuring-playbook-bot-baibot.md:356 msgid "[🦻 speech-to-text](https://github.com/etkecc/baibot/blob/main/docs/features.md#-speech-to-text): turning your voice messages into text" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:326 +#: ../../../docs/configuring-playbook-bot-baibot.md:358 msgid "[🗣️ text-to-speech](https://github.com/etkecc/baibot/blob/main/docs/features.md#-text-to-speech): turning bot or users text messages into voice messages" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:328 +#: ../../../docs/configuring-playbook-bot-baibot.md:360 msgid "[🖌️ image-generation](https://github.com/etkecc/baibot/blob/main/docs/features.md#-image-generation): generating images based on instructions" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:330 +#: ../../../docs/configuring-playbook-bot-baibot.md:362 msgid "❓ catch-all: special purposes, indicating use as a fallback (when no specific handler is configured)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:332 +#: ../../../docs/configuring-playbook-bot-baibot.md:364 msgid "[Mixing & matching models](https://github.com/etkecc/baibot/blob/main/docs/features.md#mixing--matching-models) is made possible by the bot's ability to have different [🤝 handlers](https://github.com/etkecc/baibot/blob/main/docs/configuration/handlers.md) configured for different purposes." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:334 +#: ../../../docs/configuring-playbook-bot-baibot.md:366 msgid "This configuration can be done as a global fallback, or per-room. Both of these [🛠️ configurations](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md) are managed at runtime (viat chat), but **the global configuration can have some initial defaults configured via Ansible**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:336 +#: ../../../docs/configuring-playbook-bot-baibot.md:368 msgid "You can configure the **initial values** for these via Ansible, via the `matrix_bot_baibot_config_initial_global_config_handler_*` variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:338 +#: ../../../docs/configuring-playbook-bot-baibot.md:370 msgid "Example **additional** `vars.yml` configuration:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:355 +#: ../../../docs/configuring-playbook-bot-baibot.md:387 msgid "**Note**: these are initial defaults for the bot's global configuration. As such, changing any of these values subsequently has no effect on the bot's behavior. **Once initially configured the global configuration cannot be managed Ansible**, but only via bot commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:357 +#: ../../../docs/configuring-playbook-bot-baibot.md:389 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:359 +#: ../../../docs/configuring-playbook-bot-baibot.md:391 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:361 +#: ../../../docs/configuring-playbook-bot-baibot.md:393 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:363 +#: ../../../docs/configuring-playbook-bot-baibot.md:395 msgid "`roles/custom/matrix-bot-baibot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:364 +#: ../../../docs/configuring-playbook-bot-baibot.md:396 msgid "`roles/custom/matrix-bot-baibot/templates/config.yaml.j2` for the bot's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_baibot_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:366 +#: ../../../docs/configuring-playbook-bot-baibot.md:398 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:368 +#: ../../../docs/configuring-playbook-bot-baibot.md:400 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:375 +#: ../../../docs/configuring-playbook-bot-baibot.md:407 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:377 -msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." +#: ../../../docs/configuring-playbook-bot-baibot.md:409 +msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account when password authentication is used." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:379 +#: ../../../docs/configuring-playbook-bot-baibot.md:411 +msgid "If you're using access-token authentication, the bot account must already exist and the configured token + device ID must match that account. This mode is mainly for MAS/OIDC setups where password-based bot login is not suitable." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:413 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:381 +#: ../../../docs/configuring-playbook-bot-baibot.md:415 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:383 -msgid "If you change the bot password (`matrix_bot_baibot_config_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_baibot_config_user_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-baibot.md:417 +msgid "If you change the bot password (`matrix_bot_baibot_config_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_baibot_config_user_password` to let the bot know its new password. (This note applies to password authentication mode.)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:385 +#: ../../../docs/configuring-playbook-bot-baibot.md:419 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:387 +#: ../../../docs/configuring-playbook-bot-baibot.md:421 msgid "To use the bot, invite it to any existing Matrix room (`/invite @baibot:example.com` where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:389 +#: ../../../docs/configuring-playbook-bot-baibot.md:423 msgid "If you're an allowed bot [👥 user](https://github.com/etkecc/baibot/blob/main/docs/access.md#user) (see [👥 Initial users configuration](#-initial-users-configuration)), the bot will accept your invitation and join the room." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:391 +#: ../../../docs/configuring-playbook-bot-baibot.md:425 msgid "After joining, the bot will introduce itself and show information about the [✨ features](https://github.com/etkecc/baibot/blob/main/docs/features.md) that are enabled for it." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:393 +#: ../../../docs/configuring-playbook-bot-baibot.md:427 msgid "If you've [🤖 configured one or more agents via Ansible](#-configuring-agents-via-ansible) and have [🤝 configured initial default handlers](#configuring-initial-default-handlers), the bot will immediately be able to make use of these agents for this new room. Otherwise, you will need to configure agents and/or handlers via chat commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:395 +#: ../../../docs/configuring-playbook-bot-baibot.md:429 msgid "Send `!bai help` to the bot in the room to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:397 +#: ../../../docs/configuring-playbook-bot-baibot.md:431 msgid "You can also refer to the upstream [baibot](https://github.com/etkecc/baibot) project's documentation." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:399 +#: ../../../docs/configuring-playbook-bot-baibot.md:433 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:401 -msgid "As with all other services, you can find service logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by running something like `journalctl -fu matrix-bot-baibot`" +#: ../../../docs/configuring-playbook-bot-baibot.md:435 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-baibot`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:403 -msgid "The default logging level for this service is `info`, but you can increase it to `debug` (or even `trace`) with the following additional configuration:" +#: ../../../docs/configuring-playbook-bot-baibot.md:437 +msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:417 +#: ../../../docs/configuring-playbook-bot-baibot.md:439 +msgid "The default logging level for this service is `info`. If you want to increase the verbosity to `debug` (or even `trace`), add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:453 msgid "**Alternatively**, you can use a single variable to set the logging level for all of the above (bot + all libraries):" msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-buscarron.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-buscarron.po index 0d5f3364d..553822c64 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-buscarron.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-buscarron.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,156 +18,156 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-buscarron.md:1 +#: ../../../docs/configuring-playbook-bot-buscarron.md:9 msgid "Setting up Buscarron (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:3 +#: ../../../docs/configuring-playbook-bot-buscarron.md:11 msgid "The playbook can install and configure [Buscarron](https://github.com/etkecc/buscarron) for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:5 +#: ../../../docs/configuring-playbook-bot-buscarron.md:13 msgid "Buscarron is bot that receives HTTP POST submissions of web forms and forwards them to a Matrix room." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:7 +#: ../../../docs/configuring-playbook-bot-buscarron.md:15 msgid "See the project's [documentation](https://github.com/etkecc/buscarron/blob/main/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:9 +#: ../../../docs/configuring-playbook-bot-buscarron.md:17 msgid "Adjusting DNS records" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:11 +#: ../../../docs/configuring-playbook-bot-buscarron.md:19 msgid "By default, this playbook installs Buscarron on the `buscarron.` subdomain (`buscarron.example.com`) and requires you to create a CNAME record for `buscarron`, which targets `matrix.example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:13 +#: ../../../docs/configuring-playbook-bot-buscarron.md:21 msgid "When setting, replace `example.com` with your own." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:15 +#: ../../../docs/configuring-playbook-bot-buscarron.md:23 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:17 +#: ../../../docs/configuring-playbook-bot-buscarron.md:25 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:40 +#: ../../../docs/configuring-playbook-bot-buscarron.md:48 msgid "Adjusting the Buscarron URL (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:42 +#: ../../../docs/configuring-playbook-bot-buscarron.md:50 msgid "By tweaking the `matrix_bot_buscarron_hostname` and `matrix_bot_buscarron_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:44 +#: ../../../docs/configuring-playbook-bot-buscarron.md:52 msgid "Example additional configuration for your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:55 +#: ../../../docs/configuring-playbook-bot-buscarron.md:63 msgid "After changing the domain, **you may need to adjust your DNS** records to point the Buscarron domain to the Matrix server." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:57 +#: ../../../docs/configuring-playbook-bot-buscarron.md:65 msgid "If you've decided to reuse the `matrix.` domain, you won't need to do any extra DNS configuration." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:59 +#: ../../../docs/configuring-playbook-bot-buscarron.md:67 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:61 +#: ../../../docs/configuring-playbook-bot-buscarron.md:69 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:63 +#: ../../../docs/configuring-playbook-bot-buscarron.md:71 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:65 +#: ../../../docs/configuring-playbook-bot-buscarron.md:73 msgid "`roles/custom/matrix-bot-buscarron/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:67 +#: ../../../docs/configuring-playbook-bot-buscarron.md:75 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:69 +#: ../../../docs/configuring-playbook-bot-buscarron.md:77 msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:76 +#: ../../../docs/configuring-playbook-bot-buscarron.md:84 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:78 +#: ../../../docs/configuring-playbook-bot-buscarron.md:86 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:80 +#: ../../../docs/configuring-playbook-bot-buscarron.md:88 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:82 +#: ../../../docs/configuring-playbook-bot-buscarron.md:90 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:84 -msgid "If you change the bot password (`matrix_bot_buscarron_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_buscarron_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-buscarron.md:92 +msgid "If you change the bot password (`matrix_bot_buscarron_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_buscarron_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:86 +#: ../../../docs/configuring-playbook-bot-buscarron.md:94 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:88 +#: ../../../docs/configuring-playbook-bot-buscarron.md:96 msgid "To use the bot, invite it to the room you specified on your `vars.yml` file (`/invite @bot.buscarron:example.com` where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:90 +#: ../../../docs/configuring-playbook-bot-buscarron.md:98 msgid "After the bot joins the room, anyone can call the web form via HTTP POST method." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:92 +#: ../../../docs/configuring-playbook-bot-buscarron.md:100 msgid "Here is an example for the `contact` form:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:100 +#: ../../../docs/configuring-playbook-bot-buscarron.md:108 msgid "**Note**: to fight against spam, Buscarron is **very aggressive when it comes to banning** and will ban you if:" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:102 +#: ../../../docs/configuring-playbook-bot-buscarron.md:110 msgid "you hit the homepage (HTTP `GET` request to `/`)" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:103 +#: ../../../docs/configuring-playbook-bot-buscarron.md:111 msgid "you submit a form to the wrong URL (`POST` request to `/non-existing-form`)" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:104 +#: ../../../docs/configuring-playbook-bot-buscarron.md:112 msgid "`hasemail` is enabled for the form (like in the example above) and you don't submit an `email` field" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:106 +#: ../../../docs/configuring-playbook-bot-buscarron.md:114 msgid "If you get banned, you'd need to restart the process by running the playbook with `--tags=start` or running `systemctl restart matrix-bot-buscarron` on the server." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:108 +#: ../../../docs/configuring-playbook-bot-buscarron.md:116 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:110 +#: ../../../docs/configuring-playbook-bot-buscarron.md:118 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-buscarron`." msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:112 +#: ../../../docs/configuring-playbook-bot-buscarron.md:120 msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bot-buscarron.md:114 +#: ../../../docs/configuring-playbook-bot-buscarron.md:122 msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-draupnir.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-draupnir.po index ca0afde4f..3e39aa69d 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-draupnir.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-draupnir.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,392 +18,421 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-draupnir.md:1 +#: ../../../docs/configuring-playbook-bot-draupnir.md:10 msgid "Setting up Draupnir (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:3 +#: ../../../docs/configuring-playbook-bot-draupnir.md:12 msgid "The playbook can install and configure the [Draupnir](https://github.com/the-draupnir-project/Draupnir) moderation bot for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:5 +#: ../../../docs/configuring-playbook-bot-draupnir.md:14 msgid "See the project's [documentation](https://the-draupnir-project.github.io/draupnir-documentation/) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:7 +#: ../../../docs/configuring-playbook-bot-draupnir.md:16 msgid "This documentation page is about installing Draupnir in bot mode. As an alternative, you can run a multi-instance Draupnir deployment by installing [Draupnir in appservice mode](./configuring-playbook-appservice-draupnir-for-all.md) (called Draupnir-for-all) instead." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:9 +#: ../../../docs/configuring-playbook-bot-draupnir.md:18 msgid "If your migrating from [Mjolnir](configuring-playbook-bot-mjolnir.md), skip to [this section](#migrating-from-mjolnir-only-required-if-migrating)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:11 +#: ../../../docs/configuring-playbook-bot-draupnir.md:20 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:13 +#: ../../../docs/configuring-playbook-bot-draupnir.md:22 msgid "Create a management room" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:15 +#: ../../../docs/configuring-playbook-bot-draupnir.md:24 msgid "Using your own account, create a new invite only room that you will use to manage the bot. This is the room where you will see the status of the bot and where you will send commands to the bot, such as the command to ban a user from another room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:17 +#: ../../../docs/configuring-playbook-bot-draupnir.md:26 msgid "[!WARNING] Anyone in this room can control the bot so it is important that you only invite trusted users to this room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:20 +#: ../../../docs/configuring-playbook-bot-draupnir.md:29 msgid "It is possible to make the management room encrypted (E2EE). If doing so, then you need to enable the native E2EE support (see [below](#native-e2ee-support))." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:22 +#: ../../../docs/configuring-playbook-bot-draupnir.md:31 msgid "Once you have created the room you need to copy the room ID so you can specify it on your `inventory/host_vars/matrix.example.com/vars.yml` file. In Element Web you can check the ID by going to the room's settings and clicking \"Advanced\". The room ID will look something like `!qporfwt:example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:24 +#: ../../../docs/configuring-playbook-bot-draupnir.md:33 msgid "End-to-End Encryption support" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:26 +#: ../../../docs/configuring-playbook-bot-draupnir.md:35 msgid "Decide whether you want to support having an encrypted management room or not. Draupnir can still protect encrypted rooms without encryption support enabled." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:28 +#: ../../../docs/configuring-playbook-bot-draupnir.md:37 msgid "Refer to Draupnir's [documentation](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#protecting-encrypted-rooms) for more details about why you might want to care about encryption support for protected rooms." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:30 +#: ../../../docs/configuring-playbook-bot-draupnir.md:39 msgid "Disable Pantalaimon for Draupnir (since v2.0.0; optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:32 +#: ../../../docs/configuring-playbook-bot-draupnir.md:41 msgid "It is known that running Draupnir along with Pantalaimon breaks all workflows that involve answering prompts with reactions." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:34 +#: ../../../docs/configuring-playbook-bot-draupnir.md:43 msgid "If you are updating Draupnir from v1.x.x and have enabled Pantalaimon for it, you can disable Pantalaimon in favor of the native E2EE support. To disable Pantalaimon, remove the configuration `matrix_bot_draupnir_pantalaimon_use: true` from your `vars.yml` file." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:36 +#: ../../../docs/configuring-playbook-bot-draupnir.md:45 msgid "**Note**: because the management room is still encrypted, disabling it without enabling the native E2EE support will break the management room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:38 +#: ../../../docs/configuring-playbook-bot-draupnir.md:47 msgid "Native E2EE support" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:40 +#: ../../../docs/configuring-playbook-bot-draupnir.md:49 msgid "To enable the native E2EE support, you need to obtain an access token for Draupnir and set it on your `vars.yml` file." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:42 +#: ../../../docs/configuring-playbook-bot-draupnir.md:51 msgid "Note that native E2EE requires a clean access token that has not touched E2EE so curl is recommended as a method to obtain it. **The access token obtained via Element Web does not work with it**. Refer to the documentation on [how to obtain an access token via curl](obtaining-access-tokens.md#obtain-an-access-token-via-curl)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:44 +#: ../../../docs/configuring-playbook-bot-draupnir.md:53 msgid "To enable the native E2EE support, add the following configuration to your `vars.yml` file. Make sure to replace `CLEAN_ACCESS_TOKEN_HERE` with the access token you obtained just now." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:55 +#: ../../../docs/configuring-playbook-bot-draupnir.md:64 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:57 +#: ../../../docs/configuring-playbook-bot-draupnir.md:66 msgid "To enable the bot, add the following configuration to your `vars.yml` file. Make sure to replace `MANAGEMENT_ROOM_ID_HERE` with the one of the room which you have created earlier." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:76 +#: ../../../docs/configuring-playbook-bot-draupnir.md:85 msgid "Create and invite the bot to the management room" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:78 +#: ../../../docs/configuring-playbook-bot-draupnir.md:87 msgid "Before proceeding to the next step, run the playbook with the following command to create the bot user." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:84 +#: ../../../docs/configuring-playbook-bot-draupnir.md:93 msgid "**Note**: the `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:86 +#: ../../../docs/configuring-playbook-bot-draupnir.md:95 msgid "Then, invite the bot (`@bot.draupnir:example.com`) to its management room which you have created earlier." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:88 +#: ../../../docs/configuring-playbook-bot-draupnir.md:97 msgid "Make sure the account is free from rate limiting (optional, recommended)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:90 +#: ../../../docs/configuring-playbook-bot-draupnir.md:99 msgid "If your homeserver's implementation is Synapse, you will need to prevent it from rate limiting the bot's account. **This is a highly recommended step. If you do not configure it, Draupnir performance will be degraded.**" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:92 +#: ../../../docs/configuring-playbook-bot-draupnir.md:101 msgid "This can be done using Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users). They can be accessed both externally and internally." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:94 +#: ../../../docs/configuring-playbook-bot-draupnir.md:103 msgid "**Note**: access to the APIs is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, doing so is not recommended for additional security. See [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:96 -msgid "The APIs can also be accessed via [Synapse Admin](https://github.com/etkecc/synapse-admin), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:105 +msgid "The APIs can also be accessed via [Ketesa](https://github.com/etkecc/ketesa), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:98 +#: ../../../docs/configuring-playbook-bot-draupnir.md:107 msgid "Add the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:100 +#: ../../../docs/configuring-playbook-bot-draupnir.md:109 msgid "To expose the APIs publicly, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:106 +#: ../../../docs/configuring-playbook-bot-draupnir.md:115 msgid "Obtain an access token for admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:108 +#: ../../../docs/configuring-playbook-bot-draupnir.md:117 msgid "Manual access to Synapse's Admin APIs requires an access token for a homeserver admin account. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:110 +#: ../../../docs/configuring-playbook-bot-draupnir.md:119 msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:113 +#: ../../../docs/configuring-playbook-bot-draupnir.md:122 msgid "Run the `curl` command" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:115 +#: ../../../docs/configuring-playbook-bot-draupnir.md:124 msgid "To disable rate limiting, run the following command on systems that ship curl. Before running it, make sure to replace:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:117 +#: ../../../docs/configuring-playbook-bot-draupnir.md:126 msgid "`ADMIN_ACCESS_TOKEN_HERE` with the access token of the admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:118 +#: ../../../docs/configuring-playbook-bot-draupnir.md:127 msgid "`example.com` with your base domain" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:119 +#: ../../../docs/configuring-playbook-bot-draupnir.md:128 msgid "`@bot.draupnir:example.com` with the MXID of your Draupnir bot user" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:125 +#: ../../../docs/configuring-playbook-bot-draupnir.md:134 +#: ../../../docs/configuring-playbook-bot-draupnir.md:207 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:126 +#: ../../../docs/configuring-playbook-bot-draupnir.md:135 msgid "This does not work on outdated Windows 10 as curl is not available there." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:127 +#: ../../../docs/configuring-playbook-bot-draupnir.md:136 msgid "Even if the APIs are not exposed to the internet, you should still be able to run the command on the homeserver locally." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:129 +#: ../../../docs/configuring-playbook-bot-draupnir.md:138 msgid "Abuse Reports" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:131 +#: ../../../docs/configuring-playbook-bot-draupnir.md:140 msgid "Draupnir can receive reports in the management room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:133 +#: ../../../docs/configuring-playbook-bot-draupnir.md:142 msgid "The bot can intercept the report API endpoint of the client-server API, which requires integration with the reverse proxy in front of the homeserver. If you are using Traefik, this playbook can set this up for you:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:145 +#: ../../../docs/configuring-playbook-bot-draupnir.md:148 +msgid "Enabling synapse-http-antispam support" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:150 +msgid "Certain protections in Draupnir require the [synapse-http-antispam](https://github.com/maunium/synapse-http-antispam) module and a Synapse homeserver plus homeserver admin status to function. This module can be enabled in the playbook via setting `matrix_bot_draupnir_config_web_synapseHTTPAntispam_enabled` to `true` and making sure that Draupnir admin API access is enabled." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:160 +msgid "These protections need to be manually activated and consulting the [enabling protections](#enabling-built-in-protections) guide can be helpful or consulting upstream documentation." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:168 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:147 +#: ../../../docs/configuring-playbook-bot-draupnir.md:170 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:149 +#: ../../../docs/configuring-playbook-bot-draupnir.md:172 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:151 +#: ../../../docs/configuring-playbook-bot-draupnir.md:174 msgid "`roles/custom/matrix-bot-draupnir/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_draupnir_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:153 +#: ../../../docs/configuring-playbook-bot-draupnir.md:176 msgid "For example, to change Draupnir's `acceptInvitesFromSpace` option to `!qporfwt:example.com`, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:167 +#: ../../../docs/configuring-playbook-bot-draupnir.md:190 msgid "Migrating from Mjolnir (Only required if migrating)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:169 +#: ../../../docs/configuring-playbook-bot-draupnir.md:192 msgid "Replace your `matrix_bot_mjolnir` config with `matrix_bot_draupnir` config. Also disable Mjolnir if you're doing migration." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:171 +#: ../../../docs/configuring-playbook-bot-draupnir.md:194 msgid "Note that Draupnir supports E2EE natively, so you can enable it instead of Pantalaimon. It is recommended to consult the instruction [here](#native-e2ee-support)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:173 +#: ../../../docs/configuring-playbook-bot-draupnir.md:196 msgid "That is all you need to do due to that Draupnir can complete migration on its own." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:175 +#: ../../../docs/configuring-playbook-bot-draupnir.md:198 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:177 +#: ../../../docs/configuring-playbook-bot-draupnir.md:200 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:184 +#: ../../../docs/configuring-playbook-bot-draupnir.md:209 +msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:211 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:186 +#: ../../../docs/configuring-playbook-bot-draupnir.md:213 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:188 +#: ../../../docs/configuring-playbook-bot-draupnir.md:215 +msgid "If you change the bot password (`matrix_bot_draupnir_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_draupnir_password` to let the bot know its new password." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:217 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:190 +#: ../../../docs/configuring-playbook-bot-draupnir.md:219 msgid "You can refer to the upstream [documentation](https://the-draupnir-project.github.io/draupnir-documentation/) for additional ways to use and configure Draupnir and for a more detailed usage guide." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:192 +#: ../../../docs/configuring-playbook-bot-draupnir.md:221 msgid "Below is a **non-exhaustive quick-start guide** for the impatient." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:194 +#: ../../../docs/configuring-playbook-bot-draupnir.md:223 msgid "Making Draupnir join and protect a room" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:196 +#: ../../../docs/configuring-playbook-bot-draupnir.md:225 msgid "Draupnir can be told to self-join public rooms, but it's better to follow this flow which works well for all kinds of rooms:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:198 +#: ../../../docs/configuring-playbook-bot-draupnir.md:227 msgid "Invite the bot to the room manually ([inviting Draupnir to rooms](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#inviting-draupnir-to-rooms)). Before joining, the bot *may* ask for confirmation in the Management Room" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:200 +#: ../../../docs/configuring-playbook-bot-draupnir.md:229 msgid "[Give the bot permissions to do its job](#giving-draupnir-permissions-to-do-its-job)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:202 +#: ../../../docs/configuring-playbook-bot-draupnir.md:231 msgid "Tell it to protect the room (using the [rooms command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#using-the-draupnir-rooms-command)) by sending the following command to the Management Room: `!draupnir rooms add !qporfwt:example.com`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:204 +#: ../../../docs/configuring-playbook-bot-draupnir.md:233 msgid "To have Draupnir provide useful room protection, you need do to a bit more work (at least the first time around). You may wish to [Subscribe to a public policy list](#subscribing-to-a-public-policy-list), [Create your own own policy and rules](#creating-your-own-policy-lists-and-rules) and [Enabling built-in protections](#enabling-built-in-protections)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:206 +#: ../../../docs/configuring-playbook-bot-draupnir.md:235 msgid "Giving Draupnir permissions to do its job" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:208 +#: ../../../docs/configuring-playbook-bot-draupnir.md:237 msgid "For Draupnir to do its job, you need to [give it permissions](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#giving-draupnir-permissions) in rooms it's protecting. This involves **giving it an Administrator power level**." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:210 +#: ../../../docs/configuring-playbook-bot-draupnir.md:239 msgid "**We recommend setting this power level as soon as the bot joins your room** (and before you create new rules), so that it can apply rules as soon as they are available. If the bot is under-privileged, it may fail to apply protections and may not retry for a while (or until your restart it)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:212 +#: ../../../docs/configuring-playbook-bot-draupnir.md:241 msgid "Subscribing to a public policy list" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:214 +#: ../../../docs/configuring-playbook-bot-draupnir.md:243 msgid "We recommend **subscribing to a public [policy list](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists)** using the [watch command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-policy-lists#using-draupnirs-watch-command-to-subscribe-to-policy-rooms)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:216 -msgid "Polcy lists are maintained in Matrix rooms. A popular policy list is maintained in the public `#community-moderation-effort-bl:neko.dev` room." +#: ../../../docs/configuring-playbook-bot-draupnir.md:245 +msgid "Policy lists are maintained in Matrix rooms. Popular ones maintained in the public are:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:218 -msgid "You can tell Draupnir to subscribe to it by sending the following command to the Management Room: `!draupnir watch #community-moderation-effort-bl:neko.dev`" +#: ../../../docs/configuring-playbook-bot-draupnir.md:247 +msgid "`#community-moderation-effort-bl:neko.dev`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:220 +#: ../../../docs/configuring-playbook-bot-draupnir.md:248 +msgid "`#huginn-muninn-active-threats:feline.support`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:250 +msgid "You can tell Draupnir to subscribe to each of these by sending the following command to the Management Room: `!draupnir watch POLICY_LIST_ADDRESS_HERE` (e.g. `!draupnir watch #community-moderation-effort-bl:neko.dev`)" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:252 msgid "Creating your own policy lists and rules" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:222 +#: ../../../docs/configuring-playbook-bot-draupnir.md:254 msgid "We also recommend **creating your own policy lists** with the [list create](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-policy-lists#using-draupnirs-list-create-command-to-create-a-policy-room) command." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:224 +#: ../../../docs/configuring-playbook-bot-draupnir.md:256 msgid "You can do so by sending the following command to the Management Room: `!draupnir list create my-bans my-bans-bl`. This will create a policy list having a name (shortcode) of `my-bans` and stored in a public `#my-bans-bl:example.com` room on your server. As soon as you run this command, the bot will invite you to the policy list room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:226 +#: ../../../docs/configuring-playbook-bot-draupnir.md:258 msgid "A policy list does nothing by itself, so the next step is **adding some rules to your policy list**. Policies target a so-called `entity` (one of: `user`, `room` or `server`). These entities are mentioned on the [policy lists](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists) documentation page and in the Matrix Spec [here](https://spec.matrix.org/v1.11/client-server-api/#mban-recommendation)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:228 +#: ../../../docs/configuring-playbook-bot-draupnir.md:260 msgid "The simplest and most useful entity to target is `user`. Below are a few examples using the [ban command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#the-ban-command) and targeting users." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:230 +#: ../../../docs/configuring-playbook-bot-draupnir.md:262 msgid "To create rules, you run commands in the Management Room (**not** in the policy list room)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:232 +#: ../../../docs/configuring-playbook-bot-draupnir.md:264 msgid "(ban a single user on a given homeserver): `!draupnir ban @charles:example.com my-bans Rude to others`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:233 -msgid "(ban all users on a given homeserver by using a [wildcard](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#wildcards)): `!draupnir ban @*:example.org my-bans Spam server - all users are fake`" +#: ../../../docs/configuring-playbook-bot-draupnir.md:265 +msgid "(ban all users on a given homeserver by using a [wildcard](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#wildcards)): `!draupnir ban @*:example.org my-bans Spam server, all users are fake`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:235 +#: ../../../docs/configuring-playbook-bot-draupnir.md:267 msgid "As a result of running these commands, you may observe:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:237 +#: ../../../docs/configuring-playbook-bot-draupnir.md:269 msgid "Draupnir creating `m.policy.rule.user` state events in the `#my-bans-bl:example.com` room on your server" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:238 +#: ../../../docs/configuring-playbook-bot-draupnir.md:270 msgid "applying these rules against all rooms that Draupnir is an Administrator in" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:240 +#: ../../../docs/configuring-playbook-bot-draupnir.md:272 msgid "You can undo bans with the [unban command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#the-unban-command)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:242 +#: ../../../docs/configuring-playbook-bot-draupnir.md:274 msgid "Enabling built-in protections" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:244 -msgid "You can also **turn on various built-in [protections](https://the-draupnir-project.github.io/draupnir-documentation/protections)** like `JoinWaveShortCircuit` (\"If X amount of users join in Y time, set the room to invite-only\")." +#: ../../../docs/configuring-playbook-bot-draupnir.md:276 +msgid "You can also **turn on various built-in [protections](https://the-draupnir-project.github.io/draupnir-documentation/protections)** like `JoinWaveShortCircuitProtection` (\"If X amount of users join in Y time, set the room to invite-only\")." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:246 +#: ../../../docs/configuring-playbook-bot-draupnir.md:278 msgid "To **see which protections are available and which are enabled**, send a `!draupnir protections` command to the Management Room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:248 -msgid "To **see the configuration options for a given protection**, send a `!draupnir protections show PROTECTION_NAME` (e.g. `!draupnir protections show JoinWaveShortCircuit`)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:280 +msgid "To [**see the configuration options for a given protection**](https://the-draupnir-project.github.io/draupnir-documentation/protections/configuring-protections#displaying-the-protection-settings), send a `!draupnir protections show PROTECTION_NAME` (e.g. `!draupnir protections show JoinWaveShortCircuitProtection`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:250 -msgid "To **set a specific option for a given protection**, send a command like this: `!draupnir config set PROTECTION_NAME.OPTION VALUE` (e.g. `!draupnir config set JoinWaveShortCircuit.timescaleMinutes 30`)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:282 +msgid "To [**set a specific option for a given protection**](https://the-draupnir-project.github.io/draupnir-documentation/protections/configuring-protections#changing-protection-settings), send a command like this: `!draupnir protections config set PROTECTION_NAME OPTION VALUE` (e.g. `!draupnir protections config set JoinWaveShortCircuitProtection timescaleMinutes 30`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:252 -msgid "To **enable a given protection**, send a command like this: `!draupnir enable PROTECTION_NAME` (e.g. `!draupnir enable JoinWaveShortCircuit`)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:284 +msgid "To [**enable a given protection**](https://the-draupnir-project.github.io/draupnir-documentation/protections/block-invitations-on-server-protection#enabling-the-protection), send a command like this: `!draupnir protections enable PROTECTION_NAME` (e.g. `!draupnir protections enable JoinWaveShortCircuitProtection`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:254 -msgid "To **disable a given protection**, send a command like this: `!draupnir disable PROTECTION_NAME` (e.g. `!draupnir disable JoinWaveShortCircuit`)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:286 +msgid "To **disable a given protection**, send a command like this: `!draupnir protections disable PROTECTION_NAME` (e.g. `!draupnir protections disable JoinWaveShortCircuitProtection`)." msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-honoroit.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-honoroit.po index 58bc343a4..8e84dad01 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-honoroit.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-honoroit.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,108 +18,140 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-honoroit.md:1 +#: ../../../docs/configuring-playbook-bot-honoroit.md:9 msgid "Setting up Honoroit (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:3 +#: ../../../docs/configuring-playbook-bot-honoroit.md:11 msgid "The playbook can install and configure [Honoroit](https://github.com/etkecc/honoroit) for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:5 +#: ../../../docs/configuring-playbook-bot-honoroit.md:13 msgid "It's a bot you can use to setup **your own helpdesk on matrix**" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:7 +#: ../../../docs/configuring-playbook-bot-honoroit.md:15 msgid "See the project's [documentation](https://github.com/etkecc/honoroit/blob/main/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:9 +#: ../../../docs/configuring-playbook-bot-honoroit.md:17 msgid "Adjusting DNS records (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:11 +#: ../../../docs/configuring-playbook-bot-honoroit.md:19 msgid "By default, this playbook installs Honoroit on the `matrix.` subdomain, at the `/honoroit` path (https://matrix.example.com/honoroit). This makes it easy to install it, because it **doesn't require additional DNS records to be set up**. If that's okay, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:13 +#: ../../../docs/configuring-playbook-bot-honoroit.md:21 msgid "If you wish to adjust it, see the section [below](#adjusting-the-honoroit-url-optional) for details about DNS configuration." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:15 +#: ../../../docs/configuring-playbook-bot-honoroit.md:23 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:17 +#: ../../../docs/configuring-playbook-bot-honoroit.md:25 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:32 +#: ../../../docs/configuring-playbook-bot-honoroit.md:40 msgid "Adjusting the Honoroit URL (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:34 +#: ../../../docs/configuring-playbook-bot-honoroit.md:42 msgid "By tweaking the `matrix_bot_honoroit_hostname` and `matrix_bot_honoroit_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:36 +#: ../../../docs/configuring-playbook-bot-honoroit.md:44 msgid "Example additional configuration for your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:44 +#: ../../../docs/configuring-playbook-bot-honoroit.md:52 msgid "If you've changed the default hostname, you may need to create a CNAME record for the Honoroit domain (`honoroit.example.com`), which targets `matrix.example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:46 +#: ../../../docs/configuring-playbook-bot-honoroit.md:54 msgid "When setting, replace `example.com` with your own." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:48 +#: ../../../docs/configuring-playbook-bot-honoroit.md:56 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:58 +msgid "There are some additional things you may wish to configure about the bot." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:60 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:62 +msgid "`roles/custom/matrix-bot-honoroit/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:64 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:50 +#: ../../../docs/configuring-playbook-bot-honoroit.md:66 msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:57 +#: ../../../docs/configuring-playbook-bot-honoroit.md:73 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:59 +#: ../../../docs/configuring-playbook-bot-honoroit.md:75 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:61 +#: ../../../docs/configuring-playbook-bot-honoroit.md:77 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:63 +#: ../../../docs/configuring-playbook-bot-honoroit.md:79 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:65 -msgid "If you change the bot password (`matrix_bot_honoroit_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_honoroit_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-honoroit.md:81 +msgid "If you change the bot password (`matrix_bot_honoroit_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_honoroit_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:67 +#: ../../../docs/configuring-playbook-bot-honoroit.md:83 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:69 +#: ../../../docs/configuring-playbook-bot-honoroit.md:85 msgid "To use the bot, invite it to the room you specified on your `vars.yml` file (`/invite @honoroit:example.com` where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:71 +#: ../../../docs/configuring-playbook-bot-honoroit.md:87 msgid "After the bot joins the room, any Matrix user can send a message to it to start a new thread in that room." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:73 +#: ../../../docs/configuring-playbook-bot-honoroit.md:89 msgid "Send `!ho help` to the bot in the room to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-honoroit.md:75 +#: ../../../docs/configuring-playbook-bot-honoroit.md:91 msgid "You can also refer to the upstream [documentation](https://github.com/etkecc/honoroit#features)." msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:93 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:95 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-honoroit`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:97 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-honoroit.md:99 +msgid "If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-matrix-registration-bot.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-matrix-registration-bot.po index b3110a4dc..c1d81c6ea 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-matrix-registration-bot.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-matrix-registration-bot.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-23 13:09+0900\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,84 +18,120 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:1 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:13 msgid "Setting up matrix-registration-bot (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:3 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:15 msgid "The playbook can install and configure [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot) for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:5 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:17 msgid "The bot allows you to easily **create and manage registration tokens** aka. invitation codes. It can be used for an invitation-based server, where you invite someone by sending them a registration token (tokens look like this: `rbalQ0zkaDSRQCOp`). They can register as per normal but have to provide a valid registration token in the final step of the registration process." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:7 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:19 msgid "See the project's [documentation](https://github.com/moan0s/matrix-registration-bot/blob/master/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:9 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:21 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:11 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:23 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:30 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:46 msgid "The bot account will be created automatically." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:32 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:48 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:50 +msgid "There are some additional things you may wish to configure about the bot." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:52 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:54 +msgid "`roles/custom/matrix-bot-matrix-registration-bot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:55 +msgid "`roles/custom/matrix-bot-matrix-registration-bot/templates/config.yaml.j2` for the bridge's default configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:57 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:34 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:59 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:41 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:66 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:43 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:68 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:45 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:70 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:47 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:72 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:49 -msgid "If you change the bot password (`matrix_bot_matrix_registration_bot_bot_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_matrix_registration_bot_bot_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:74 +msgid "If you change the bot password (`matrix_bot_matrix_registration_bot_bot_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_matrix_registration_bot_bot_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:51 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:76 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:53 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:78 msgid "To use the bot, start a chat with `@bot.matrix-registration-bot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:55 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:80 msgid "Send `help` to the bot to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:57 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:82 msgid "You can also refer to the upstream [Usage documentation](https://github.com/moan0s/matrix-registration-bot#supported-commands)." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:59 -msgid "If you have any questions, or if you need help setting it up, read the [troublshooting guide](https://github.com/moan0s/matrix-registration-bot/blob/main/docs/troubleshooting.md) or join [#matrix-registration-bot:hyteck.de](https://matrix.to/#/#matrix-registration-bot:hyteck.de)." +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:84 +msgid "If you have any questions, or if you need help setting it up, read the [troubleshooting guide](https://github.com/moan0s/matrix-registration-bot/blob/main/docs/troubleshooting.md) or join [#matrix-registration-bot:hyteck.de](https://matrix.to/#/#matrix-registration-bot:hyteck.de)." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:61 +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:86 msgid "To clean the cache (session & encryption data) after you changed the bot's username, changed the login method from access_token to password etc… you can use:" msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:92 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:94 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-matrix-registration-bot`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:96 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:98 +msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-matrix-reminder-bot.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-matrix-reminder-bot.po index 20f7e1e24..afd581d6c 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-matrix-reminder-bot.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-matrix-reminder-bot.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-23 13:09+0900\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,80 +18,116 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:1 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:9 msgid "Setting up matrix-reminder-bot (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:3 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:11 msgid "The playbook can install and configure [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot) for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:5 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:13 msgid "It's a bot you can use to **schedule one-off & recurring reminders and alarms**." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:7 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:15 msgid "See the project's [documentation](https://github.com/anoadragon453/matrix-reminder-bot/blob/master/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:9 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:17 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:11 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:19 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:26 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:34 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:36 +msgid "There are some additional things you may wish to configure about the bot." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:38 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:40 +msgid "`roles/custom/matrix-bot-matrix-reminder-bot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:41 +msgid "`roles/custom/matrix-bot-matrix-reminder-bot/templates/config.yaml.j2` for the bot's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_matrix_reminder_bot_configuration_extension_yaml` variable" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:43 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:28 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:45 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:35 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:52 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:37 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:54 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:39 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:56 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:41 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:58 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:43 -msgid "If you change the bot password (`matrix_bot_matrix_reminder_bot_matrix_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_matrix_reminder_bot_matrix_user_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:60 +msgid "If you change the bot password (`matrix_bot_matrix_reminder_bot_matrix_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_matrix_reminder_bot_matrix_user_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:45 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:62 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:47 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:64 msgid "To use the bot, start a chat with `@bot.matrix-reminder-bot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:49 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:66 msgid "You can also add the bot to any existing Matrix room (`/invite @bot.matrix-reminder-bot:example.com`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:51 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:68 msgid "Basic usage is like this: `!remindme in 2 minutes; This is a test`" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:53 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:70 msgid "Send `!help reminders` to the room to see the bot's help menu for additional commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:55 +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:72 msgid "You can also refer to the upstream [Usage documentation](https://github.com/anoadragon453/matrix-reminder-bot#usage)." msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:74 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:76 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-matrix-reminder-bot`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:78 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:80 +msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-maubot.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-maubot.po index 59ef67301..ca897756a 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-maubot.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-maubot.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,149 +18,185 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-maubot.md:1 +#: ../../../docs/configuring-playbook-bot-maubot.md:12 msgid "Setting up maubot (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:3 +#: ../../../docs/configuring-playbook-bot-maubot.md:14 msgid "The playbook can install and configure [maubot](https://github.com/maubot/maubot) for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:5 +#: ../../../docs/configuring-playbook-bot-maubot.md:16 msgid "After setting up maubot, you can use the web management interface to make it do things. The default location of the management interface is `matrix.example.com/_matrix/maubot/`" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:7 +#: ../../../docs/configuring-playbook-bot-maubot.md:18 msgid "See the project's [documentation](https://docs.mau.fi/maubot/usage/basic.html) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:9 +#: ../../../docs/configuring-playbook-bot-maubot.md:20 msgid "Adjusting DNS records (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:11 +#: ../../../docs/configuring-playbook-bot-maubot.md:22 msgid "By default, this playbook installs maubot on the `matrix.` subdomain, at the `/_matrix/maubot/` path (https://matrix.example.com/_matrix/maubot/). This makes it easy to install it, because it **doesn't require additional DNS records to be set up**." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:13 +#: ../../../docs/configuring-playbook-bot-maubot.md:24 msgid "If you wish to adjust it, see the section [below](#adjusting-the-maubot-url-optional) for details about DNS configuration." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:15 +#: ../../../docs/configuring-playbook-bot-maubot.md:26 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:17 +#: ../../../docs/configuring-playbook-bot-maubot.md:28 msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:32 +#: ../../../docs/configuring-playbook-bot-maubot.md:43 msgid "You can add multiple admins. The admin accounts are only used to access the maubot administration interface." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:34 +#: ../../../docs/configuring-playbook-bot-maubot.md:45 msgid "Adjusting the maubot URL (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:36 +#: ../../../docs/configuring-playbook-bot-maubot.md:47 msgid "By tweaking the `matrix_bot_maubot_hostname` and `matrix_bot_maubot_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:38 -#: ../../../docs/configuring-playbook-bot-maubot.md:56 +#: ../../../docs/configuring-playbook-bot-maubot.md:49 +#: ../../../docs/configuring-playbook-bot-maubot.md:76 msgid "Example additional configuration for your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:46 +#: ../../../docs/configuring-playbook-bot-maubot.md:57 msgid "If you've changed the default hostname, you may need to create a CNAME record for the maubot domain (`maubot.example.com`), which targets `matrix.example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:48 +#: ../../../docs/configuring-playbook-bot-maubot.md:59 msgid "When setting, replace `example.com` with your own." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:50 +#: ../../../docs/configuring-playbook-bot-maubot.md:61 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:63 +msgid "There are some additional things you may wish to configure about the bot." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:65 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:67 +msgid "`roles/custom/matrix-bot-maubot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:68 +msgid "`roles/custom/matrix-bot-maubot/templates/config.yaml.j2` for the bot's default configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:70 msgid "Customizing the maubot container image" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:52 +#: ../../../docs/configuring-playbook-bot-maubot.md:72 msgid "Certain [maubot plugins](https://plugins.mau.bot/) require additional dependencies to be installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:54 +#: ../../../docs/configuring-playbook-bot-maubot.md:74 msgid "You can customize the default maubot container image and install your own dependencies." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:67 +#: ../../../docs/configuring-playbook-bot-maubot.md:87 msgid "Consult the [Dockerfile reference](https://docs.docker.com/reference/dockerfile/) for more information about the syntax." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:69 +#: ../../../docs/configuring-playbook-bot-maubot.md:89 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:71 +#: ../../../docs/configuring-playbook-bot-maubot.md:91 msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:78 +#: ../../../docs/configuring-playbook-bot-maubot.md:98 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:80 +#: ../../../docs/configuring-playbook-bot-maubot.md:100 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:82 +#: ../../../docs/configuring-playbook-bot-maubot.md:102 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:84 +#: ../../../docs/configuring-playbook-bot-maubot.md:104 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:86 -msgid "If you change the bot password (`matrix_bot_maubot_initial_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_maubot_initial_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-maubot.md:106 +msgid "If you change the bot password (`matrix_bot_maubot_initial_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_maubot_initial_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:88 +#: ../../../docs/configuring-playbook-bot-maubot.md:108 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:90 +#: ../../../docs/configuring-playbook-bot-maubot.md:110 msgid "By default, you can visit `matrix.example.com/_matrix/maubot/` to manage your available plugins, clients and instances." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:92 +#: ../../../docs/configuring-playbook-bot-maubot.md:112 msgid "You should start in the following order" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:93 +#: ../../../docs/configuring-playbook-bot-maubot.md:113 msgid "**Create one or more clients**: A client is a Matrix account which the bot will use to message. By default, the playbook creates a `bot.maubot` account (as per the configuration above). You only need to [obtain an access token](#obtaining-an-access-token) for it" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:94 +#: ../../../docs/configuring-playbook-bot-maubot.md:114 msgid "**Upload some Plugins**: Plugins can be obtained from [here](https://github.com/maubot/maubot#plugins) or any other source." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:95 +#: ../../../docs/configuring-playbook-bot-maubot.md:115 msgid "**Create an instance**: An instance is the actual bot. You have to specify a client which the bot instance will use and the plugin (how the bot will behave)" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:97 +#: ../../../docs/configuring-playbook-bot-maubot.md:117 msgid "Obtain an access token" msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:99 +#: ../../../docs/configuring-playbook-bot-maubot.md:119 msgid "This can be done via `mbc login` then `mbc auth` (see the [maubot documentation](https://docs.mau.fi/maubot/usage/cli/auth.html)). To run these commands, you'll first need to `exec` into the maubot container with `docker exec -it matrix-bot-maubot sh`." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:101 +#: ../../../docs/configuring-playbook-bot-maubot.md:121 msgid "Alternatively, you can refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md). Be aware that you'd better use the **Obtain an access token via curl** method (not **Obtain an access token via Element Web**) as the latter will causes issues to your bot in encrypted rooms. Read [more](https://docs.mau.fi/maubot/usage/basic.html#creating-clients)." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:103 +#: ../../../docs/configuring-playbook-bot-maubot.md:123 msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:126 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:128 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-maubot`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:130 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-maubot.md:132 +msgid "The default logging level for this component is `WARNING`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-mjolnir.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-mjolnir.po index 0b81d8024..de08ca6f6 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-mjolnir.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bot-mjolnir.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,254 +18,266 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:1 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:12 msgid "Setting up Mjolnir (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:3 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:14 msgid "The playbook can install and configure the [Mjolnir](https://github.com/matrix-org/mjolnir) moderation bot for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:5 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:16 msgid "See the project's [documentation](https://github.com/matrix-org/mjolnir/blob/main/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:7 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:18 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:9 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:20 msgid "Register the bot account" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:11 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:22 msgid "The playbook does not automatically create users for you. You **need to register the bot user manually** before setting up the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:13 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:24 msgid "Generate a strong password for the bot. You can create one with a command like `pwgen -s 64 1`." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:15 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:26 msgid "You can use the playbook to [register a new user](registering-users.md):" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:21 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:32 msgid "If you would like Mjolnir to be able to deactivate users, move aliases, shutdown rooms, etc then it must be a server admin so you need to change `admin=no` to `admin=yes` in the command above." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:23 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:34 msgid "Obtain an access token" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:25 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:36 msgid "The bot requires an access token to be able to connect to your homeserver. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:27 -#: ../../../docs/configuring-playbook-bot-mjolnir.md:52 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:38 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:63 msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:30 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:41 msgid "Make sure the account is free from rate limiting" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:32 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:43 msgid "If your homeserver's implementation is Synapse, you will need to prevent it from rate limiting the bot's account. **This is a required step. If you do not configure it, Mjolnir will crash.**" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:34 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:45 msgid "This can be done using Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users). They can be accessed both externally and internally." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:36 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:47 msgid "**Note**: access to the APIs is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, doing so is not recommended for additional security. See [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:38 -msgid "The APIs can also be accessed via [Synapse Admin](https://github.com/etkecc/synapse-admin), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md)." +#: ../../../docs/configuring-playbook-bot-mjolnir.md:49 +msgid "The APIs can also be accessed via [Ketesa](https://github.com/etkecc/ketesa), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:40 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:51 msgid "Add the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:42 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:53 msgid "To expose the APIs publicly, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:48 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:59 msgid "Obtain an access token for admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:50 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:61 msgid "Manual access to Synapse's Admin APIs requires an access token for a homeserver admin account. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md). If you have made Mjolnir an admin, you can just use the Mjolnir token." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:55 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:66 msgid "Run the `curl` command" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:57 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:68 msgid "To disable rate limiting, run the following command on systems that ship curl. Before running it, make sure to replace:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:59 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:70 msgid "`ADMIN_ACCESS_TOKEN_HERE` with the access token of the admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:60 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:71 msgid "`example.com` with your base domain" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:61 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:72 msgid "`@bot.mjolnir:example.com` with the MXID of your Mjolnir bot user" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:67 -#: ../../../docs/configuring-playbook-bot-mjolnir.md:184 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:78 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:195 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:68 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:79 msgid "This does not work on outdated Windows 10 as curl is not available there." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:69 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:80 msgid "Even if the APIs are not exposed to the internet, you should still be able to run the command on the homeserver locally." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:71 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:82 msgid "Create a management room" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:73 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:84 msgid "Using your own account, create a new invite only room that you will use to manage the bot. This is the room where you will see the status of the bot and where you will send commands to the bot, such as the command to ban a user from another room." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:75 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:86 msgid "[!WARNING] Anyone in this room can control the bot so it is important that you only invite trusted users to this room." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:78 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:89 msgid "It is possible to make the management room encrypted (E2EE). If doing so, then you MUST enable and use Pantalaimon (see [below](#configuration-with-e2ee-support))." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:80 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:91 msgid "Once you have created the room you need to copy the room ID so you can specify it on your `vars.yml` file. In Element Web you can check the ID by going to the room's settings and clicking \"Advanced\". The room ID will look something like `!qporfwt:example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:82 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:93 msgid "Finally invite the `@bot.mjolnir:example.com` account you created earlier into the room." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:84 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:95 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:86 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:97 msgid "To enable the bot, add the following configuration to your `vars.yml` file. Make sure to replace `MANAGEMENT_ROOM_ID_HERE` with the one of the room which you have created just now." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:95 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:106 msgid "End-to-End Encryption support" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:97 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:108 msgid "Decide whether you want Mjolnir to be capable of operating in end-to-end encrypted (E2EE) rooms. This includes the management room and the moderated rooms." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:99 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:110 msgid "To support E2EE, Mjolnir needs to [use Pantalaimon](configuring-playbook-pantalaimon.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:101 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:112 msgid "Configuration with E2EE support" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:103 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:114 msgid "When using Pantalaimon, Mjolnir will log in to its bot account itself through Pantalaimon, so configure its username and password." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:105 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:116 msgid "Add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:119 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:130 msgid "The playbook's `group_vars` will configure other required settings. If using this role separately without the playbook, you also need to configure the two URLs that Mjolnir uses to reach the homeserver, one through Pantalaimon and one \"raw\". This example is taken from the playbook's `group_vars`:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:131 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:142 msgid "Configuration without E2EE support" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:133 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:144 msgid "When NOT using Pantalaimon, Mjolnir does not log in by itself and you must give it an access token for its bot account." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:135 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:146 msgid "Add the following configuration to your `vars.yml` file. Make sure to replace `ACCESS_TOKEN_HERE` with the one created [above](#obtain-an-access-token)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:141 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:152 msgid "Adding Mjolnir synapse antispam module (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:143 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:154 msgid "To enable Mjolnir synapse antispam module, add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:153 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:164 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:155 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:166 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:157 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:168 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:159 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:170 msgid "`roles/custom/matrix-bot-mjolnir/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_mjolnir_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:161 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:172 msgid "For example, to change Mjolnir's `recordIgnoredInvites` option to `true`, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:175 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:186 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:177 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:188 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:186 -msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-mjolnir.md:188 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:197 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:190 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:199 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:192 -msgid "If you change the Pantalaimon's password (`matrix_bot_mjolnir_pantalaimon_password` in your `vars.yml` file) subsequently, its credentials on the homeserver won't be updated automatically. If you'd like to change the password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_mjolnir_pantalaimon_password` to let Pantalaimon know its new password." +#: ../../../docs/configuring-playbook-bot-mjolnir.md:201 +msgid "If you change the Pantalaimon's password (`matrix_bot_mjolnir_pantalaimon_password` in your `vars.yml` file) subsequently, its credentials on the homeserver won't be updated automatically. If you'd like to change the password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_mjolnir_pantalaimon_password` to let Pantalaimon know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:194 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:203 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:196 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:205 msgid "You can refer to the upstream [documentation](https://github.com/matrix-org/mjolnir) for additional ways to use and configure Mjolnir. Check out their [quickstart guide](https://github.com/matrix-org/mjolnir#quickstart-guide) for some basic commands you can give to the bot." msgstr "" + +#: ../../../docs/configuring-playbook-bot-mjolnir.md:207 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-mjolnir.md:209 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-mjolnir`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-mjolnir.md:211 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-mjolnir.md:213 +msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bridge-postmoogle.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bridge-postmoogle.po index 3d52c8a1f..945e2a30e 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bridge-postmoogle.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-bridge-postmoogle.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,53 +18,53 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:1 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:10 msgid "Setting up Postmoogle email bridging (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:3 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:12 msgid "The playbook can install and configure [Postmoogle](https://github.com/etkecc/postmoogle) for you." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:5 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:14 msgid "Postmoogle is a bridge you can use to have its bot user forward emails to Matrix rooms. It runs an SMTP email server and allows you to assign mailbox addresses to the rooms." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:7 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:16 msgid "See the project's [documentation](https://github.com/etkecc/postmoogle/blob/master/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:9 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:18 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:11 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:20 msgid "Open the following ports on your server to be able to receive incoming emails:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:13 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:22 msgid "`25/tcp`: SMTP" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:14 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:23 msgid "`587/tcp`: Submission (TLS-encrypted SMTP)" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:16 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:25 msgid "If you don't open these ports, you will still be able to send emails, but not receive any." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:18 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:27 msgid "These port numbers are configurable via the `matrix_postmoogle_smtp_host_bind_port` and `matrix_postmoogle_submission_host_bind_port` variables, but other email servers will try to deliver on these default (standard) ports, so changing them is of little use." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:20 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:29 msgid "Adjusting DNS records" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:22 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:31 msgid "To make Postmoogle enable its email sending features, you need to configure MX and TXT (SPF, DMARC, and DKIM) records. See the table below for values which need to be specified." msgstr "" @@ -140,90 +140,94 @@ msgstr "" msgid "get it from `!pm dkim`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:31 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:40 msgid "**Note**: the DKIM record can be retrieved after configuring and installing the bridge's bot." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:33 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:42 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:35 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:44 msgid "Add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:56 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:65 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:58 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:67 msgid "There are some additional things you may wish to configure about the bridge." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:60 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:69 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:62 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:71 msgid "`roles/custom/matrix-bridge-postmoogle/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:64 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:73 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:66 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:75 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:73 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:82 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:75 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:84 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create a user account of the bridge's bot." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:77 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:86 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:79 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:88 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:81 -msgid "If you change the bridge's bot password (`matrix_postmoogle_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_postmoogle_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:90 +msgid "If you change the bridge's bot password (`matrix_postmoogle_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_postmoogle_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:83 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:92 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:85 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:94 msgid "To use the bridge, invite the `@postmoogle:example.com` bot user into a room you want to use as a mailbox." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:87 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:96 msgid "Then send `!pm mailbox NAME` to expose this Matrix room as an inbox with the email address `NAME@matrix.example.com`. Emails sent to that email address will be forwarded to the room." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:89 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:98 msgid "Send `!pm help` to the bot in the room to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:91 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:100 msgid "You can also refer to the upstream [documentation](https://github.com/etkecc/postmoogle)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:93 +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:102 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:95 -msgid "As with all other services, you can find their logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by running something like `journalctl -fu matrix-postmoogle`" +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:104 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-postmoogle`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:106 +msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bridge-postmoogle.md:97 -msgid "The default logging level for this bridge is `INFO`, but you can increase it to `DEBUG` with the following additional configuration:" +#: ../../../docs/configuring-playbook-bridge-postmoogle.md:108 +msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-element-admin.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-element-admin.po new file mode 100644 index 000000000..21b97cc55 --- /dev/null +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-element-admin.po @@ -0,0 +1,117 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community +# members +# This file is distributed under the same license as the +# matrix-docker-ansible-deploy package. +# FIRST AUTHOR , 2026. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: jp\n" +"Language-Team: jp \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" + +#: ../../../docs/configuring-playbook-element-admin.md:8 +msgid "Setting up Element Admin (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:10 +msgid "The playbook can install and configure [Element Admin](https://github.com/element-hq/element-admin) for you." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:12 +msgid "Element Admin is a web-based administration panel for Synapse and [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md)." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:14 +msgid "See the project's [documentation](https://github.com/element-hq/element-admin) to learn more." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:16 +msgid "💡 **Note**: This project is still very young and doesn't have many features. [Ketesa](./configuring-playbook-ketesa.md) is the fully-featured alternative — it covers all Synapse and MAS Admin APIs, including complete user management, session management, and MAS policy data. Element Admin remains a valid choice if you prefer its interface." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:18 +msgid "Prerequisites" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:20 +msgid "A [Synapse](configuring-playbook-synapse.md) homeserver with its Admin API enabled (the playbook automatically enables it for you when you enable Element Admin)" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:21 +msgid "[Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) with its Admin API enabled (the playbook automatically enables it for you when you enable Element Admin)" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:23 +msgid "Decide on a domain and path" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:25 +msgid "By default, the Element Admin is configured to be served on the `admin.element.example.com` domain." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:27 +msgid "If you'd like to run Element Admin on another hostname, see the [Adjusting the Element Admin URL](#adjusting-the-element-admin-url-optional) section below." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:29 +msgid "Adjusting DNS records (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:31 +msgid "By default, this playbook installs Element Admin on the `admin.element.` subdomain (`admin.element.example.com`) and requires you to create a `CNAME` record for `admin.element`, which targets `matrix.example.com`." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:33 +msgid "When setting these values, replace `example.com` with your own." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:35 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:37 +msgid "Add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:43 +msgid "Adjusting the Element Admin URL (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:45 +msgid "By tweaking the `matrix_element_admin_hostname` variable, you can easily make the service available at a **different hostname** than the default one." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:47 +msgid "Example additional configuration for your `vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:53 +msgid "[!WARNING] A `matrix_element_admin_path_prefix` variable is also available and mean to let you configure a path prefix for the Element Admin service, but **Element Admin does not support running under a sub-path yet**." +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:56 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:58 +msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:65 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-element-admin.md:67 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-ketesa.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-ketesa.po new file mode 100644 index 000000000..4289059a3 --- /dev/null +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-ketesa.po @@ -0,0 +1,165 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community +# members +# This file is distributed under the same license as the +# matrix-docker-ansible-deploy package. +# FIRST AUTHOR , 2026. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-04-03 12:02+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: jp\n" +"Language-Team: jp \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.18.0\n" + +#: ../../../docs/configuring-playbook-ketesa.md:14 +msgid "Setting up Ketesa (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:16 +msgid "The playbook can install and configure [Ketesa](https://github.com/etkecc/ketesa) for you." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:18 +msgid "Ketesa is a fully-featured admin interface for Matrix homeservers — manage users, rooms, media, sessions, and more from one clean, responsive web UI. It is the evolution of [Awesome-Technologies/synapse-admin](https://github.com/Awesome-Technologies/synapse-admin): what began as a fork has grown into its own independent project with a redesigned interface, comprehensive Synapse and MAS API coverage, and multi-language support." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:20 +msgid "[!NOTE]" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:22 +msgid "Ketesa does not work with other homeserver implementations than Synapse due to API's incompatibility." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:23 +msgid "The latest version of Ketesa is hosted by [etke.cc](https://etke.cc/) at [admin.etke.cc](https://admin.etke.cc/). If you only need this service occasionally and trust giving your admin credentials to a 3rd party Single Page Application, you can consider using it from there and avoiding the (small) overhead of self-hosting." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:24 +msgid "This playbook also supports an alternative management UI in the shape of [Element Admin](./configuring-playbook-element-admin.md). Please note that it's currently less feature-rich than Ketesa and requires [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md)." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:26 +msgid "Adjusting DNS records (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:28 +msgid "By default, this playbook installs Ketesa on the `matrix.` subdomain, at the `/synapse-admin` path (https://matrix.example.com/synapse-admin) — the legacy path is kept for backward compatibility. This makes it easy to install it, because it **doesn't require additional DNS records to be set up**. If that's okay, you can skip this section." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:30 +msgid "If you wish to adjust it, see the section [below](#adjusting-the-ketesa-url-optional) for details about DNS configuration." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:32 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:34 +msgid "To enable Ketesa, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:40 +msgid "**Note**: Ketesa requires Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/usage/administration/admin_api/index.html) to function. Access to them is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, for additional security, we normally leave them unexposed, following [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints). Because Ketesa needs these APIs to function, when installing Ketesa, the playbook **automatically** exposes the Synapse Admin API publicly for you. Depending on the homeserver implementation you're using (Synapse, Dendrite), this is equivalent to:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:42 +msgid "for [Synapse](./configuring-playbook-synapse.md) (our default homeserver implementation): `matrix_synapse_container_labels_public_client_synapse_admin_api_enabled: true`" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:43 +msgid "for [Dendrite](./configuring-playbook-dendrite.md): `matrix_dendrite_container_labels_public_client_synapse_admin_api_enabled: true`" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:45 +msgid "By default, Ketesa installation will be [restricted to only work with one homeserver](https://github.com/etkecc/ketesa/blob/main/README.md#restricting-available-homeserver) — the one managed by the playbook. To adjust these restrictions, tweak the `matrix_ketesa_config_restrictBaseUrl` variable." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:47 +msgid "Adjusting the Ketesa URL (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:49 +msgid "By tweaking the `matrix_ketesa_hostname` and `matrix_ketesa_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:51 +msgid "We recommend updating the path prefix to `/ketesa` to align with the new branding, while the default `/synapse-admin` is kept for backward compatibility:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:57 +msgid "Or to change the hostname entirely:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:65 +msgid "If you've changed the default hostname, you may need to create a CNAME record for the Ketesa domain (`admin.example.com`), which targets `matrix.example.com`." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:67 +msgid "When setting, replace `example.com` with your own." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:69 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:71 +msgid "There are some additional things you may wish to configure about the component." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:73 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:75 +msgid "`roles/custom/matrix-ketesa/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_ketesa_configuration_extension_json` variable" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:77 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:79 +msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:86 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:88 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:90 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:92 +msgid "After installation, Ketesa will be accessible at: `https://matrix.example.com/synapse-admin/` (or `/ketesa/` if you updated the path prefix as recommended)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:94 +msgid "To use Ketesa, you need to have [registered at least one administrator account](registering-users.md) on your server." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:96 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:98 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-ketesa`." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:100 +msgid "If you have questions, you can join this community room and feel free to ask: [#ketesa:etke.cc](https://matrix.to/#/#ketesa:etke.cc)" +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-matrix-authentication-service.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-matrix-authentication-service.po index 84baf5f02..d3f280c39 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-matrix-authentication-service.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-matrix-authentication-service.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,150 +18,134 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:1 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:8 msgid "Setting up Matrix Authentication Service (optional)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:3 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:10 msgid "The playbook can install and configure [Matrix Authentication Service](https://github.com/element-hq/matrix-authentication-service/) (MAS) — a service operating alongside your existing [Synapse](./configuring-playbook-synapse.md) homeserver and providing [better authentication, session management and permissions in Matrix](https://matrix.org/blog/2023/09/better-auth/)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:5 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:12 msgid "Matrix Authentication Service is an implementation of [MSC3861: Next-generation auth for Matrix, based on OAuth 2.0/OIDC](https://github.com/matrix-org/matrix-spec-proposals/pull/3861) and still work in progress, tracked at the [areweoidcyet.com](https://areweoidcyet.com/) website." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:7 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:14 msgid "**Before going through with starting to use Matrix Authentication Service**, make sure to read:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:9 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:16 msgid "the [Reasons to use Matrix Authentication Service](#reasons-to-use-matrix-authentication-service) section below" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:10 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:17 msgid "the [Expectations](#expectations) section below" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:11 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:18 msgid "the [FAQ section on areweoidcyet.com](https://areweoidcyet.com/#faqs)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:13 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:20 msgid "**If you've already been using Synapse** and have user accounts in its database, you can [migrate to Matrix Authentication Service](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:15 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:22 msgid "Reasons to use Matrix Authentication Service" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:17 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:24 msgid "You may be wondering whether you should make the switch to Matrix Authentication Service (MAS) or keep using your existing authentication flow via Synapse (password-based or [OIDC](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on)-enabled)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:19 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:26 msgid "Matrix Authentication Service is **still an experimental service** and **not a default** for this Ansible playbook." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:21 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:28 msgid "The [Expectations](#expectations) section contains a list of what works and what doesn't (**some services don't work with MAS yet**), as well as the **relative irreversability** of the migration process." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:23 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:30 msgid "Below, we'll try to **highlight some potential reasons for switching** to Matrix Authentication Service:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:25 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:32 msgid "To use SSO in [Element X](https://element.io/blog/element-x-ignition/). The old [Synapse OIDC](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on) login flow is only supported in old Element clients and will not be supported in Element X. Element X will only support the new SSO-based login flow provided by MAS, so if you want to use SSO with Element X, you will need to switch to MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:27 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:34 msgid "To help drive adoption of the \"Next-generation auth for Matrix\" by switching to what's ultimately coming anyway" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:29 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:36 msgid "To help discover (and potentially fix) MAS integration issues with this Ansible playbook" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:31 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:38 msgid "To help discover (and potentially fix) MAS integration issues with various other Matrix components (bridges, bots, clients, etc.)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:33 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:40 msgid "To reap some of the security benefits that Matrix Authentication Service offers, as outlined in the [Better authentication, session management and permissions in Matrix](https://matrix.org/blog/2023/09/better-auth/) article." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:35 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:42 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:37 -msgid "⚠️ the [Synapse](configuring-playbook-synapse.md) homeserver implementation (which is the default for this playbook). Other homeserver implementations ([Dendrite](./configuring-playbook-dendrite.md), [Conduit](./configuring-playbook-conduit.md), etc.) do not support integrating wtih Matrix Authentication Service yet." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:44 +msgid "⚠️ the [Synapse](configuring-playbook-synapse.md) homeserver implementation (which is the default for this playbook). Other homeserver implementations ([Dendrite](./configuring-playbook-dendrite.md), [Conduit](./configuring-playbook-conduit.md), etc.) do not support integrating with Matrix Authentication Service yet." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:39 -msgid "⚠️ **email sending** configured (see [Adjusting email-sending settings](./configuring-playbook-email.md)), because **Matrix Authentication Service [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user** going through the new SSO-based login flow. It's also possible to [work around email deliverability issues](#working-around-email-deliverability-issues) if your email configuration is not working." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:41 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:46 msgid "❌ **disabling all password providers** for Synapse (things like [shared-secret-auth](./configuring-playbook-shared-secret-auth.md), [rest-auth](./configuring-playbook-rest-auth.md), [LDAP auth](./configuring-playbook-ldap-auth.md), etc.) More details about this are available in the [Expectations](#expectations) section below." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:43 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:48 msgid "Expectations" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:45 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:50 msgid "This section details what you can expect when switching to the Matrix Authentication Service (MAS)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:47 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:52 msgid "❌ **Synapse password providers will need to be disabled**. You can no longer use [shared-secret-auth](./configuring-playbook-shared-secret-auth.md), [rest-auth](./configuring-playbook-rest-auth.md), [LDAP auth](./configuring-playbook-ldap-auth.md), etc. When the authentication flow is handled by MAS (not by Synapse anymore), it doesn't make sense to extend the Synapse authentication flow with additional modules. Many bridges used to rely on shared-secret-auth for doing double-puppeting (impersonating other users), but most (at least the mautrix bridges) nowadays use [Appservice Double Puppet](./configuring-playbook-appservice-double-puppet.md) as a better alternative. Older/maintained bridges may still rely on shared-secret-auth, as do other services like [matrix-corporal](./configuring-playbook-matrix-corporal.md)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:49 -msgid "❌ Certain **tools like [synapse-admin](./configuring-playbook-synapse-admin.md) do not have full compatibility with MAS yet**. synapse-admin already supports [login with access token](https://github.com/etkecc/synapse-admin/pull/58), browsing users (which Synapse will internally fetch from MAS) and updating user avatars. However, editing users (passwords, etc.) now needs to happen directly against MAS using the [MAS Admin API](https://element-hq.github.io/matrix-authentication-service/api/index.html), which synapse-admin cannot interact with yet." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:54 +msgid "✅ **[Ketesa](./configuring-playbook-ketesa.md) has full MAS integration**. Ketesa supports OIDC auth, user management, all session types (browser, OAuth2, compatibility), linked email addresses, upstream OAuth provider links, MAS policy data, and user creation through MAS. It is the recommended tool for managing homeservers running MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:51 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:56 msgid "❌ **Some services experience issues when authenticating via MAS**:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:53 -msgid "[Postmoogle](./configuring-playbook-bridge-postmoogle.md) works the first time around, but it consistently fails after restarting:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:55 -msgid "cannot initialize matrix bot error=\"olm account is marked as shared, keys seem to have disappeared from the server\"" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:57 -msgid "[matrix-reminder-bot](./configuring-playbook-bot-matrix-reminder-bot.md) fails to start (see [element-hq/matrix-authentication-service#3439](https://github.com/element-hq/matrix-authentication-service/issues/3439))" -msgstr "" - #: ../../../docs/configuring-playbook-matrix-authentication-service.md:58 -msgid "Other services may be similarly affected. This list is not exhaustive." +msgid "[Reminder bot](configuring-playbook-bot-matrix-reminder-bot.md) seems to be losing some of its state on each restart and may reschedule old reminders once again" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:60 -msgid "❌ **Encrypted appservices** do not work yet (related to [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190) and [PR 17705 for Synapse](https://github.com/element-hq/synapse/pull/17705)), so all bridges/bots that rely on encryption will fail to start (see [this issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3658) for Hookshot). You can use these bridges/bots only if you **keep end-to-bridge encryption disabled** (which is the default setting)." +msgid "[Postmoogle](./configuring-playbook-bridge-postmoogle.md) works the first time around, but it consistently fails after restarting:" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:62 -msgid "⚠️ **You will need to have email sending configured** (see [Adjusting email-sending settings](./configuring-playbook-email.md)), because **Matrix Authentication Service [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user** going through the new SSO-based login flow. It's also possible to [work around email deliverability issues](#working-around-email-deliverability-issues) if your email configuration is not working." +msgid "cannot initialize matrix bot error=\"olm account is marked as shared, keys seem to have disappeared from the server\"" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:64 -msgid "⚠️ [Migrating an existing Synapse homeserver to Matrix Authentication Service](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) is **possible**, but requires **some playbook-assisted manual work**. Migration is **reversible with no or minor issues if done quickly enough**, but as users start logging in (creating new login sessions) via the new MAS setup, disabling MAS and reverting back to the Synapse user database will cause these new sessions to break." +msgid "❌ **Encrypted appservices** do not work yet (related to [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190) and [PR 17705 for Synapse](https://github.com/element-hq/synapse/pull/17705)), so all bridges/bots that rely on encryption will fail to start (see [this issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3658) for Hookshot). You can use these bridges/bots only if you **keep end-to-bridge encryption disabled** (which is the default setting)." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:66 -msgid "⚠️ [Migrating an existing Synapse homeserver to Matrix Authentication Service](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) does not currently seem to preserve the \"admin\" flag for users (as found in the Synapse database). All users are imported as non-admin — see [element-hq/matrix-authentication-service#3440](https://github.com/element-hq/matrix-authentication-service/issues/3440). You may need update the Matrix Authentication Service's database manually and adjust the `can_request_admin` column in the `users` table to `true` for users that need to be administrators (e.g. `UPDATE users SET can_request_admin = true WHERE username = 'someone';`)" +msgid "⚠️ [Migrating an existing Synapse homeserver to Matrix Authentication Service](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) is **possible**, but requires **some playbook-assisted manual work**. Migration is **reversible with no or minor issues if done quickly enough**, but as users start logging in (creating new login sessions) via the new MAS setup, disabling MAS and reverting back to the Synapse user database will cause these new sessions to break." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:68 -msgid "⚠️ Delegating user authentication to MAS causes **your Synapse server to be completely dependant on one more service** for its operations. MAS is quick & lightweight and should be stable enough already, but this is something to keep in mind when making the switch." +msgid "⚠️ Delegating user authentication to MAS causes **your Synapse server to be completely dependent on one more service** for its operations. MAS is quick & lightweight and should be stable enough already, but this is something to keep in mind when making the switch." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:70 @@ -181,7 +165,7 @@ msgid "✅ Various clients ([Cinny](./configuring-playbook-client-cinny.md), [El msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:78 -msgid "✅ The **old login flow** (called `m.login.password`) **will still continue to work**, so clients (old Element Web, etc.) and bridges/bots that don't support the new OIDC-based login flow will still work. Going through the old login flow does not require users to have a verified email address, as [is the case](https://github.com/element-hq/matrix-authentication-service/issues/1505) for the new SSO-based login flow." +msgid "✅ The **old login flow** (called `m.login.password`) **will still continue to work**, so clients (old Element Web, etc.) and bridges/bots that don't support the new OIDC-based login flow will still work" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:80 @@ -209,7 +193,7 @@ msgid "Existing homeserver" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:92 -msgid "Other homeserver implementations ([Dendrite](./configuring-playbook-dendrite.md), [Conduit](./configuring-playbook-conduit.md), etc.) do not support integrating wtih Matrix Authentication Service yet." +msgid "Other homeserver implementations ([Dendrite](./configuring-playbook-dendrite.md), [Conduit](./configuring-playbook-conduit.md), etc.) do not support integrating with Matrix Authentication Service yet." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:94 @@ -297,326 +281,346 @@ msgstr "" msgid "The playbook exposes a `matrix_authentication_service_config_upstream_oauth2_providers` variable for controlling this setting." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:269 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:273 msgid "💡 Refer to the [`upstream_oauth2.providers` setting](https://element-hq.github.io/matrix-authentication-service/reference/configuration.html#upstream_oauth2providers) for the most up-to-date schema and example for providers. The value shown above here may be out of date." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:271 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:275 msgid "⚠️ The syntax for existing [OIDC providers configured in Synapse](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on) is slightly different, so you will need to adjust your configuration when switching from Synapse OIDC to MAS upstream OAuth2." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:273 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:277 msgid "⚠️ When [migrating an existing homeserver](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) which contains OIDC-sourced users, you will need to:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:275 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:279 msgid "[Configure upstream OIDC provider mapping for syn2mas](#configuring-upstream-oidc-provider-mapping-for-syn2mas)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:276 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:280 msgid "go through the [migrating an existing homeserver](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) process" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:277 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:281 msgid "remove all Synapse OIDC-related configuration (`matrix_synapse_oidc_*`) to prevent it being in conflict with the MAS OIDC configuration" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:279 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:283 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:285 +msgid "There are some additional things you may wish to configure about the component." +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:287 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:289 +msgid "`roles/custom/matrix-authentication-service/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:290 +msgid "`roles/custom/matrix-authentication-service/templates/config.yaml.j2` for the component's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_authentication_service_configuration_extension_yaml` variable" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:292 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:281 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:294 msgid "Now that you've [adjusted the playbook configuration](#adjusting-the-playbook-configuration) and [your DNS records](#adjusting-dns-records), you can run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:288 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:301 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:290 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:303 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:292 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:305 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:294 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:307 msgid "If you're in the process of migrating an existing Synapse homeserver to MAS, you should now follow the rest of the steps in the [Migrating an existing Synapse homeserver to Matrix Authentication Service](#migrating-an-existing-synapse-homeserver-to-matrix-authentication-service) guide." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:296 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:309 msgid "💡 After installation, you should [verify that Matrix Authentication Service is installed correctly](#verify-that-matrix-authentication-service-is-installed-correctly)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:298 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:311 msgid "Migrating an existing Synapse homeserver to Matrix Authentication Service" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:300 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:313 msgid "Our migration guide is loosely based on the upstream [Migrating an existing homeserver](https://element-hq.github.io/matrix-authentication-service/setup/migration.html) guide." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:302 -msgid "Migration is done via a tool called `syn2mas`, which the playbook could run for you (in a container)." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:315 +msgid "Migration is done via a sub-command called `syn2mas`, which the playbook could run for you (in a container)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:304 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:317 msgid "The installation + migration steps are like this:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:306 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:319 msgid "[Adjust your configuration](#adjusting-the-playbook-configuration) to **disable the integration between the homeserver and MAS**. This is done by **uncommenting** the `matrix_authentication_service_migration_in_progress: true` line." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:308 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:321 msgid "Perform the initial [installation](#installing). At this point:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:310 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:323 msgid "Matrix Authentication Service will be installed. Its database will be empty, so it cannot validate existing access tokens or authentication users yet." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:312 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:325 msgid "The homeserver will still continue to use its local database for validating existing access tokens." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:314 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:327 msgid "Various [compatibility layer URLs](https://element-hq.github.io/matrix-authentication-service/setup/homeserver.html#set-up-the-compatibility-layer) are not yet installed. New login sessions will still be forwarded to the homeserver, which is capable of completing them." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:316 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:329 msgid "The `matrix-user-creator` role would be suppressed, so that it doesn't automatically attempt to create users (for bots, etc.) in the MAS database. These user accounts likely already exist in Synapse's user database and could be migrated over (via syn2mas, as per the steps below), so creating them in the MAS database would have been unnecessary and potentially problematic (conflicts during the syn2mas migration)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:318 -msgid "Consider taking a full [backup of your Postgres database](./maintenance-postgres.md#backing-up-postgresql). This is done just in case. The **syn2mas migration tool does not delete any data**, so it should be possible to revert to your previous setup by merely disabling MAS and re-running the playbook (no need to restore a Postgres backup). However, do note that as users start logging in (creating new login sessions) via the new MAS setup, disabling MAS and reverting back to the Synapse user database will cause these new sessions to break." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:331 +msgid "Consider taking a full [backup of your Postgres database](./maintenance-postgres.md#backing-up-postgresql). This is done just in case. The **syn2mas migration command does not delete any data**, so it should be possible to revert to your previous setup by merely disabling MAS and re-running the playbook (no need to restore a Postgres backup). However, do note that as users start logging in (creating new login sessions) via the new MAS setup, disabling MAS and reverting back to the Synapse user database will cause these new sessions to break." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:320 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:333 msgid "[Migrate your data from Synapse to Matrix Authentication Service using syn2mas](#migrate-your-data-from-synapse-to-matrix-authentication-service-using-syn2mas)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:322 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:335 msgid "[Adjust your configuration](#adjusting-the-playbook-configuration) again, to:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:324 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:337 msgid "remove the `matrix_authentication_service_migration_in_progress: false` line" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:326 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:339 msgid "if you had been using [OIDC providers configured in Synapse](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on), remove all Synapse OIDC-related configuration (`matrix_synapse_oidc_*`) to prevent it being in conflict with the MAS OIDC configuration" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:328 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:341 msgid "Perform the [installation](#installing) again. At this point:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:330 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:343 msgid "The homeserver will start delegating authentication to MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:332 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:345 msgid "The compatibility layer URLs will be installed. New login sessions will be completed by MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:334 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:347 msgid "[Verify that Matrix Authentication Service is installed correctly](#verify-that-matrix-authentication-service-is-installed-correctly)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:336 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:349 msgid "Migrate your data from Synapse to Matrix Authentication Service using syn2mas" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:338 -msgid "We **don't** ask you to [run the `syn2mas` migration advisor command](https://element-hq.github.io/matrix-authentication-service/setup/migration.html#run-the-migration-advisor), because it only gives you the green light if your Synapse configuration (`homeserver.yaml`) is configured in a way that's compatible with MAS (delegating authentication to MAS; disabling Synapse's password config; etc.). Until we migrate your data with the `syn2mas` tool, we intentionally avoid doing these changes to allow existing user sessions to work." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:340 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:351 msgid "You can invoke the `syn2mas` tool via the playbook by running the playbook's `matrix-authentication-service-mas-cli-syn2mas` tag. We recommend first doing a [dry-run](#performing-a-syn2mas-dry-run) and then a [real migration](#performing-a-real-syn2mas-migration)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:342 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:353 msgid "Configuring syn2mas" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:344 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:355 msgid "If you're using [OIDC with Synapse](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on), you will need to [Configuring upstream OIDC provider mapping for syn2mas](#configuring-upstream-oidc-provider-mapping-for-syn2mas)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:346 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:357 msgid "If you only have local (non-OIDC) users in your Synapse database, you can likely run `syn2mas` as-is (without doing additional configuration changes)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:348 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:359 msgid "When you're done with potentially configuring `syn2mas`, proceed to doing a [dry-run](#performing-a-syn2mas-dry-run) and then a [real migration](#performing-a-real-syn2mas-migration)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:350 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:361 msgid "Configuring upstream OIDC provider mapping for syn2mas" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:352 -msgid "If you have existing OIDC users in your Synapse user database (which will be the case if when using [OIDC with Synapse](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on)), you may need to pass an additional `--upstreamProviderMapping` argument to the `syn2mas` tool to tell it which provider (on the Synapse side) maps to which other provider on the MAS side." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:354 -msgid "If you don't do this, `syn2mas` would report errors like this one:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:356 -msgid "[FATAL] migrate - [Failed to import external id 4264b0f0-4f11-4ddd-aedb-b500e4d07c25 with oidc-keycloak for user @alice:example.com: Error: Unknown upstream provider oidc-keycloak]" +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:363 +msgid "Since Matrix Authentication Service v0.16.0 (which replaced the standalone `syn2mas` tool with a `mas-cli syn2mas` sub-command), OIDC configuration (mapping from your old OIDC configuration to your new one, etc) is meant to be configured in the Matrix Authentication Service configuration (via `matrix_authentication_service_config_upstream_oauth2_providers`) as a `synapse_idp_id` property for each provider." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:358 -msgid "Below is an example situation and a guide for how to solve it." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:365 +msgid "You can refer to the [Map any upstream SSO providers](https://element-hq.github.io/matrix-authentication-service/setup/migration.html#map-any-upstream-sso-providers) section of the MAS documentation for figuring out how to set the `synapse_idp_id` value in `matrix_authentication_service_config_upstream_oauth2_providers` correctly." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:360 -msgid "If in `matrix_synapse_oidc_providers` your provider `idp_id` is (was) named `keycloak`, in the Synapse database users would be associated with the `oidc-keycloak` provider (note the `oidc-` prefix that was added automatically by Synapse to your `idp_id` value)." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:362 -msgid "The same OIDC provider may have an `id` of `01HFVBY12TMNTYTBV8W921M5FA` on the MAS side, as defined in `matrix_authentication_service_config_upstream_oauth2_providers` (see the [Upstream OAuth2 configuration](#upstream-oauth2-configuration) section above)." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:364 -msgid "To tell `syn2mas` how the Synapse-configured OIDC provider maps to the new MAS-configured OIDC provider, add this additional configuration to your `vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:373 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:367 msgid "Performing a syn2mas dry-run" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:375 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:369 msgid "Having [configured syn2mas](#configuring-syn2mas), we recommend doing a [dry-run](https://en.wikipedia.org/wiki/Dry_run_(testing)) first to verify that everything will work out as expected." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:377 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:371 msgid "A dry-run would not cause downtime, because it avoids stopping Synapse." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:379 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:373 msgid "To perform a dry-run, run:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:385 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:379 msgid "Observe the command output (especially the last line of the the syn2mas output). If you are confident that the migration will work out as expected, you can proceed with a [real migration](#performing-a-real-syn2mas-migration)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:387 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:381 msgid "Performing a real syn2mas migration" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:389 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:383 msgid "Before performing a real migration make sure:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:391 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:385 msgid "you've familiarized yourself with the [expectations](#expectations)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:393 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:387 msgid "you've performed a Postgres backup, just in case" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:395 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:389 msgid "you're aware of the irreversibility of the migration process without disruption after users have created new login sessions via the new MAS setup" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:397 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:391 msgid "you've [configured syn2mas](#configuring-syn2mas), especially if you've used [OIDC with Synapse](./configuring-playbook-synapse.md#synapse--openid-connect-for-single-sign-on)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:399 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:393 msgid "you've performed a [syn2mas dry-run](#performing-a-syn2mas-dry-run) and don't see any issues in its output" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:401 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:395 msgid "To perform a real migration, run the `matrix-authentication-service-mas-cli-syn2mas` tag **without** the `matrix_authentication_service_syn2mas_migrate_dry_run` variable:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:407 -msgid "Having performed a `syn2mas` migration once, trying to do it again will report errors for users that were already migrated (e.g. \"Error: Unknown upstream provider oauth-delegated\")." +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:401 +msgid "After `syn2mas` completes, Synapse will intentionally remain stopped to avoid new registrations or other authentication changes from being accepted before the migration is completed. Continue with the next steps in this guide before re-running the installation." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:409 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:403 +msgid "Having performed a `syn2mas` migration once, trying to do it again will report errors (e.g. \"Error: The MAS database is not empty: rows found in at least `users`. Please drop and recreate the database, then try again.\")." +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:405 msgid "Verify that Matrix Authentication Service is installed correctly" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:411 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:407 msgid "After [installation](#installing), run the `doctor` subcommand of the [`mas-cli` command-line tool](https://element-hq.github.io/matrix-authentication-service/reference/cli/index.html) to verify that MAS is installed correctly." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:413 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:409 msgid "You can do it:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:415 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:411 msgid "either via the Ansible playbook's `matrix-authentication-service-mas-cli-doctor` tag: `just run-tags matrix-authentication-service-mas-cli-doctor`" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:417 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:413 msgid "or by running the `mas-cli` script on the server (which invokes the `mas-cli` tool inside a container): `/matrix/matrix-authentication-service/bin/mas-cli doctor`" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:419 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:415 msgid "If successful, you should see some output that looks like this:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:431 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:427 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:429 msgid "Management" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:433 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:431 msgid "You can use the [`mas-cli` command-line tool](https://element-hq.github.io/matrix-authentication-service/reference/cli/index.html) (exposed via the `/matrix/matrix-authentication-service/bin/mas-cli` script) to perform administrative tasks against MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:435 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:433 msgid "This documentation page already mentions:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:437 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:435 msgid "the `mas-cli doctor` sub-command in the [Verify that Matrix Authentication Service is installed correctly](#verify-that-matrix-authentication-service-is-installed-correctly) section, which you can run via the CLI and via the Ansible playbook's `matrix-authentication-service-mas-cli-doctor` tag" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:439 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:437 msgid "the `mas-cli manage register-user` sub-command in the [Registering users](./registering-users.md) documentation" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:441 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:439 msgid "There are other sub-commands available. Run `/matrix/matrix-authentication-service/bin/mas-cli` to get an overview." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:443 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:441 msgid "User registration" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:445 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:443 msgid "After Matrix Authentication Service is [installed](#installing), users need to be managed there (unless you're managing them in an [upstream OAuth2 provider](#upstream-oauth2-configuration))." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:447 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:445 msgid "You can register users new users as described in the [Registering users](./registering-users.md) documentation (via `mas-cli manage register-user` or the Ansible playbook's `register-user` tag)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:449 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:447 msgid "Working around email deliverability issues" msgstr "" +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:449 +msgid "Matrix Authentication Service only sends emails when:" +msgstr "" + #: ../../../docs/configuring-playbook-matrix-authentication-service.md:451 -msgid "Because Matrix Authentication Service [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user, you may need to work around email deliverability issues if [your email-sending configuration](./configuring-playbook-email.md) is not working." +msgid "it verifies email addresses for users who are self-registering with a password" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:453 -msgid "Matrix Authentication Service attempts to verify email addresses by sending a verification email to the address specified by the user whenever they log in to an account without a verified email address." +msgid "a user tries to add an email to their account" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:455 -msgid "If email delivery is not working, **you can retrieve the email configuration code from the Matrix Authentication Service's logs** (`journalctl -fu matrix-authentication-service`)." +msgid "If Matrix Authentication Service tries to send an email and it fails because [your email-sending configuration](./configuring-playbook-email.md) is not working, you may need to work around email deliverability." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:457 +msgid "If email delivery is not working, **you can retrieve the email verification code from the Matrix Authentication Service's logs** (`journalctl -fu matrix-authentication-service`)." +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:459 msgid "Alternatively, you can use the [`mas-cli` management tool](#management) to manually verify email addresses for users. Example: `/matrix/matrix-authentication-service/bin/mas-cli manage verify-email some.username email@example.com`" msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:461 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:463 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-authentication-service`." +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-synapse.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-synapse.po index c2a063525..cd6cfae48 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-synapse.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook-synapse.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,261 +18,305 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook-synapse.md:1 +#: ../../../docs/configuring-playbook-synapse.md:12 msgid "Configuring Synapse (optional)" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:3 +#: ../../../docs/configuring-playbook-synapse.md:14 msgid "By default, this playbook configures the [Synapse](https://github.com/element-hq/synapse) Matrix server, so that it works for the general case. If that's okay, you can skip this document." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:5 +#: ../../../docs/configuring-playbook-synapse.md:16 +msgid "💡 See this page for details about maintaining Synapse: [Synapse maintenance](maintenance-synapse.md)" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:18 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:7 +#: ../../../docs/configuring-playbook-synapse.md:20 msgid "Load balancing with workers" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:9 +#: ../../../docs/configuring-playbook-synapse.md:22 msgid "To have Synapse gracefully handle thousands of users, worker support should be enabled. It factors out some homeserver tasks and spreads the load of incoming client and server-to-server traffic between multiple processes. More information can be found in the [official Synapse workers documentation](https://github.com/element-hq/synapse/blob/master/docs/workers.md) and [Tom Foster](https://github.com/tcpipuk)'s [Synapse homeserver guide](https://tcpipuk.github.io/synapse/index.html)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:11 +#: ../../../docs/configuring-playbook-synapse.md:24 msgid "To enable Synapse worker support, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:19 +#: ../../../docs/configuring-playbook-synapse.md:32 msgid "By default, this enables the `one-of-each` [worker preset](#worker-presets), but you may wish to use another preset or [control the number of worker instances](#controlling-the-number-of-worker-instances)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:21 +#: ../../../docs/configuring-playbook-synapse.md:34 msgid "Worker presets" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:23 +#: ../../../docs/configuring-playbook-synapse.md:36 msgid "We support a few configuration presets (`matrix_synapse_workers_preset: one-of-each` being the default configuration right now):" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:25 +#: ../../../docs/configuring-playbook-synapse.md:38 msgid "(federation-only) `little-federation-helper` — a very minimal worker configuration to improve federation performance" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:26 +#: ../../../docs/configuring-playbook-synapse.md:39 msgid "(generic) `one-of-each` — defaults to one worker of each supported type — no smart routing, just generic workers" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:27 +#: ../../../docs/configuring-playbook-synapse.md:40 msgid "(specialized) `specialized-workers` — defaults to one worker of each supported type, but disables generic workers and uses [specialized workers](#specialized-workers) instead" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:29 +#: ../../../docs/configuring-playbook-synapse.md:42 msgid "These presets represent a few common configurations. There are many worker types which can be mixed and matched based on your needs." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:31 +#: ../../../docs/configuring-playbook-synapse.md:44 msgid "Generic workers" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:33 +#: ../../../docs/configuring-playbook-synapse.md:46 msgid "Previously, the playbook only supported the most basic type of load-balancing. We call it **generic load-balancing** below, because incoming HTTP requests are sent to a generic worker. Load-balancing was done based on the requestor's IP address. This is simple, but not necessarily optimal. If you're accessing your account from multiple IP addresses (e.g. your mobile phone being on a different network than your PC), these separate requests may potentially be routed to different workers, each of which would need to cache roughly the same data." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:35 +#: ../../../docs/configuring-playbook-synapse.md:48 msgid "This is **still the default load-balancing method (preset) used by the playbook**." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:37 +#: ../../../docs/configuring-playbook-synapse.md:50 msgid "To use generic load-balancing, do not specify `matrix_synapse_workers_preset` to make it use the default value (`one-of-each`), or better yet — explicitly set it as `one-of-each`." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:39 +#: ../../../docs/configuring-playbook-synapse.md:52 msgid "You may also consider [tweaking the number of workers of each type](#controlling-the-number-of-worker-instances) from the default (one of each)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:41 +#: ../../../docs/configuring-playbook-synapse.md:54 msgid "Specialized workers" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:43 -msgid "The playbook now supports a smarter **specialized load-balancing** inspired by [Tom Foster](https://github.com/tcpipuk)'s [Synapse homeserver guide](https://tcpipuk.github.io/synapse/index.html). Instead of routing requests to one or more [generic workers](#generic-workers) based only on the requestor's IP adddress, specialized load-balancing routes to **4 different types of specialized workers** based on **smarter criteria** — the access token (username) of the requestor and/or on the resource (room, etc.) being requested." +#: ../../../docs/configuring-playbook-synapse.md:56 +msgid "The playbook now supports a smarter **specialized load-balancing** inspired by [Tom Foster](https://github.com/tcpipuk)'s [Synapse homeserver guide](https://tcpipuk.github.io/synapse/index.html). Instead of routing requests to one or more [generic workers](#generic-workers) based only on the requester's IP address, specialized load-balancing routes to **4 different types of specialized workers** based on **smarter criteria** — the access token (username) of the requester and/or on the resource (room, etc.) being requested." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:45 +#: ../../../docs/configuring-playbook-synapse.md:58 msgid "The playbook supports these **4 types** of specialized workers:" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:47 +#: ../../../docs/configuring-playbook-synapse.md:60 msgid "Room workers — handles various [Client-Server](https://spec.matrix.org/v1.9/client-server-api/) & [Federation](https://spec.matrix.org/v1.9/server-server-api) APIs dedicated to handling specific rooms" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:48 +#: ../../../docs/configuring-playbook-synapse.md:61 msgid "Sync workers — handles various [Client-Server](https://spec.matrix.org/v1.9/client-server-api/) APIs related to synchronization (most notably [the `/sync` endpoint](https://spec.matrix.org/v1.9/client-server-api/#get_matrixclientv3sync))" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:49 +#: ../../../docs/configuring-playbook-synapse.md:62 msgid "Client readers — handles various [Client-Server](https://spec.matrix.org/v1.9/client-server-api/) APIs which are not for specific rooms (handled by **room workers**) or for synchronization (handled by **sync workers**)" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:50 +#: ../../../docs/configuring-playbook-synapse.md:63 msgid "Federation readers — handles various [Federation](https://spec.matrix.org/v1.9/server-server-api) APIs which are not for specific rooms (handled by **room workers**)" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:52 +#: ../../../docs/configuring-playbook-synapse.md:65 msgid "To use specialized load-balancing, consider enabling the `specialized-workers` [worker preset](#worker-presets) and potentially [tweaking the number of workers of each type](#controlling-the-number-of-worker-instances) from the default (one of each)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:54 +#: ../../../docs/configuring-playbook-synapse.md:67 msgid "Controlling the number of worker instances" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:56 +#: ../../../docs/configuring-playbook-synapse.md:69 msgid "If you'd like more customization power, you can start with one of the [worker presets](#worker-presets) and then tweak various `matrix_synapse_workers_*_count` variables manually." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:58 +#: ../../../docs/configuring-playbook-synapse.md:71 msgid "To find what variables are available for you to override in your own `vars.yml` configuration file, see the [`defaults/main.yml` file for the `matrix-synapse` Ansible role](../roles/custom/matrix-synapse/defaults/main.yml)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:60 +#: ../../../docs/configuring-playbook-synapse.md:73 msgid "The only thing you **cannot** do is mix [generic workers](#generic-workers) and [specialized workers](#specialized-workers)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:62 +#: ../../../docs/configuring-playbook-synapse.md:75 msgid "Effect of enabling workers on the rest of your server" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:64 +#: ../../../docs/configuring-playbook-synapse.md:77 msgid "When Synapse workers are enabled, the integrated [Postgres database is tuned](maintenance-postgres.md#tuning-postgresql), so that the maximum number of Postgres connections are increased from `200` to `500`. If you need to decrease or increase the number of maximum Postgres connections further, use the `postgres_max_connections` variable." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:66 -msgid "A separate Ansible role (`matrix-synapse-reverse-proxy-companion`) and component handles load-balancing for workers. This role/component is automatically enabled when you enable workers. Make sure to use the `setup-all` tag (not `install-all`!) during the playbook's [installation](./installing.md) process, especially if you're disabling workers, so that components may be installed/uninstalled correctly." +#: ../../../docs/configuring-playbook-synapse.md:79 +msgid "The `matrix-synapse` role also manages the `matrix-synapse-reverse-proxy-companion` component for load-balancing with workers. This component is automatically enabled when you enable workers. Make sure to use the `setup-all` tag (not `install-all`!) during the playbook's [installation](./installing.md) process, especially if you're disabling workers, so that components may be installed/uninstalled correctly." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:68 +#: ../../../docs/configuring-playbook-synapse.md:81 msgid "In case any problems occur, make sure to have a look at the [list of synapse issues about workers](https://github.com/element-hq/synapse/issues?q=workers+in%3Atitle) and your `journalctl --unit 'matrix-*'`." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:70 +#: ../../../docs/configuring-playbook-synapse.md:83 +msgid "Limit joining heavy rooms on constrained hosts" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:85 +msgid "If your server is underpowered, joining heavy rooms can cause Synapse to consume a lot of resources and be unavailable for long (while it catches up)." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:87 +msgid "To avoid this, Synapse can be configured to reject joins for remote rooms that are too complex before users enter them." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:89 +msgid "Complexity is computed as `current_state_events / 500` (Synapse state event count for current room state). When the resulting value is higher than `matrix_synapse_limit_remote_rooms_complexity` and `matrix_synapse_limit_remote_rooms_enabled` is `true`, Synapse blocks joining the room." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:91 +msgid "We recommend using this as a guardrail on low-resource servers:" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:106 msgid "Synapse + OpenID Connect for Single-Sign-On" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:72 +#: ../../../docs/configuring-playbook-synapse.md:108 msgid "💡 An alternative to setting up OIDC in Synapse is to use [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) (MAS). Newer clients (like Element X) only support SSO-based authentication via MAS and not via the legacy Synapse OIDC setup described below. That said, MAS is still a new experimental service which comes with its own downsides. Consult its documentation to learn if it will be a good fit for your deployment." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:74 +#: ../../../docs/configuring-playbook-synapse.md:110 msgid "If you'd like to use OpenID Connect authentication with Synapse, you'll need some additional configuration." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:76 +#: ../../../docs/configuring-playbook-synapse.md:112 msgid "This example configuration is for [keycloak](https://www.keycloak.org/), an opensource Identity Provider maintained by Red Hat." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:78 +#: ../../../docs/configuring-playbook-synapse.md:114 msgid "For more detailed documentation on available options and how to setup keycloak, see the [Synapse documentation on OpenID Connect with keycloak](https://github.com/element-hq/synapse/blob/develop/docs/openid.md#keycloak)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:80 -#, python-format +#: ../../../docs/configuring-playbook-synapse.md:116 +#, python-format, python-brace-format msgid "In case you encounter errors regarding the parsing of the variables, you can try to add `{% raw %}` and `{% endraw %}` blocks around them. For example ;" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:101 +#: ../../../docs/configuring-playbook-synapse.md:137 msgid "Customizing templates" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:103 +#: ../../../docs/configuring-playbook-synapse.md:139 msgid "[Templates](https://github.com/element-hq/synapse/blob/develop/docs/templates.md) are used by Synapse for showing **certain web pages** handled by the server, as well as for **email notifications**." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:105 +#: ../../../docs/configuring-playbook-synapse.md:141 msgid "This playbook allows you to customize the default templates (see the [`synapse/res/templates` directory](https://github.com/element-hq/synapse/tree/develop/synapse/res/templates))." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:107 +#: ../../../docs/configuring-playbook-synapse.md:143 msgid "If template customization is enabled, the playbook will build a custom container image based on the official one." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:109 +#: ../../../docs/configuring-playbook-synapse.md:145 msgid "Your custom templates need to live in a public or private git repository. This repository will be cloned during Synapse image customization (during the playbook run)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:111 +#: ../../../docs/configuring-playbook-synapse.md:147 msgid "To enable template customizations, add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:137 +#: ../../../docs/configuring-playbook-synapse.md:173 msgid "As mentioned in Synapse's Templates documentation, Synapse will fall back to its own templates if a template is not found in that directory. Due to this, it's recommended to only store and maintain template files in your repository if you need to make custom changes. Other files (which you don't need to change), should not be duplicated, so that you don't need to worry about getting out-of-sync with the original Synapse templates." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:139 +#: ../../../docs/configuring-playbook-synapse.md:175 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:141 +#: ../../../docs/configuring-playbook-synapse.md:177 msgid "There are some additional things you may wish to configure about the server." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:143 +#: ../../../docs/configuring-playbook-synapse.md:179 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:145 +#: ../../../docs/configuring-playbook-synapse.md:181 msgid "`roles/custom/matrix-synapse/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:146 +#: ../../../docs/configuring-playbook-synapse.md:182 msgid "`roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2` for the server's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_synapse_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:148 +#: ../../../docs/configuring-playbook-synapse.md:184 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:150 +#: ../../../docs/configuring-playbook-synapse.md:186 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:157 +#: ../../../docs/configuring-playbook-synapse.md:193 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:159 +#: ../../../docs/configuring-playbook-synapse.md:195 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:161 +#: ../../../docs/configuring-playbook-synapse.md:197 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:163 -msgid "Synapse Admin" +#: ../../../docs/configuring-playbook-synapse.md:199 +msgid "Ketesa" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:165 -msgid "With [Synapse Admin](configuring-playbook-synapse-admin.md), certain Synapse administration tasks (managing users and rooms, etc.) can be performed via a web user-interace." +#: ../../../docs/configuring-playbook-synapse.md:201 +msgid "[Ketesa](configuring-playbook-ketesa.md) is a fully-featured web UI for administrating your homeserver — managing users, rooms, media, sessions, and more." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:167 -msgid "The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md)." +#: ../../../docs/configuring-playbook-synapse.md:203 +msgid "The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:169 +#: ../../../docs/configuring-playbook-synapse.md:205 msgid "Monitoring Synapse Metrics with Prometheus and Grafana" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:171 +#: ../../../docs/configuring-playbook-synapse.md:207 msgid "This playbook allows you to enable Synapse metrics, which can provide insight into the performance and activity of Synapse." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:173 -msgid "To enable Synapse runtime metrics see: [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md)" +#: ../../../docs/configuring-playbook-synapse.md:209 +msgid "To enable Synapse runtime metrics, see: [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md) and [its subsection](configuring-playbook-prometheus-grafana.md#expose-metrics-of-other-services-roles)" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:175 +#: ../../../docs/configuring-playbook-synapse.md:211 msgid "To enable Synapse usage metrics, see: [Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md)" msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:213 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:215 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-synapse`." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:217 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:219 +msgid "Because Synapse is originally very chatty when it comes to logging, we intentionally reduce its [logging level](https://docs.python.org/3/library/logging.html#logging-levels) from `INFO` to `WARNING`." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:221 +msgid "If you'd like to debug an issue or [report a Synapse bug](https://github.com/element-hq/synapse/issues/new/choose) to the developers, it'd be better if you temporarily increase the logging verbosity to `INFO`. To do so, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook.po b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook.po index 2e19c7b85..54896c345 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/configuring-playbook.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,528 +18,568 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/configuring-playbook.md:1 +#: ../../../docs/configuring-playbook.md:17 msgid "Configuring the playbook" msgstr "" -#: ../../../docs/configuring-playbook.md:3 -msgid "[Prerequisites](prerequisites.md) > [Configuring your DNS settings](configuring-dns.md) > [Getting the playbook](getting-the-playbook.md) > Configuring the playbook > [Installing](installing.md)" +#: ../../../docs/configuring-playbook.md:19 +msgid "[Prerequisites](prerequisites.md) > [Configuring DNS settings](configuring-dns.md) > [Getting the playbook](getting-the-playbook.md) > Configuring the playbook > [Installing](installing.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:5 +#: ../../../docs/configuring-playbook.md:21 msgid "If you've configured your DNS records and retrieved the playbook's source code to your computer, you can start configuring the playbook. To do so, follow these steps inside the playbook directory:" msgstr "" -#: ../../../docs/configuring-playbook.md:7 +#: ../../../docs/configuring-playbook.md:23 msgid "create a directory to hold your configuration (`mkdir -p inventory/host_vars/matrix.example.com` where `example.com` is your \"base domain\")" msgstr "" -#: ../../../docs/configuring-playbook.md:9 +#: ../../../docs/configuring-playbook.md:25 msgid "copy the sample configuration file (`cp examples/vars.yml inventory/host_vars/matrix.example.com/vars.yml`)" msgstr "" -#: ../../../docs/configuring-playbook.md:11 -msgid "edit the configuration file (`inventory/host_vars/matrix.example.com/vars.yml`) to your liking. You may also take a look at the various `roles/*/ROLE_NAME_HERE/defaults/main.yml` files and see if there's something you'd like to copy over and override in your `vars.yml` configuration file." +#: ../../../docs/configuring-playbook.md:27 +msgid "edit the configuration file (`inventory/host_vars/matrix.example.com/vars.yml`) to your liking. You may also take a look at the various `roles/*/ROLE_NAME_HERE/defaults/main.yml` files (after importing external roles with `just update` into `roles/galaxy`) and see if there's something you'd like to copy over and override in your `vars.yml` configuration file." msgstr "" -#: ../../../docs/configuring-playbook.md:13 +#: ../../../docs/configuring-playbook.md:29 msgid "copy the sample inventory hosts file (`cp examples/hosts inventory/hosts`)" msgstr "" -#: ../../../docs/configuring-playbook.md:15 +#: ../../../docs/configuring-playbook.md:31 msgid "edit the inventory hosts file (`inventory/hosts`) to your liking" msgstr "" -#: ../../../docs/configuring-playbook.md:17 -msgid "(optional, advanced) you may wish to keep your `inventory` directory under version control with [git](https://git-scm.com/) or any other version-control system." +#: ../../../docs/configuring-playbook.md:33 +msgid "(optional, advanced) you may wish to keep your `inventory` directory under version control with [git](https://git-scm.com/) or any other version-control system. The `inventory` directory path is ignored via `.gitignore`, so it won't be part of the playbook repository. You can safely create a new git repository inside that directory with `git init`, etc." msgstr "" -#: ../../../docs/configuring-playbook.md:19 +#: ../../../docs/configuring-playbook.md:35 msgid "(optional, advanced) to run Ansible against multiple servers with different `sudo` credentials, you can copy the sample inventory hosts yaml file for each of your hosts: (`cp examples/host.yml inventory/my_host1.yml` …) and use the [`ansible-all-hosts.sh`](../bin/ansible-all-hosts.sh) script [in the installation step](installing.md)." msgstr "" -#: ../../../docs/configuring-playbook.md:21 +#: ../../../docs/configuring-playbook.md:37 msgid "For a basic Matrix installation, that's all you need." msgstr "" -#: ../../../docs/configuring-playbook.md:23 +#: ../../../docs/configuring-playbook.md:39 msgid "For a more custom setup, see the [Other configuration options](#other-configuration-options) below." msgstr "" -#: ../../../docs/configuring-playbook.md:25 +#: ../../../docs/configuring-playbook.md:41 msgid "[▶️](installing.md) When you're done with all the configuration you'd like to do, continue with [Installing](installing.md)." msgstr "" -#: ../../../docs/configuring-playbook.md:27 +#: ../../../docs/configuring-playbook.md:43 msgid "Other configuration options" msgstr "" -#: ../../../docs/configuring-playbook.md:29 +#: ../../../docs/configuring-playbook.md:45 msgid "**Note**: some of the roles like one for integrating Etherpad or Jitsi are managed by their own repositories, and the configuration files for them cannot be found locally (in `roles/galaxy`) until those roles are fetched from the upstream projects. Check [requirements.yml](../requirements.yml) for the URLs of those roles." msgstr "" -#: ../../../docs/configuring-playbook.md:31 +#: ../../../docs/configuring-playbook.md:47 msgid "Core service adjustments" msgstr "" -#: ../../../docs/configuring-playbook.md:33 +#: ../../../docs/configuring-playbook.md:49 msgid "Homeserver configuration:" msgstr "" -#: ../../../docs/configuring-playbook.md:34 +#: ../../../docs/configuring-playbook.md:50 msgid "[Configuring Synapse](configuring-playbook-synapse.md), if you're going with the default/recommended homeserver implementation" msgstr "" -#: ../../../docs/configuring-playbook.md:36 +#: ../../../docs/configuring-playbook.md:52 msgid "[Configuring Conduit](configuring-playbook-conduit.md), if you've switched to the [Conduit](https://conduit.rs) homeserver implementation" msgstr "" -#: ../../../docs/configuring-playbook.md:38 -msgid "[Configuring conduwuit](configuring-playbook-conduwuit.md), if you've switched to the [conduwuit](https://conduwuit.puppyirl.gay/) homeserver implementation" +#: ../../../docs/configuring-playbook.md:54 +msgid "[Configuring continuwuity](configuring-playbook-continuwuity.md), if you've switched to the [continuwuity](https://continuwuity.org) homeserver implementation" msgstr "" -#: ../../../docs/configuring-playbook.md:40 +#: ../../../docs/configuring-playbook.md:56 msgid "[Configuring Dendrite](configuring-playbook-dendrite.md), if you've switched to the [Dendrite](https://matrix-org.github.io/dendrite) homeserver implementation" msgstr "" -#: ../../../docs/configuring-playbook.md:42 +#: ../../../docs/configuring-playbook.md:58 msgid "Server components:" msgstr "" -#: ../../../docs/configuring-playbook.md:43 +#: ../../../docs/configuring-playbook.md:59 msgid "[Using an external PostgreSQL server](configuring-playbook-external-postgres.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:45 +#: ../../../docs/configuring-playbook.md:61 msgid "[Configuring a TURN server](configuring-playbook-turn.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:47 +#: ../../../docs/configuring-playbook.md:63 msgid "[Configuring the Traefik reverse-proxy](configuring-playbook-traefik.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:49 +#: ../../../docs/configuring-playbook.md:65 msgid "[Using your own webserver, instead of this playbook's Traefik reverse-proxy](configuring-playbook-own-webserver.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:51 +#: ../../../docs/configuring-playbook.md:67 msgid "[Adjusting SSL certificate retrieval](configuring-playbook-ssl-certificates.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:53 +#: ../../../docs/configuring-playbook.md:69 msgid "[Adjusting email-sending settings](configuring-playbook-email.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:55 -msgid "[Setting up ma1sd Identity Server](configuring-playbook-ma1sd.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:57 +#: ../../../docs/configuring-playbook.md:71 msgid "[Setting up Dynamic DNS](configuring-playbook-dynamic-dns.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:59 +#: ../../../docs/configuring-playbook.md:73 msgid "Server connectivity:" msgstr "" -#: ../../../docs/configuring-playbook.md:60 +#: ../../../docs/configuring-playbook.md:74 msgid "[Enabling Telemetry for your Matrix server](configuring-playbook-telemetry.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:62 +#: ../../../docs/configuring-playbook.md:76 msgid "[Controlling Matrix federation](configuring-playbook-federation.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:64 +#: ../../../docs/configuring-playbook.md:78 +msgid "[Configuring IPv6](./configuring-ipv6.md)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:80 msgid "Clients" msgstr "" -#: ../../../docs/configuring-playbook.md:66 +#: ../../../docs/configuring-playbook.md:82 msgid "Web clients for Matrix that you can host on your own domains." msgstr "" -#: ../../../docs/configuring-playbook.md:68 +#: ../../../docs/configuring-playbook.md:84 msgid "[Configuring Element Web](configuring-playbook-client-element-web.md), if you're going with the default/recommended client" msgstr "" -#: ../../../docs/configuring-playbook.md:70 +#: ../../../docs/configuring-playbook.md:86 msgid "[Setting up Hydrogen](configuring-playbook-client-hydrogen.md), if you've enabled [Hydrogen](https://github.com/element-hq/hydrogen-web), a lightweight Matrix client with legacy and mobile browser support" msgstr "" -#: ../../../docs/configuring-playbook.md:72 +#: ../../../docs/configuring-playbook.md:88 msgid "[Setting up Cinny](configuring-playbook-client-cinny.md), if you've enabled [Cinny](https://github.com/ajbura/cinny), a web client focusing primarily on simple, elegant and secure interface" msgstr "" -#: ../../../docs/configuring-playbook.md:74 +#: ../../../docs/configuring-playbook.md:90 +msgid "[Setting up Sable](configuring-playbook-client-sable.md), if you've enabled [Sable](https://github.com/7w1/sable), a web client focusing primarily on simple, elegant and secure interface" +msgstr "" + +#: ../../../docs/configuring-playbook.md:92 msgid "[Setting up SchildiChat Web](configuring-playbook-client-schildichat-web.md), if you've enabled [SchildiChat Web](https://schildi.chat/), a web client based on [Element Web](https://element.io/) with some extras and tweaks" msgstr "" -#: ../../../docs/configuring-playbook.md:76 +#: ../../../docs/configuring-playbook.md:94 +msgid "[Setting up FluffyChat Web](configuring-playbook-client-fluffychat-web.md), if you've enabled [FluffyChat Web](https://github.com/krille-chan/fluffychat), a cute cross-platform messenger (web, iOS, Android) for Matrix written in [Flutter](https://flutter.dev/)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:97 msgid "Authentication and user-related" msgstr "" -#: ../../../docs/configuring-playbook.md:78 +#: ../../../docs/configuring-playbook.md:99 msgid "Extend and modify how users are authenticated on your homeserver." msgstr "" -#: ../../../docs/configuring-playbook.md:80 +#: ../../../docs/configuring-playbook.md:101 msgid "[Setting up Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) (Next-generation auth for Matrix, based on OAuth 2.0/OIDC)" msgstr "" -#: ../../../docs/configuring-playbook.md:82 +#: ../../../docs/configuring-playbook.md:103 msgid "[Setting up Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:84 -msgid "[Setting up Synapse Admin](configuring-playbook-synapse-admin.md)" +#: ../../../docs/configuring-playbook.md:105 +msgid "[Setting up Ketesa](configuring-playbook-ketesa.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:86 +#: ../../../docs/configuring-playbook.md:107 msgid "[Setting up matrix-registration](configuring-playbook-matrix-registration.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:88 +#: ../../../docs/configuring-playbook.md:109 msgid "[Setting up the REST authentication password provider module](configuring-playbook-rest-auth.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:90 +#: ../../../docs/configuring-playbook.md:111 msgid "[Setting up the Shared Secret Auth password provider module](configuring-playbook-shared-secret-auth.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:92 +#: ../../../docs/configuring-playbook.md:113 msgid "[Setting up the LDAP authentication password provider module](configuring-playbook-ldap-auth.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:94 +#: ../../../docs/configuring-playbook.md:115 msgid "[Setting up matrix-ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:96 +#: ../../../docs/configuring-playbook.md:117 msgid "[Setting up Synapse Simple Antispam](configuring-playbook-synapse-simple-antispam.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:98 +#: ../../../docs/configuring-playbook.md:119 msgid "[Setting up Matrix User Verification Service](configuring-playbook-user-verification-service.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:100 +#: ../../../docs/configuring-playbook.md:121 msgid "File Storage" msgstr "" -#: ../../../docs/configuring-playbook.md:102 +#: ../../../docs/configuring-playbook.md:123 msgid "Use alternative file storage to the default `media_store` folder." msgstr "" -#: ../../../docs/configuring-playbook.md:104 -msgid "[Storing Matrix media files on Amazon S3 with Goofys](configuring-playbook-s3-goofys.md)" +#: ../../../docs/configuring-playbook.md:125 +msgid "[Storing Matrix media files using matrix-media-repo](configuring-playbook-matrix-media-repo.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:106 +#: ../../../docs/configuring-playbook.md:127 msgid "[Storing Synapse media files on Amazon S3 or another compatible Object Storage](configuring-playbook-s3.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:108 -msgid "[Storing Matrix media files using matrix-media-repo](configuring-playbook-matrix-media-repo.md)" +#: ../../../docs/configuring-playbook.md:129 +msgid "[Storing Synapse media files on Amazon S3 with Goofys](configuring-playbook-s3-goofys.md)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:131 +msgid "[Storing Synapse media files on Amazon S3 with synapse-s3-storage-provider](configuring-playbook-synapse-s3-storage-provider.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:110 +#: ../../../docs/configuring-playbook.md:133 msgid "Bridging other networks" msgstr "" -#: ../../../docs/configuring-playbook.md:112 +#: ../../../docs/configuring-playbook.md:135 msgid "Bridges can be used to connect your Matrix installation with third-party communication networks." msgstr "" -#: ../../../docs/configuring-playbook.md:114 +#: ../../../docs/configuring-playbook.md:137 msgid "[Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md) — a common guide for configuring mautrix bridges" msgstr "" -#: ../../../docs/configuring-playbook.md:116 +#: ../../../docs/configuring-playbook.md:139 +msgid "[Setting up Mautrix Bluesky bridging](configuring-playbook-bridge-mautrix-bluesky.md)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:141 msgid "[Setting up Mautrix Discord bridging](configuring-playbook-bridge-mautrix-discord.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:118 +#: ../../../docs/configuring-playbook.md:143 msgid "[Setting up Mautrix Telegram bridging](configuring-playbook-bridge-mautrix-telegram.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:120 +#: ../../../docs/configuring-playbook.md:145 msgid "[Setting up Mautrix Slack bridging](configuring-playbook-bridge-mautrix-slack.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:122 +#: ../../../docs/configuring-playbook.md:147 msgid "[Setting up Mautrix Google Messages bridging](configuring-playbook-bridge-mautrix-gmessages.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:124 +#: ../../../docs/configuring-playbook.md:149 msgid "[Setting up Mautrix Whatsapp bridging](configuring-playbook-bridge-mautrix-whatsapp.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:126 +#: ../../../docs/configuring-playbook.md:151 msgid "[Setting up Instagram bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-instagram.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:128 +#: ../../../docs/configuring-playbook.md:153 msgid "[Setting up Messenger bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-messenger.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:130 +#: ../../../docs/configuring-playbook.md:155 msgid "[Setting up Mautrix Google Chat bridging](configuring-playbook-bridge-mautrix-googlechat.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:132 +#: ../../../docs/configuring-playbook.md:157 msgid "[Setting up Mautrix Twitter bridging](configuring-playbook-bridge-mautrix-twitter.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:134 +#: ../../../docs/configuring-playbook.md:159 msgid "[Setting up Mautrix Signal bridging](configuring-playbook-bridge-mautrix-signal.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:136 +#: ../../../docs/configuring-playbook.md:161 msgid "[Setting up Mautrix wsproxy for bridging Android SMS or Apple iMessage](configuring-playbook-bridge-mautrix-wsproxy.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:138 +#: ../../../docs/configuring-playbook.md:163 msgid "[Setting up Appservice IRC bridging](configuring-playbook-bridge-appservice-irc.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:140 +#: ../../../docs/configuring-playbook.md:165 msgid "[Setting up Appservice Discord bridging](configuring-playbook-bridge-appservice-discord.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:142 -msgid "[Setting up Appservice Slack bridging](configuring-playbook-bridge-appservice-slack.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:144 +#: ../../../docs/configuring-playbook.md:167 msgid "[Setting up Appservice Kakaotalk bridging](configuring-playbook-bridge-appservice-kakaotalk.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:146 +#: ../../../docs/configuring-playbook.md:169 msgid "[Setting up Beeper LinkedIn bridging](configuring-playbook-bridge-beeper-linkedin.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:148 +#: ../../../docs/configuring-playbook.md:171 msgid "[Setting up matrix-hookshot](configuring-playbook-bridge-hookshot.md) — a bridge between Matrix and multiple project management services, such as [GitHub](https://github.com), [GitLab](https://about.gitlab.com) and [JIRA](https://www.atlassian.com/software/jira)." msgstr "" -#: ../../../docs/configuring-playbook.md:150 -msgid "[Setting up MX Puppet Slack bridging](configuring-playbook-bridge-mx-puppet-slack.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:152 -msgid "[Setting up MX Puppet Instagram bridging](configuring-playbook-bridge-mx-puppet-instagram.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:154 -msgid "[Setting up MX Puppet Twitter bridging](configuring-playbook-bridge-mx-puppet-twitter.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:156 -msgid "[Setting up MX Puppet Discord bridging](configuring-playbook-bridge-mx-puppet-discord.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:158 +#: ../../../docs/configuring-playbook.md:173 msgid "[Setting up MX Puppet GroupMe bridging](configuring-playbook-bridge-mx-puppet-groupme.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:160 -msgid "[Setting up MX Puppet Steam bridging](configuring-playbook-bridge-mx-puppet-steam.md)" +#: ../../../docs/configuring-playbook.md:175 +msgid "[Setting up Steam bridging](configuring-playbook-bridge-steam.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:162 -msgid "[Setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md)" +#: ../../../docs/configuring-playbook.md:177 +msgid "[Setting up MX Puppet Steam bridging](configuring-playbook-bridge-mx-puppet-steam.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:164 +#: ../../../docs/configuring-playbook.md:179 msgid "[Setting up Postmoogle email bridging](configuring-playbook-bridge-postmoogle.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:166 +#: ../../../docs/configuring-playbook.md:181 msgid "[Setting up Matrix SMS bridging](configuring-playbook-bridge-matrix-bridge-sms.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:168 +#: ../../../docs/configuring-playbook.md:183 msgid "[Setting up Heisenbridge bouncer-style IRC bridging](configuring-playbook-bridge-heisenbridge.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:170 +#: ../../../docs/configuring-playbook.md:185 msgid "[Setting up WeChat bridging](configuring-playbook-bridge-wechat.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:172 +#: ../../../docs/configuring-playbook.md:187 msgid "Bots" msgstr "" -#: ../../../docs/configuring-playbook.md:174 +#: ../../../docs/configuring-playbook.md:189 msgid "Bots provide various additional functionality to your installation." msgstr "" -#: ../../../docs/configuring-playbook.md:176 +#: ../../../docs/configuring-playbook.md:191 msgid "[Setting up baibot](configuring-playbook-bot-baibot.md) — a bot through which you can talk to various [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) services ([OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/) and [others](https://github.com/etkecc/baibot/blob/main/docs/providers.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:178 +#: ../../../docs/configuring-playbook.md:193 msgid "[Setting up matrix-reminder-bot](configuring-playbook-bot-matrix-reminder-bot.md) — a bot to remind you about stuff" msgstr "" -#: ../../../docs/configuring-playbook.md:180 +#: ../../../docs/configuring-playbook.md:195 msgid "[Setting up matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md) — a bot to create and manage registration tokens to invite users" msgstr "" -#: ../../../docs/configuring-playbook.md:182 +#: ../../../docs/configuring-playbook.md:197 msgid "[Setting up maubot](configuring-playbook-bot-maubot.md) — a plugin-based Matrix bot system" msgstr "" -#: ../../../docs/configuring-playbook.md:184 +#: ../../../docs/configuring-playbook.md:199 msgid "[Setting up Honoroit](configuring-playbook-bot-honoroit.md) — a helpdesk bot" msgstr "" -#: ../../../docs/configuring-playbook.md:186 +#: ../../../docs/configuring-playbook.md:201 msgid "[Setting up Mjolnir](configuring-playbook-bot-mjolnir.md) — a moderation tool/bot" msgstr "" -#: ../../../docs/configuring-playbook.md:188 +#: ../../../docs/configuring-playbook.md:203 msgid "[Setting up Draupnir](configuring-playbook-bot-draupnir.md) — a moderation tool/bot, forked from Mjolnir and maintained by its former leader developer" msgstr "" -#: ../../../docs/configuring-playbook.md:190 +#: ../../../docs/configuring-playbook.md:205 msgid "[Setting up Draupnir for all/D4A](configuring-playbook-appservice-draupnir-for-all.md) — like the [Draupnir bot](configuring-playbook-bot-draupnir.md) mentioned above, but running in appservice mode and supporting multiple instances" msgstr "" -#: ../../../docs/configuring-playbook.md:192 +#: ../../../docs/configuring-playbook.md:207 msgid "[Setting up Buscarron](configuring-playbook-bot-buscarron.md) — a bot you can use to send any form (HTTP POST, HTML) to a (encrypted) Matrix room" msgstr "" -#: ../../../docs/configuring-playbook.md:194 +#: ../../../docs/configuring-playbook.md:209 msgid "Administration" msgstr "" -#: ../../../docs/configuring-playbook.md:196 +#: ../../../docs/configuring-playbook.md:211 msgid "Services that help you in administrating and monitoring your Matrix installation." msgstr "" -#: ../../../docs/configuring-playbook.md:198 +#: ../../../docs/configuring-playbook.md:213 msgid "[Setting up Prometheus Alertmanager integration via matrix-alertmanager-receiver](configuring-playbook-alertmanager-receiver.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:200 +#: ../../../docs/configuring-playbook.md:215 msgid "[Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:202 -msgid "[Enabling metrics and graphs for NginX logs](configuring-playbook-prometheus-nginxlog.md)" -msgstr "" - -#: ../../../docs/configuring-playbook.md:204 +#: ../../../docs/configuring-playbook.md:217 msgid "[Setting up the rageshake bug report server](configuring-playbook-rageshake.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:206 +#: ../../../docs/configuring-playbook.md:219 msgid "[Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:208 +#: ../../../docs/configuring-playbook.md:221 msgid "Backups:" msgstr "" -#: ../../../docs/configuring-playbook.md:209 +#: ../../../docs/configuring-playbook.md:222 msgid "[Setting up BorgBackup](configuring-playbook-backup-borg.md) — a full Matrix server backup solution, including the Postgres database" msgstr "" -#: ../../../docs/configuring-playbook.md:211 -msgid "[Setting up postgres backup](configuring-playbook-postgres-backup.md) — a Postgres-database backup solution (note: does not include other files)" +#: ../../../docs/configuring-playbook.md:224 +msgid "[Setting up Postgres backup](configuring-playbook-postgres-backup.md) — a Postgres-database backup solution (note: does not include other files)" msgstr "" -#: ../../../docs/configuring-playbook.md:213 +#: ../../../docs/configuring-playbook.md:226 msgid "Other specialized services" msgstr "" -#: ../../../docs/configuring-playbook.md:215 +#: ../../../docs/configuring-playbook.md:228 msgid "Various services that don't fit any other categories." msgstr "" -#: ../../../docs/configuring-playbook.md:217 -msgid "[Setting up Synapse Auto Invite Accept](configuring-playbook-synapse-auto-accept-invite.md)" +#: ../../../docs/configuring-playbook.md:230 +msgid "[Setting up Element Call](configuring-playbook-element-call.md) — a native Matrix video conferencing application, built on top of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" msgstr "" -#: ../../../docs/configuring-playbook.md:219 +#: ../../../docs/configuring-playbook.md:232 +msgid "[Setting up LiveKit JWT Service](configuring-playbook-livekit-jwt-service.md) - a component of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:234 +msgid "[Setting up LiveKit Server](configuring-playbook-livekit-server.md) - a component of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:236 +msgid "[Setting up Matrix RTC](configuring-playbook-matrix-rtc.md) (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:238 msgid "[Setting up synapse-auto-compressor](configuring-playbook-synapse-auto-compressor.md) for compressing the database on Synapse homeservers" msgstr "" -#: ../../../docs/configuring-playbook.md:221 +#: ../../../docs/configuring-playbook.md:240 msgid "[Setting up Matrix Corporal](configuring-playbook-matrix-corporal.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:223 +#: ../../../docs/configuring-playbook.md:242 +msgid "[Setting up Matrix.to](configuring-playbook-matrixto.md)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:244 msgid "[Setting up Etherpad](configuring-playbook-etherpad.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:225 +#: ../../../docs/configuring-playbook.md:246 msgid "[Setting up the Jitsi video-conferencing platform](configuring-playbook-jitsi.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:227 +#: ../../../docs/configuring-playbook.md:248 msgid "[Setting up Cactus Comments](configuring-playbook-cactus-comments.md) — a federated comment system built on Matrix" msgstr "" -#: ../../../docs/configuring-playbook.md:229 +#: ../../../docs/configuring-playbook.md:250 msgid "[Setting up Pantalaimon (E2EE aware proxy daemon)](configuring-playbook-pantalaimon.md) (advanced)" msgstr "" -#: ../../../docs/configuring-playbook.md:231 +#: ../../../docs/configuring-playbook.md:252 msgid "[Setting up the Sygnal push gateway](configuring-playbook-sygnal.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:233 +#: ../../../docs/configuring-playbook.md:254 msgid "[Setting up the ntfy push notifications server](configuring-playbook-ntfy.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:235 +#: ../../../docs/configuring-playbook.md:256 msgid "Deprecated / unmaintained / removed services" msgstr "" -#: ../../../docs/configuring-playbook.md:237 +#: ../../../docs/configuring-playbook.md:258 msgid "**Note**: since a deprecated or unmaintained service will not be updated, its bug or vulnerability will be unlikely to get patched. It is recommended to migrate from the service to an alternative if any, and make sure to do your own research before you decide to keep it running nonetheless." msgstr "" -#: ../../../docs/configuring-playbook.md:239 +#: ../../../docs/configuring-playbook.md:260 +msgid "[Configuring conduwuit](configuring-playbook-conduwuit.md) (removed; this component has been abandoned and unmaintained)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:262 msgid "[Setting up the Sliding Sync proxy](configuring-playbook-sliding-sync-proxy.md) for clients which require Sliding Sync support (like old Element X versions, before it got switched to Simplified Sliding Sync)" msgstr "" -#: ../../../docs/configuring-playbook.md:241 -msgid "[Setting up Appservice Webhooks bridging](configuring-playbook-bridge-appservice-webhooks.md) (deprecated; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be installed using [this playbook](configuring-playbook-bridge-hookshot.md))" +#: ../../../docs/configuring-playbook.md:264 +msgid "[Setting up Appservice Slack bridging](configuring-playbook-bridge-appservice-slack.md) (removed; this component has been discontinued)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:266 +msgid "[Setting up Appservice Webhooks bridging](configuring-playbook-bridge-appservice-webhooks.md) (deprecated; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:243 +#: ../../../docs/configuring-playbook.md:268 msgid "[Setting up the Dimension integration manager](configuring-playbook-dimension.md) ([unmaintained](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2806#issuecomment-1673559299); after [installing](installing.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:245 -msgid "[Setting up Email2Matrix](configuring-playbook-email2matrix.md) (unmaintained; the author suggests taking a look at [Postmoogle](https://github.com/etkecc/postmoogle) as a replacement, which can also be installed using [this playbook](configuring-playbook-bridge-postmoogle.md))" +#: ../../../docs/configuring-playbook.md:270 +msgid "[Setting up Email2Matrix](configuring-playbook-email2matrix.md) (removed; the author suggests taking a look at [Postmoogle](https://github.com/etkecc/postmoogle) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-postmoogle.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:247 -msgid "[Setting up Go-NEB](configuring-playbook-bot-go-neb.md) (unmaintained; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be installed using [this playbook](configuring-playbook-bridge-hookshot.md))" +#: ../../../docs/configuring-playbook.md:272 +msgid "[Setting up Go-NEB](configuring-playbook-bot-go-neb.md) (unmaintained; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:249 -msgid "[Setting up matrix-bot-chatgpt](configuring-playbook-bot-chatgpt.md) (unmaintained; the bridge's author suggests taking a look at [baibot](https://github.com/etkecc/baibot) as a replacement, which can also be installed using [this playbook](configuring-playbook-bot-baibot.md))" +#: ../../../docs/configuring-playbook.md:274 +msgid "[Setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md) (removed; Skype has been discontinued since May 2025)" msgstr "" -#: ../../../docs/configuring-playbook.md:251 -msgid "[Setting up Mautrix Facebook bridging](configuring-playbook-bridge-mautrix-facebook.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-messenger](configuring-playbook-bridge-mautrix-meta-messenger.md))" +#: ../../../docs/configuring-playbook.md:276 +msgid "[Setting up ma1sd Identity Server](configuring-playbook-ma1sd.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook.)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:278 +msgid "[Setting up matrix-bot-chatgpt](configuring-playbook-bot-chatgpt.md) (unmaintained; the bridge's author suggests taking a look at [baibot](https://github.com/etkecc/baibot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bot-baibot.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:253 -msgid "[Setting up Mautrix Hangouts bridging](configuring-playbook-bridge-mautrix-hangouts.md) (deprecated in favor of the Google Chat bridge with [mautrix-googlechat](configuring-playbook-bridge-mautrix-googlechat.md))" +#: ../../../docs/configuring-playbook.md:280 +msgid "[Setting up Mautrix Facebook bridging](configuring-playbook-bridge-mautrix-facebook.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-messenger](configuring-playbook-bridge-mautrix-meta-messenger.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:255 +#: ../../../docs/configuring-playbook.md:282 msgid "[Setting up Mautrix Instagram bridging](configuring-playbook-bridge-mautrix-instagram.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-instagram](configuring-playbook-bridge-mautrix-meta-instagram.md))" msgstr "" -#: ../../../docs/configuring-playbook.md:257 +#: ../../../docs/configuring-playbook.md:284 +msgid "[Setting up MX Puppet Discord bridging](configuring-playbook-bridge-mx-puppet-discord.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Discord bridging](configuring-playbook-bridge-mautrix-discord.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:286 +msgid "[Setting up MX Puppet Instagram bridging](configuring-playbook-bridge-mx-puppet-instagram.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Instagram bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-instagram.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:288 msgid "[Setting up MX Puppet Skype bridging](configuring-playbook-bridge-mx-puppet-skype.md) (removed; this component has been broken for a long time, so it has been removed from the playbook. Consider [setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md))" msgstr "" + +#: ../../../docs/configuring-playbook.md:290 +msgid "[Setting up MX Puppet Slack bridging](configuring-playbook-bridge-mx-puppet-slack.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Slack bridging](configuring-playbook-bridge-mautrix-slack.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:292 +msgid "[Setting up MX Puppet Twitter bridging](configuring-playbook-bridge-mx-puppet-twitter.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Twitter bridging](configuring-playbook-bridge-mautrix-twitter.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:294 +msgid "[Setting up Synapse Auto Invite Accept](configuring-playbook-synapse-auto-accept-invite.md) (removed; since Synapse [v1.109.0](https://github.com/element-hq/synapse/releases/tag/v1.109.0) the same feature is available natively.)" +msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/container-images.po b/i18n/locales/jp/LC_MESSAGES/docs/container-images.po index 02bcdb812..9670b134f 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/container-images.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/container-images.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,21 +18,21 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/container-images.md:1 +#: ../../../docs/container-images.md:18 msgid "Container images used by the playbook" msgstr "" -#: ../../../docs/container-images.md:3 +#: ../../../docs/container-images.md:20 msgid "This page summarizes the container ([Docker](https://www.docker.com/)) images used by the playbook when setting up your server." msgstr "" -#: ../../../docs/container-images.md:5 +#: ../../../docs/container-images.md:22 msgid "We try to stick to official images (provided by their respective projects) as much as possible." msgstr "" -#: ../../../docs/container-images.md:7 +#: ../../../docs/container-images.md:24 msgid "Homeserver" msgstr "" @@ -85,15 +85,15 @@ msgid "Storing your data and managing your presence in the [Matrix](http://matri msgstr "" #: ../../../docs/container-images.md -msgid "[conduwuit](configuring-playbook-conduwuit.md)" +msgid "[continuwuity](configuring-playbook-continuwuity.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[girlbossceo/conduwuit](https://ghcr.io/girlbossceo/conduwuit)" +msgid "[continuwuation/continuwuity](https://forgejo.ellis.link/continuwuation/continuwuity)" msgstr "" #: ../../../docs/container-images.md -msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. conduwuit is a fork of Conduit." +msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. continuwuity is a continuation of conduwuit." msgstr "" #: ../../../docs/container-images.md @@ -108,11 +108,11 @@ msgstr "" msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Dendrite is a second-generation Matrix homeserver written in Go, an alternative to Synapse." msgstr "" -#: ../../../docs/container-images.md:16 +#: ../../../docs/container-images.md:33 msgid "Clients" msgstr "" -#: ../../../docs/container-images.md:18 +#: ../../../docs/container-images.md:35 msgid "Web clients for Matrix that you can host on your own domains." msgstr "" @@ -152,6 +152,14 @@ msgstr "" msgid "Simple, elegant and secure web client" msgstr "" +#: ../../../docs/container-images.md +msgid "[Sable](configuring-playbook-client-sable.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[7w1/sable](https://ghcr.io/7w1/sable)" +msgstr "" + #: ../../../docs/container-images.md msgid "[SchildiChat Web](configuring-playbook-client-schildichat-web.md)" msgstr "" @@ -164,11 +172,11 @@ msgstr "" msgid "Based on Element Web, with a more traditional instant messaging experience" msgstr "" -#: ../../../docs/container-images.md:27 +#: ../../../docs/container-images.md:45 msgid "Server Components" msgstr "" -#: ../../../docs/container-images.md:29 +#: ../../../docs/container-images.md:47 msgid "Services that run on the server to make the various parts of your installation work." msgstr "" @@ -205,7 +213,7 @@ msgid "[Traefik](https://hub.docker.com/_/traefik/)" msgstr "" #: ../../../docs/container-images.md -msgid "Web server, listening on ports 80, 443 and 8448 — standing in front of all the other services. Using your own webserver [is possible](configuring-playbook-own-webserver.md)" +msgid "Web server, listening on ports 80, 443 and 8448 — standing in front of all the other services. [Using your own webserver](configuring-playbook-own-webserver.md) is also possible." msgstr "" #: ../../../docs/container-images.md @@ -217,7 +225,7 @@ msgid "[certbot/certbot](https://hub.docker.com/r/certbot/certbot/)" msgstr "" #: ../../../docs/container-images.md -msgid "The [certbot](https://certbot.eff.org/) tool for obtaining SSL certificates from [Let's Encrypt](https://letsencrypt.org/)" +msgid "[Certbot](https://certbot.eff.org/) tool for obtaining SSL certificates from [Let's Encrypt](https://letsencrypt.org/)" msgstr "" #: ../../../docs/container-images.md @@ -233,34 +241,46 @@ msgid "Mail server, through which all Matrix services send outgoing email (can b msgstr "" #: ../../../docs/container-images.md -msgid "[ma1sd](configuring-playbook-ma1sd.md)" +msgid "[ddclient](configuring-playbook-dynamic-dns.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[ma1uta/ma1sd](https://hub.docker.com/r/ma1uta/ma1sd/)" +msgid "[linuxserver/ddclient](https://hub.docker.com/r/linuxserver/ddclient)" msgstr "" #: ../../../docs/container-images.md -msgid "Matrix Identity Server" +msgid "Update dynamic DNS entries for accounts on Dynamic DNS Network Service Provider" msgstr "" #: ../../../docs/container-images.md -msgid "[ddclient](configuring-playbook-dynamic-dns.md)" +msgid "[LiveKit Server](configuring-playbook-livekit-server.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[linuxserver/ddclient](https://hub.docker.com/r/linuxserver/ddclient)" +msgid "[livekit/livekit-server](https://hub.docker.com/r/livekit/livekit-server/)" msgstr "" #: ../../../docs/container-images.md -msgid "Update dynamic DNS entries for accounts on Dynamic DNS Network Service Provider" +msgid "WebRTC server for audio/video calls" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[Livekit JWT Service](configuring-playbook-livekit-jwt-service.md)" msgstr "" -#: ../../../docs/container-images.md:41 +#: ../../../docs/container-images.md +msgid "[element-hq/lk-jwt-service](https://ghcr.io/element-hq/lk-jwt-service)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "JWT service for integrating [Element Call](./configuring-playbook-element-call.md) with [LiveKit Server](./configuring-playbook-livekit-server.md)" +msgstr "" + +#: ../../../docs/container-images.md:60 msgid "Authentication" msgstr "" -#: ../../../docs/container-images.md:43 +#: ../../../docs/container-images.md:62 msgid "Extend and modify how users are authenticated on your homeserver." msgstr "" @@ -301,7 +321,7 @@ msgid "[activism.international/matrix_ldap_registration_proxy](https://gitlab.co msgstr "" #: ../../../docs/container-images.md -msgid "A proxy that handles Matrix registration requests and forwards them to LDAP." +msgid "Proxy that handles Matrix registration requests and forwards them to LDAP" msgstr "" #: ../../../docs/container-images.md @@ -313,11 +333,11 @@ msgid "[zeratax/matrix-registration](https://hub.docker.com/r/devture/zeratax-ma msgstr "" #: ../../../docs/container-images.md -msgid "A simple python application to have a token based Matrix registration" +msgid "Simple python application to have a token based Matrix registration" msgstr "" #: ../../../docs/container-images.md -msgid "[Matrix User Verification Service](configuring-playbook-user-verification-service.md) (UVS)" +msgid "[Matrix User Verification Service](configuring-playbook-user-verification-service.md)" msgstr "" #: ../../../docs/container-images.md @@ -333,14 +353,14 @@ msgid "[synapse-simple-antispam](configuring-playbook-synapse-simple-antispam.md msgstr "" #: ../../../docs/container-images.md -msgid "A spam checker module" +msgid "Spam checker module" msgstr "" -#: ../../../docs/container-images.md:55 +#: ../../../docs/container-images.md:74 msgid "File Storage" msgstr "" -#: ../../../docs/container-images.md:57 +#: ../../../docs/container-images.md:76 msgid "Use alternative file storage to the default `media_store` folder." msgstr "" @@ -369,17 +389,29 @@ msgid "[t2bot/matrix-media-repo](https://ghcr.io/t2bot/matrix-media-repo)" msgstr "" #: ../../../docs/container-images.md -msgid "matrix-media-repo is a highly customizable multi-domain media repository for Matrix. Intended for medium to large deployments, this media repo de-duplicates media while being fully compliant with the specification." +msgid "Highly customizable multi-domain media repository for Matrix. Intended for medium to large deployments, this media repo de-duplicates media while being fully compliant with the specification." msgstr "" -#: ../../../docs/container-images.md:65 +#: ../../../docs/container-images.md:84 msgid "Bridges" msgstr "" -#: ../../../docs/container-images.md:67 +#: ../../../docs/container-images.md:86 msgid "Bridges can be used to connect your Matrix installation with third-party communication networks." msgstr "" +#: ../../../docs/container-images.md +msgid "[mautrix-bluesky](configuring-playbook-bridge-mautrix-bluesky.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[mautrix/bluesky](https://mau.dev/mautrix/bluesky/container_registry)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Bridge to [Bluesky](https://bsky.social/about)" +msgstr "" + #: ../../../docs/container-images.md msgid "[mautrix-discord](configuring-playbook-bridge-mautrix-discord.md)" msgstr "" @@ -548,14 +580,6 @@ msgstr "" msgid "Bridge to [Discord](https://discordapp.com/)" msgstr "" -#: ../../../docs/container-images.md -msgid "[matrix-appservice-slack](configuring-playbook-bridge-appservice-slack.md)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[matrixdotorg/matrix-appservice-slack](https://hub.docker.com/r/matrixdotorg/matrix-appservice-slack)" -msgstr "" - #: ../../../docs/container-images.md msgid "[matrix-hookshot](configuring-playbook-bridge-hookshot.md)" msgstr "" @@ -605,71 +629,27 @@ msgid "Bouncer-style bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_C msgstr "" #: ../../../docs/container-images.md -msgid "[go-skype-bridge](configuring-playbook-bridge-go-skype-bridge.md)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[nodefyme/go-skype-bridge](https://hub.docker.com/r/nodefyme/go-skype-bridge)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "Bridge to [Skype](https://www.skype.com)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[mx-puppet-slack](configuring-playbook-bridge-mx-puppet-slack.md)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[mx-puppet/slack/mx-puppet-slack](https://gitlab.com/mx-puppet/slack/mx-puppet-slack/container_registry)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "Bridge to [Slack](https://slack.com)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[mx-puppet-instagram](configuring-playbook-bridge-mx-puppet-instagram.md)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[sorunome/mx-puppet-instagram](https://hub.docker.com/r/sorunome/mx-puppet-instagram)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "Bridge for Instagram-DMs ([Instagram](https://www.instagram.com/))" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[mx-puppet-twitter](configuring-playbook-bridge-mx-puppet-twitter.md)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "[sorunome/mx-puppet-twitter](https://hub.docker.com/r/sorunome/mx-puppet-twitter)" -msgstr "" - -#: ../../../docs/container-images.md -msgid "Bridge for Twitter-DMs ([Twitter](https://twitter.com/))" +msgid "[mx-puppet-groupme](configuring-playbook-bridge-mx-puppet-groupme.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[mx-puppet-discord](configuring-playbook-bridge-mx-puppet-discord.md)" +msgid "[xangelix/mx-puppet-groupme](https://hub.docker.com/r/xangelix/mx-puppet-groupme)" msgstr "" #: ../../../docs/container-images.md -msgid "[mx-puppet/discord/mx-puppet-discord](https://gitlab.com/mx-puppet/discord/mx-puppet-discord/container_registry)" +msgid "Bridge to [GroupMe](https://groupme.com/)" msgstr "" #: ../../../docs/container-images.md -msgid "[mx-puppet-groupme](configuring-playbook-bridge-mx-puppet-groupme.md)" +msgid "[matrix-steam-bridge](configuring-playbook-bridge-steam.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[xangelix/mx-puppet-groupme](https://hub.docker.com/r/xangelix/mx-puppet-groupme)" +msgid "[jasonlaguidice/matrix-steam-bridge](https://github.com/jasonlaguidice/matrix-steam-bridge/pkgs/container/matrix-steam-bridge)" msgstr "" #: ../../../docs/container-images.md -msgid "Bridge to [GroupMe](https://groupme.com/)" +msgid "Bridge to [Steam](https://steampowered.com/)" msgstr "" #: ../../../docs/container-images.md @@ -696,11 +676,11 @@ msgstr "" msgid "Email to Matrix bridge" msgstr "" -#: ../../../docs/container-images.md:99 +#: ../../../docs/container-images.md:114 msgid "Bots" msgstr "" -#: ../../../docs/container-images.md:101 +#: ../../../docs/container-images.md:116 msgid "Bots provide various additional functionality to your installation." msgstr "" @@ -713,7 +693,7 @@ msgid "[etke.cc/baibot](https://ghcr.io/etkecc/baibot)" msgstr "" #: ../../../docs/container-images.md -msgid "A bot that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you" +msgid "Bot that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you" msgstr "" #: ../../../docs/container-images.md @@ -749,7 +729,7 @@ msgid "[dock.mau.dev/maubot/maubot](https://mau.dev/maubot/maubot/container_regi msgstr "" #: ../../../docs/container-images.md -msgid "A plugin-based Matrix bot system" +msgid "Plugin-based Matrix bot system" msgstr "" #: ../../../docs/container-images.md @@ -761,7 +741,7 @@ msgid "[etke.cc/honoroit](https://github.com/etkecc/honoroit/container_registry) msgstr "" #: ../../../docs/container-images.md -msgid "A helpdesk bot" +msgid "Helpdesk bot" msgstr "" #: ../../../docs/container-images.md @@ -773,7 +753,7 @@ msgid "[matrixdotorg/mjolnir](https://hub.docker.com/r/matrixdotorg/mjolnir)" msgstr "" #: ../../../docs/container-images.md -msgid "A moderation tool for Matrix" +msgid "Moderation tool for Matrix" msgstr "" #: ../../../docs/container-images.md @@ -785,7 +765,7 @@ msgid "[gnuxie/draupnir](https://hub.docker.com/r/gnuxie/draupnir)" msgstr "" #: ../../../docs/container-images.md -msgid "A moderation tool for Matrix (Fork of Mjolnir)" +msgid "Moderation tool for Matrix (Fork of Mjolnir)" msgstr "" #: ../../../docs/container-images.md @@ -800,11 +780,11 @@ msgstr "" msgid "Web forms (HTTP POST) to Matrix" msgstr "" -#: ../../../docs/container-images.md:114 +#: ../../../docs/container-images.md:129 msgid "Administration" msgstr "" -#: ../../../docs/container-images.md:116 +#: ../../../docs/container-images.md:131 msgid "Services that help you in administrating and monitoring your Matrix installation." msgstr "" @@ -833,15 +813,15 @@ msgid "OAuth 2.0 and OpenID Provider server" msgstr "" #: ../../../docs/container-images.md -msgid "[synapse-admin](configuring-playbook-synapse-admin.md)" +msgid "[ketesa](configuring-playbook-ketesa.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[etke.cc/synapse-admin](https://ghcr.io/etkecc/synapse-admin)" +msgid "[etkecc/ketesa](https://ghcr.io/etkecc/ketesa)" msgstr "" #: ../../../docs/container-images.md -msgid "A web UI tool for administrating users and rooms on your Matrix server" +msgid "Fully-featured web UI for administrating your Matrix homeserver — users, rooms, media, sessions, and more" msgstr "" #: ../../../docs/container-images.md @@ -873,7 +853,7 @@ msgid "Graphing tool that works well with the above two images. Our playbook als msgstr "" #: ../../../docs/container-images.md -msgid "[Metrics and Graphs](configuring-playbook-prometheus-nginxlog.md)" +msgid "[Metrics and Graphs](configuring-playbook-prometheus-grafana.md#enable-metrics-and-graphs-for-nginx-logs-optional)" msgstr "" #: ../../../docs/container-images.md @@ -893,51 +873,43 @@ msgid "Backups" msgstr "" #: ../../../docs/container-images.md -msgid "[rageshake](configuring-playbook-rageshake.md)" +msgid "[postgres-backup-local](configuring-playbook-postgres-backup.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[matrix-org/rageshake](https://ghcr.io/matrix-org/rageshake)" +msgid "[prodrigestivill/postgres-backup-local](https://hub.docker.com/r/prodrigestivill/postgres-backup-local)" msgstr "" #: ../../../docs/container-images.md -msgid "Bug report server" +msgid "Create automatic database backups" msgstr "" #: ../../../docs/container-images.md -msgid "[synapse-usage-exporter](configuring-playbook-synapse-usage-exporter.md)" +msgid "[rageshake](configuring-playbook-rageshake.md)" msgstr "" #: ../../../docs/container-images.md -msgid "Export the usage statistics of a Synapse homeserver to be scraped by Prometheus." -msgstr "" - -#: ../../../docs/container-images.md:131 -msgid "Misc" -msgstr "" - -#: ../../../docs/container-images.md:133 -msgid "Various services that don't fit any other categories." +msgid "[matrix-org/rageshake](https://ghcr.io/matrix-org/rageshake)" msgstr "" #: ../../../docs/container-images.md -msgid "[sliding-sync](configuring-playbook-sliding-sync-proxy.md)" +msgid "Bug report server" msgstr "" #: ../../../docs/container-images.md -msgid "[matrix-org/sliding-sync](https://ghcr.io/matrix-org/sliding-sync)" +msgid "[synapse-usage-exporter](configuring-playbook-synapse-usage-exporter.md)" msgstr "" #: ../../../docs/container-images.md -msgid "Sliding Sync support for clients which require it (like old Element X versions, before it got switched to Simplified Sliding Sync)" +msgid "Export the usage statistics of a Synapse homeserver to be scraped by Prometheus." msgstr "" -#: ../../../docs/container-images.md -msgid "[synapse_auto_accept_invite](configuring-playbook-synapse-auto-accept-invite.md)" +#: ../../../docs/container-images.md:147 +msgid "Misc" msgstr "" -#: ../../../docs/container-images.md -msgid "A Synapse module to automatically accept invites." +#: ../../../docs/container-images.md:149 +msgid "Various services that don't fit any other categories." msgstr "" #: ../../../docs/container-images.md @@ -945,11 +917,11 @@ msgid "[synapse_auto_compressor](configuring-playbook-synapse-auto-compressor.md msgstr "" #: ../../../docs/container-images.md -msgid "[etke.cc/rust-synapse-compress-state](https://gitlab.com/etke.cc/rust-synapse-compress-state/container_registry)" +msgid "[mb-saces/rust-synapse-tools](https://gitlab.com/mb-saces/rust-synapse-tools/container_registry)" msgstr "" #: ../../../docs/container-images.md -msgid "A cli tool that automatically compresses `state_groups` database table in background." +msgid "Cli tool that automatically compresses Synapse's `state_groups` database table in background" msgstr "" #: ../../../docs/container-images.md @@ -973,7 +945,7 @@ msgid "[etherpad/etherpad](https://hub.docker.com/r/etherpad/etherpad/)" msgstr "" #: ../../../docs/container-images.md -msgid "An open source collaborative text editor" +msgid "Open source collaborative text editor" msgstr "" #: ../../../docs/container-images.md @@ -985,7 +957,7 @@ msgid "[jitsi/web](https://hub.docker.com/r/jitsi/web)" msgstr "" #: ../../../docs/container-images.md -msgid "the [Jitsi](https://jitsi.org/) web UI" +msgid "[Jitsi](https://jitsi.org/) web UI" msgstr "" #: ../../../docs/container-images.md @@ -993,7 +965,7 @@ msgid "[jitsi/jicofo](https://hub.docker.com/r/jitsi/jicofo)" msgstr "" #: ../../../docs/container-images.md -msgid "the [Jitsi](https://jitsi.org/) Focus component" +msgid "[Jitsi](https://jitsi.org/) Focus component" msgstr "" #: ../../../docs/container-images.md @@ -1001,7 +973,7 @@ msgid "[jitsi/prosody](https://hub.docker.com/r/jitsi/prosody)" msgstr "" #: ../../../docs/container-images.md -msgid "the [Jitsi](https://jitsi.org/) Prosody XMPP server component" +msgid "[Jitsi](https://jitsi.org/) Prosody XMPP server component" msgstr "" #: ../../../docs/container-images.md @@ -1009,7 +981,7 @@ msgid "[jitsi/jvb](https://hub.docker.com/r/jitsi/jvb)" msgstr "" #: ../../../docs/container-images.md -msgid "the [Jitsi](https://jitsi.org/) Video Bridge component" +msgid "[Jitsi](https://jitsi.org/) Video Bridge component" msgstr "" #: ../../../docs/container-images.md @@ -1021,7 +993,7 @@ msgid "[cactuscomments/cactus-appservice](https://hub.docker.com/r/cactuscomment msgstr "" #: ../../../docs/container-images.md -msgid "A federated comment system built on Matrix" +msgid "Federated comment system built on Matrix" msgstr "" #: ../../../docs/container-images.md @@ -1037,7 +1009,7 @@ msgid "[matrixdotorg/pantalaimon](https://hub.docker.com/r/matrixdotorg/pantalai msgstr "" #: ../../../docs/container-images.md -msgid "An E2EE aware proxy daemon" +msgid "E2EE aware proxy daemon" msgstr "" #: ../../../docs/container-images.md @@ -1064,24 +1036,36 @@ msgstr "" msgid "Self-hosted, UnifiedPush-compatible push notifications server" msgstr "" -#: ../../../docs/container-images.md:152 +#: ../../../docs/container-images.md +msgid "[Element Call](configuring-playbook-element-call.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[element-hq/element-call](https://ghcr.io/element-hq/element-call)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "A native Matrix video conferencing application" +msgstr "" + +#: ../../../docs/container-images.md:167 msgid "Container images of deprecated / unmaintained services" msgstr "" -#: ../../../docs/container-images.md:154 +#: ../../../docs/container-images.md:169 msgid "The list of the deprecated or unmaintained services is available [here](configuring-playbook.md#deprecated--unmaintained--removed-services)." msgstr "" #: ../../../docs/container-images.md -msgid "[matrix-appservice-webhooks](configuring-playbook-bridge-appservice-webhooks.md)" +msgid "[conduwuit](configuring-playbook-conduwuit.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[turt2live/matrix-appservice-webhooks](https://hub.docker.com/r/turt2live/matrix-appservice-webhooks)" +msgid "[girlbossceo/conduwuit](https://ghcr.io/girlbossceo/conduwuit)" msgstr "" #: ../../../docs/container-images.md -msgid "Bridge for slack compatible webhooks ([ConcourseCI](https://concourse-ci.org/), [Slack](https://slack.com/) etc. pp.)" +msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. conduwuit was a fork of Conduit." msgstr "" #: ../../../docs/container-images.md @@ -1093,7 +1077,7 @@ msgid "[turt2live/matrix-dimension](https://hub.docker.com/r/turt2live/matrix-di msgstr "" #: ../../../docs/container-images.md -msgid "An open source integration manager for Matrix clients" +msgid "Open source integration manager for Matrix clients" msgstr "" #: ../../../docs/container-images.md @@ -1117,7 +1101,39 @@ msgid "[matrixdotorg/go-neb](https://hub.docker.com/r/matrixdotorg/go-neb)" msgstr "" #: ../../../docs/container-images.md -msgid "A multi functional bot written in Go" +msgid "Multi functional bot written in Go" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[ma1sd](configuring-playbook-ma1sd.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[ma1uta/ma1sd](https://hub.docker.com/r/ma1uta/ma1sd/)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Matrix Identity Server" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[matrix-appservice-slack](configuring-playbook-bridge-appservice-slack.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[matrixdotorg/matrix-appservice-slack](https://hub.docker.com/r/matrixdotorg/matrix-appservice-slack)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[matrix-appservice-webhooks](configuring-playbook-bridge-appservice-webhooks.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[turt2live/matrix-appservice-webhooks](https://hub.docker.com/r/turt2live/matrix-appservice-webhooks)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Bridge for slack compatible webhooks ([ConcourseCI](https://concourse-ci.org/), [Slack](https://slack.com/) etc. pp.)" msgstr "" #: ../../../docs/container-images.md @@ -1145,25 +1161,77 @@ msgid "Bridge to [Facebook](https://facebook.com/)" msgstr "" #: ../../../docs/container-images.md -msgid "[mautrix-hangouts](configuring-playbook-bridge-mautrix-hangouts.md)" +msgid "[mautrix-instagram](configuring-playbook-bridge-mautrix-instagram.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[mautrix/hangouts](https://mau.dev/mautrix/hangouts/container_registry)" +msgid "[mautrix/instagram](https://mau.dev/mautrix/instagram/container_registry)" msgstr "" #: ../../../docs/container-images.md -msgid "Bridge to [Google Hangouts](https://en.wikipedia.org/wiki/Google_Hangouts)" +msgid "Bridge to [Instagram](https://instagram.com/)" msgstr "" #: ../../../docs/container-images.md -msgid "[mautrix-instagram](configuring-playbook-bridge-mautrix-instagram.md)" +msgid "[mx-puppet-discord](configuring-playbook-bridge-mx-puppet-discord.md)" msgstr "" #: ../../../docs/container-images.md -msgid "[mautrix/instagram](https://mau.dev/mautrix/instagram/container_registry)" +msgid "[mx-puppet/discord/mx-puppet-discord](https://gitlab.com/mx-puppet/discord/mx-puppet-discord/container_registry)" msgstr "" #: ../../../docs/container-images.md -msgid "Bridge to [Instagram](https://instagram.com/)" +msgid "[mx-puppet-instagram](configuring-playbook-bridge-mx-puppet-instagram.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[sorunome/mx-puppet-instagram](https://hub.docker.com/r/sorunome/mx-puppet-instagram)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Bridge for Instagram-DMs ([Instagram](https://www.instagram.com/))" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[mx-puppet-slack](configuring-playbook-bridge-mx-puppet-slack.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[mx-puppet/slack/mx-puppet-slack](https://gitlab.com/mx-puppet/slack/mx-puppet-slack/container_registry)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Bridge to [Slack](https://slack.com)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[mx-puppet-twitter](configuring-playbook-bridge-mx-puppet-twitter.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[sorunome/mx-puppet-twitter](https://hub.docker.com/r/sorunome/mx-puppet-twitter)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Bridge for Twitter-DMs ([Twitter](https://twitter.com/))" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[sliding-sync](configuring-playbook-sliding-sync-proxy.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[matrix-org/sliding-sync](https://ghcr.io/matrix-org/sliding-sync)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Sliding Sync support for clients which require it (like old Element X versions, before it got switched to Simplified Sliding Sync)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "[synapse_auto_accept_invite](configuring-playbook-synapse-auto-accept-invite.md)" +msgstr "" + +#: ../../../docs/container-images.md +msgid "Synapse module to automatically accept invites" msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/registering-users.po b/i18n/locales/jp/LC_MESSAGES/docs/registering-users.po index 7e203701f..7043cb1cd 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/registering-users.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/registering-users.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-27 09:54+0200\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,228 +18,225 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/registering-users.md:1 +#: ../../../docs/registering-users.md:11 msgid "Registering users" msgstr "" -#: ../../../docs/registering-users.md:3 +#: ../../../docs/registering-users.md:13 msgid "This documentation page tells you how to create user accounts on your Matrix server." msgstr "" -#: ../../../docs/registering-users.md:5 +#: ../../../docs/registering-users.md:15 msgid "Table of contents:" msgstr "" -#: ../../../docs/registering-users.md:7 +#: ../../../docs/registering-users.md:16 msgid "[Registering users](#registering-users)" msgstr "" -#: ../../../docs/registering-users.md:8 +#: ../../../docs/registering-users.md:17 msgid "[Registering users manually](#registering-users-manually)" msgstr "" -#: ../../../docs/registering-users.md:9 +#: ../../../docs/registering-users.md:18 msgid "[Managing users via a Web UI](#managing-users-via-a-web-ui)" msgstr "" -#: ../../../docs/registering-users.md:10 +#: ../../../docs/registering-users.md:19 msgid "[Letting certain users register on your private server](#letting-certain-users-register-on-your-private-server)" msgstr "" -#: ../../../docs/registering-users.md:11 +#: ../../../docs/registering-users.md:20 msgid "[Enabling public user registration](#enabling-public-user-registration)" msgstr "" -#: ../../../docs/registering-users.md:12 +#: ../../../docs/registering-users.md:21 msgid "[Adding/Removing Administrator privileges to an existing user](#addingremoving-administrator-privileges-to-an-existing-user)" msgstr "" -#: ../../../docs/registering-users.md:14 +#: ../../../docs/registering-users.md:23 msgid "Registering users manually" msgstr "" -#: ../../../docs/registering-users.md:16 ../../../docs/registering-users.md:121 +#: ../../../docs/registering-users.md:25 ../../../docs/registering-users.md:127 msgid "**Notes**:" msgstr "" -#: ../../../docs/registering-users.md:17 +#: ../../../docs/registering-users.md:26 msgid "Make sure to adjust `USERNAME_HERE` and `PASSWORD_HERE`" msgstr "" -#: ../../../docs/registering-users.md:18 +#: ../../../docs/registering-users.md:27 msgid "For `USERNAME_HERE`, use a plain username like `alice`, not a full ID (`@alice:example.com`)" msgstr "" -#: ../../../docs/registering-users.md:19 +#: ../../../docs/registering-users.md:28 msgid "Use `admin=yes` or `admin=no` depending on whether you wish to make the user an administrator of the Matrix server" msgstr "" -#: ../../../docs/registering-users.md:21 +#: ../../../docs/registering-users.md:30 msgid "After registering a user (using one of the methods below), **you can log in with that user** via the [Element Web](configuring-playbook-client-element-web.md) service that this playbook has installed for you at a URL like this: `https://element.example.com/`." msgstr "" -#: ../../../docs/registering-users.md:23 +#: ../../../docs/registering-users.md:32 msgid "Registering users via the Ansible playbook" msgstr "" -#: ../../../docs/registering-users.md:25 +#: ../../../docs/registering-users.md:34 msgid "It's best to register users via the Ansible playbook, because it works regardless of homeserver implementation (Synapse, Dendrite, etc) or usage of [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) (MAS)." msgstr "" -#: ../../../docs/registering-users.md:27 +#: ../../../docs/registering-users.md:36 msgid "To register a user via this Ansible playbook:" msgstr "" -#: ../../../docs/registering-users.md:35 +#: ../../../docs/registering-users.md:44 msgid "**or** by invoking `ansible-playbook` manually:" msgstr "" -#: ../../../docs/registering-users.md:43 +#: ../../../docs/registering-users.md:52 msgid "Feel free to register as many users (for friends, family, etc.) as you want. Still, perhaps you should grant full administrative access to your user account only (with `admin=yes`), and others should be created with `admin=no`." msgstr "" -#: ../../../docs/registering-users.md:45 +#: ../../../docs/registering-users.md:54 msgid "[!WARNING] If you're registering users against Matrix Authentication Service, do note that it [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user. Upon a user's first login, they will be asked to confirm their email address. This requires that email sending is [configured](./configuring-playbook-email.md). You can also consult the [Working around email deliverability issues](./configuring-playbook-matrix-authentication-service.md#working-around-email-deliverability-issues) section for more information." msgstr "" -#: ../../../docs/registering-users.md:48 +#: ../../../docs/registering-users.md:57 msgid "Registering users manually for Synapse" msgstr "" -#: ../../../docs/registering-users.md:50 +#: ../../../docs/registering-users.md:59 msgid "If you're using the [Synapse](configuring-playbook-synapse.md) homeserver implementation (which is the default), you can register users via the command-line after **SSH**-ing to your server (requires that [all services have been started](installing.md#install-matrix-server-and-services)):" msgstr "" -#: ../../../docs/registering-users.md:58 +#: ../../../docs/registering-users.md:67 msgid "Registering users manually for Dendrite" msgstr "" -#: ../../../docs/registering-users.md:60 +#: ../../../docs/registering-users.md:69 msgid "If you're using the [Dendrite](./configuring-playbook-dendrite.md) homeserver implementation, you can register users via the command-line after **SSH**-ing to your server (requires that [all services have been started](installing.md#install-matrix-server-and-services)):" msgstr "" -#: ../../../docs/registering-users.md:68 +#: ../../../docs/registering-users.md:77 msgid "Registering users manually for Matrix Authentication Service" msgstr "" -#: ../../../docs/registering-users.md:70 +#: ../../../docs/registering-users.md:79 msgid "If you're using the [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) and your existing homeserver (most likely [Synapse](./configuring-playbook-synapse.md)) is delegating authentication to it, you can register users via the command-line after **SSH**-ing to your server (requires that [all services have been started](installing.md#install-matrix-server-and-services)):" msgstr "" -#: ../../../docs/registering-users.md:78 +#: ../../../docs/registering-users.md:87 msgid "This `register-user` script actually invokes the `mas-cli manage register-user` command under the hood. If you'd like more control over the registration process, consider invoking the `mas-cli` command directly:" msgstr "" -#: ../../../docs/registering-users.md:84 +#: ../../../docs/registering-users.md:93 msgid "[!WARNING] Matrix Authentication Service [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user. Upon a user's first login, they will be asked to confirm their email address. This requires that email sending is [configured](./configuring-playbook-email.md). You can also consult the [Working around email deliverability issues](./configuring-playbook-matrix-authentication-service.md#working-around-email-deliverability-issues) section for more information." msgstr "" -#: ../../../docs/registering-users.md:87 +#: ../../../docs/registering-users.md:96 msgid "Managing users via a Web UI" msgstr "" -#: ../../../docs/registering-users.md:89 -msgid "To manage users more easily (via a web user-interace), you can install [Synapse Admin](configuring-playbook-synapse-admin.md)." -msgstr "" - -#: ../../../docs/registering-users.md:91 -msgid "[!WARNING] If you're using [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md), note that user management via synapse-admin is not fully working yet. See the [Expectations](configuring-playbook-matrix-authentication-service.md#expectations) section for more information." +#: ../../../docs/registering-users.md:98 +msgid "To manage users and your homeserver more easily (via a web interface), you can install [Ketesa](configuring-playbook-ketesa.md) — a fully-featured admin UI covering users, rooms, media, sessions, and MAS management." msgstr "" -#: ../../../docs/registering-users.md:94 +#: ../../../docs/registering-users.md:100 msgid "Letting certain users register on your private server" msgstr "" -#: ../../../docs/registering-users.md:96 +#: ../../../docs/registering-users.md:102 msgid "If you'd rather **keep your server private** (public registration closed, as is the default), and **let certain people create accounts by themselves** (instead of creating user accounts manually like this), consider installing and making use of [matrix-registration](configuring-playbook-matrix-registration.md)." msgstr "" -#: ../../../docs/registering-users.md:98 +#: ../../../docs/registering-users.md:104 msgid "Enabling public user registration" msgstr "" -#: ../../../docs/registering-users.md:100 +#: ../../../docs/registering-users.md:106 msgid "To **open up user registration publicly** (usually **not recommended**), add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/registering-users.md:102 +#: ../../../docs/registering-users.md:108 msgid "For Synapse:" msgstr "" -#: ../../../docs/registering-users.md:108 +#: ../../../docs/registering-users.md:114 msgid "For Dendrite:" msgstr "" -#: ../../../docs/registering-users.md:114 +#: ../../../docs/registering-users.md:120 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/registering-users.md:123 +#: ../../../docs/registering-users.md:129 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/registering-users.md:125 +#: ../../../docs/registering-users.md:131 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/registering-users.md:127 +#: ../../../docs/registering-users.md:133 msgid "If you're opening up registrations publicly like this, you might also wish to [configure CAPTCHA protection](configuring-captcha.md)." msgstr "" -#: ../../../docs/registering-users.md:129 +#: ../../../docs/registering-users.md:135 msgid "Adding/Removing Administrator privileges to an existing user" msgstr "" -#: ../../../docs/registering-users.md:131 +#: ../../../docs/registering-users.md:137 msgid "Adding/Removing Administrator privileges to an existing user in Synapse" msgstr "" -#: ../../../docs/registering-users.md:133 +#: ../../../docs/registering-users.md:139 msgid "To change the admin privileges for a user in Synapse's local database, you need to run an SQL query like this against the `synapse` database:" msgstr "" -#: ../../../docs/registering-users.md:139 +#: ../../../docs/registering-users.md:145 msgid "where:" msgstr "" -#: ../../../docs/registering-users.md:141 +#: ../../../docs/registering-users.md:147 msgid "`ADMIN_VALUE` being either `0` (regular user) or `1` (admin)" msgstr "" -#: ../../../docs/registering-users.md:142 +#: ../../../docs/registering-users.md:148 msgid "`USER` and `example.com` pointing to a valid user on your server" msgstr "" -#: ../../../docs/registering-users.md:144 +#: ../../../docs/registering-users.md:150 msgid "If you're using the integrated Postgres server and not an [external Postgres server](configuring-playbook-external-postgres.md), you can launch a Postgres into the `synapse` database by:" msgstr "" -#: ../../../docs/registering-users.md:146 +#: ../../../docs/registering-users.md:152 msgid "running `/matrix/postgres/bin/cli` — to launch [`psql`](https://www.postgresql.org/docs/current/app-psql.html)" msgstr "" -#: ../../../docs/registering-users.md:147 +#: ../../../docs/registering-users.md:153 msgid "running `\\c synapse` — to change to the `synapse` database" msgstr "" -#: ../../../docs/registering-users.md:149 +#: ../../../docs/registering-users.md:155 msgid "You can then proceed to run the query above." msgstr "" -#: ../../../docs/registering-users.md:151 +#: ../../../docs/registering-users.md:157 msgid "**Note**: directly modifying the raw data of Synapse (or any other software) could cause the software to break. You've been warned!" msgstr "" -#: ../../../docs/registering-users.md:153 +#: ../../../docs/registering-users.md:159 msgid "Adding/Removing Administrator privileges to an existing user in Matrix Authentication Service" msgstr "" -#: ../../../docs/registering-users.md:155 -msgid "Promoting/demoting a user in Matrix Authentication Service cannot currently (2024-10-19) be done via the [`mas-cli` Management tool](./configuring-playbook-matrix-authentication-service.md#management)." +#: ../../../docs/registering-users.md:161 +msgid "Promoting/demoting a user in Matrix Authentication Service can be done using the [`mas-cli`](./configuring-playbook-matrix-authentication-service.md#management) management tool's [`manage promote-admin`](https://element-hq.github.io/matrix-authentication-service/reference/cli/manage.html#manage-promote-admin) and [`manage demote-admin`](https://element-hq.github.io/matrix-authentication-service/reference/cli/manage.html#manage-demote-admin) commands. For example: `/matrix/matrix-authentication-service/bin/mas-cli manage promote-admin some.username`." msgstr "" -#: ../../../docs/registering-users.md:157 -msgid "You can do it via the [MAS Admin API](https://element-hq.github.io/matrix-authentication-service/api/index.html)'s `POST /api/admin/v1/users/{id}/set-admin` endpoint." +#: ../../../docs/registering-users.md:163 +#, python-brace-format +msgid "You can also do it via the [MAS Admin API](https://element-hq.github.io/matrix-authentication-service/api/index.html)'s `POST /api/admin/v1/users/{id}/set-admin` endpoint." msgstr "" diff --git a/i18n/locales/jp/LC_MESSAGES/docs/self-building.po b/i18n/locales/jp/LC_MESSAGES/docs/self-building.po index 1da0b78a1..ead4121ae 100644 --- a/i18n/locales/jp/LC_MESSAGES/docs/self-building.po +++ b/i18n/locales/jp/LC_MESSAGES/docs/self-building.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-16 12:05+0900\n" +"POT-Creation-Date: 2026-04-03 12:09+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: jp\n" @@ -18,160 +18,136 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.16.0\n" +"Generated-By: Babel 2.18.0\n" -#: ../../../docs/self-building.md:1 +#: ../../../docs/self-building.md:15 msgid "Self-building" msgstr "" -#: ../../../docs/self-building.md:3 +#: ../../../docs/self-building.md:17 msgid "**Caution: self-building does not have to be used on its own. See the [Alternative Architectures](alternative-architectures.md) page.**" msgstr "" -#: ../../../docs/self-building.md:5 +#: ../../../docs/self-building.md:19 msgid "The playbook supports self-building of various components, which don't have a container image for your architecture (see the [container images we use](container-images.md)). For `amd64`, self-building is not required." msgstr "" -#: ../../../docs/self-building.md:7 +#: ../../../docs/self-building.md:21 msgid "For other architectures (e.g. `arm32`, `arm64`), ready-made container images are used when available. If there's no ready-made image for a specific component and said component supports self-building, an image will be built on the host. Building images like this takes more time and resources (some build tools need to get installed by the playbook to assist building)." msgstr "" -#: ../../../docs/self-building.md:9 +#: ../../../docs/self-building.md:23 msgid "To make use of self-building, you don't need to do anything. If a component has an image for the specified architecture, the playbook will use it directly. If not, it will build the image on the server itself." msgstr "" -#: ../../../docs/self-building.md:11 +#: ../../../docs/self-building.md:25 msgid "Note that **not all components support self-building yet**." msgstr "" -#: ../../../docs/self-building.md:13 +#: ../../../docs/self-building.md:27 msgid "Possibly outdated list of roles where self-building the Docker image is currently possible:" msgstr "" -#: ../../../docs/self-building.md:14 +#: ../../../docs/self-building.md:28 msgid "`matrix-synapse`" msgstr "" -#: ../../../docs/self-building.md:15 -msgid "`matrix-synapse-admin`" +#: ../../../docs/self-building.md:29 +msgid "`matrix-ketesa`" msgstr "" -#: ../../../docs/self-building.md:16 +#: ../../../docs/self-building.md:30 msgid "`matrix-client-element`" msgstr "" -#: ../../../docs/self-building.md:17 -msgid "`matrix-client-hydrogen`" -msgstr "" - -#: ../../../docs/self-building.md:18 -msgid "`matrix-client-cinny`" +#: ../../../docs/self-building.md:31 +msgid "`hydrogen`" msgstr "" -#: ../../../docs/self-building.md:19 -msgid "`matrix-registration`" +#: ../../../docs/self-building.md:32 +msgid "`cinny`" msgstr "" -#: ../../../docs/self-building.md:20 -msgid "`matrix-coturn`" +#: ../../../docs/self-building.md:33 +msgid "`sable`" msgstr "" -#: ../../../docs/self-building.md:21 -msgid "`matrix-corporal`" +#: ../../../docs/self-building.md:34 +msgid "`matrix-registration`" msgstr "" -#: ../../../docs/self-building.md:22 -msgid "`matrix-dimension`" +#: ../../../docs/self-building.md:35 +msgid "`coturn`" msgstr "" -#: ../../../docs/self-building.md:23 -msgid "`matrix-ma1sd`" +#: ../../../docs/self-building.md:36 +msgid "`matrix-corporal`" msgstr "" -#: ../../../docs/self-building.md:24 +#: ../../../docs/self-building.md:37 msgid "`exim-relay`" msgstr "" -#: ../../../docs/self-building.md:25 +#: ../../../docs/self-building.md:38 msgid "`matrix-bridge-hookshot`" msgstr "" -#: ../../../docs/self-building.md:26 +#: ../../../docs/self-building.md:39 msgid "`matrix-bridge-appservice-irc`" msgstr "" -#: ../../../docs/self-building.md:27 -msgid "`matrix-bridge-appservice-slack`" -msgstr "" - -#: ../../../docs/self-building.md:28 -msgid "`matrix-bridge-appservice-webhooks`" -msgstr "" - -#: ../../../docs/self-building.md:29 +#: ../../../docs/self-building.md:40 msgid "`matrix-bridge-beeper-linkedin`" msgstr "" -#: ../../../docs/self-building.md:30 -msgid "`matrix-bridge-mautrix-facebook`" -msgstr "" - -#: ../../../docs/self-building.md:31 -msgid "`matrix-bridge-mautrix-hangouts`" -msgstr "" - -#: ../../../docs/self-building.md:32 +#: ../../../docs/self-building.md:41 msgid "`matrix-bridge-mautrix-googlechat`" msgstr "" -#: ../../../docs/self-building.md:33 +#: ../../../docs/self-building.md:42 msgid "`matrix-bridge-mautrix-telegram`" msgstr "" -#: ../../../docs/self-building.md:34 +#: ../../../docs/self-building.md:43 msgid "`matrix-bridge-mautrix-signal`" msgstr "" -#: ../../../docs/self-building.md:35 +#: ../../../docs/self-building.md:44 msgid "`matrix-bridge-mautrix-gmessages`" msgstr "" -#: ../../../docs/self-building.md:36 +#: ../../../docs/self-building.md:45 msgid "`matrix-bridge-mautrix-whatsapp`" msgstr "" -#: ../../../docs/self-building.md:37 +#: ../../../docs/self-building.md:46 msgid "`matrix-bridge-mx-puppet-steam`" msgstr "" -#: ../../../docs/self-building.md:38 +#: ../../../docs/self-building.md:47 msgid "`matrix-bot-mjolnir`" msgstr "" -#: ../../../docs/self-building.md:39 +#: ../../../docs/self-building.md:48 msgid "`matrix-bot-honoroit`" msgstr "" -#: ../../../docs/self-building.md:40 +#: ../../../docs/self-building.md:49 msgid "`matrix-bot-matrix-reminder-bot`" msgstr "" -#: ../../../docs/self-building.md:41 +#: ../../../docs/self-building.md:50 msgid "`matrix-bot-maubot`" msgstr "" -#: ../../../docs/self-building.md:42 -msgid "`matrix-email2matrix`" -msgstr "" - -#: ../../../docs/self-building.md:43 +#: ../../../docs/self-building.md:51 msgid "`matrix-pantalaimon`" msgstr "" -#: ../../../docs/self-building.md:45 +#: ../../../docs/self-building.md:53 msgid "Adding self-building support to other roles is welcome. Feel free to contribute!" msgstr "" -#: ../../../docs/self-building.md:47 +#: ../../../docs/self-building.md:55 msgid "If you'd like **to force self-building** even if an image is available for your architecture, look into the `matrix_*_self_build` variables provided by individual roles." msgstr "" diff --git a/i18n/requirements.txt b/i18n/requirements.txt index 972f6bbfb..6676e8c17 100644 --- a/i18n/requirements.txt +++ b/i18n/requirements.txt @@ -1,27 +1,27 @@ alabaster==1.0.0 babel==2.18.0 -certifi==2026.2.25 -charset-normalizer==3.4.6 -click==8.3.1 +certifi==2026.7.22 +charset-normalizer==3.5.1 +click==8.5.0 docutils==0.22.4 -idna==3.11 -imagesize==2.0.0 +idna==3.19 +imagesize==2.0.1 Jinja2==3.1.6 -linkify-it-py==2.1.0 -markdown-it-py==4.0.0 +linkify-it-py==2.2.0 +markdown-it-py==4.2.0 MarkupSafe==3.0.3 -mdit-py-plugins==0.5.0 +mdit-py-plugins==0.6.1 mdurl==0.1.2 -myst-parser==5.0.0 -packaging==26.0 -Pygments==2.20.0 +myst-parser==5.1.0 +packaging==26.3 +Pygments==2.21.0 PyYAML==6.0.3 -requests==2.33.0 -setuptools==82.0.1 -snowballstemmer==3.0.1 +requests==2.34.2 +setuptools==84.0.0 +snowballstemmer==3.1.1 Sphinx==9.1.0 -sphinx-intl==2.3.2 -sphinx-markdown-builder==0.6.10 +sphinx-intl==2.4.0 +sphinx-markdown-builder==0.6.11 sphinxcontrib-applehelp==2.0.0 sphinxcontrib-devhelp==2.0.0 sphinxcontrib-htmlhelp==2.1.0 @@ -30,4 +30,4 @@ sphinxcontrib-qthelp==2.0.0 sphinxcontrib-serializinghtml==2.0.0 tabulate==0.10.0 uc-micro-py==2.0.0 -urllib3==2.6.3 +urllib3==2.7.0 diff --git a/i18n/translation-templates/AGENTS.pot b/i18n/translation-templates/AGENTS.pot new file mode 100644 index 000000000..6e7ea1184 --- /dev/null +++ b/i18n/translation-templates/AGENTS.pot @@ -0,0 +1,109 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-18 04:11+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../AGENTS.md:7 +msgid "Guidance for AI agents" +msgstr "" + +#: ../../../AGENTS.md:9 +msgid "This file gives AI coding agents the minimum context for working on this repository. Human contributors may find it a useful summary too." +msgstr "" + +#: ../../../AGENTS.md:11 +msgid "What this is" +msgstr "" + +#: ../../../AGENTS.md:13 +msgid "An Ansible playbook that installs and manages a Matrix homeserver and dozens of related services, each running as a Docker container wrapped in a systemd service." +msgstr "" + +#: ../../../AGENTS.md:15 +msgid "Layout" +msgstr "" + +#: ../../../AGENTS.md:17 +msgid "`setup.yml`: the main playbook, listing all roles." +msgstr "" + +#: ../../../AGENTS.md:18 +msgid "`roles/custom/`: roles maintained in this repository." +msgstr "" + +#: ../../../AGENTS.md:19 +msgid "`roles/galaxy/`: external roles, downloaded according to `requirements.yml` via [agru](https://github.com/etkecc/agru) (preferred) or `ansible-galaxy`. Run `just roles` to install them (or `just update` to also pull the playbook itself). Editing these roles locally is fine while preparing or testing a fix, but the changes get wiped on the next roles update, so they must be synced back to the role's upstream repository, followed by a version pin update in `requirements.yml`." +msgstr "" + +#: ../../../AGENTS.md:20 +msgid "`group_vars/matrix_servers`: wires roles together (feeding one role's variables into another). Values a role can construct by itself belong in the role's `defaults/main.yml`, not here." +msgstr "" + +#: ../../../AGENTS.md:21 +msgid "`docs/`: user-facing documentation, one page per component." +msgstr "" + +#: ../../../AGENTS.md:22 +msgid "`i18n/`: translation infrastructure. Do not edit locale files by hand; they are managed by automation." +msgstr "" + +#: ../../../AGENTS.md:23 +msgid "`CHANGELOG.md`: user-facing announcements, newest first." +msgstr "" + +#: ../../../AGENTS.md:25 +msgid "Conventions" +msgstr "" + +#: ../../../AGENTS.md:27 +msgid "Follow the [style guide for playbook developers](docs/style-guide.md). In particular:" +msgstr "" + +#: ../../../AGENTS.md:29 +msgid "Variable prefixes match the role directory name." +msgstr "" + +#: ../../../AGENTS.md:30 +msgid "Playbook-extensible list variables use the `_auto` + `_custom` split; `_custom` is reserved for users." +msgstr "" + +#: ../../../AGENTS.md:31 +msgid "Renamed or removed variables get a validation entry, so stale user configuration produces an error instead of being silently ignored. Each role deprecates its own variables in its `validate_config.yml`; the `matrix_playbook_migration` role covers eliminated roles and very-early validation, and also gates breaking changes via `matrix_playbook_migration_expected_version` (see the style guide)." +msgstr "" + +#: ../../../AGENTS.md:32 +msgid "Every file carries SPDX license headers ([REUSE](https://reuse.software/) specification)." +msgstr "" + +#: ../../../AGENTS.md:33 +msgid "New components must be registered in `setup.yml`, `group_vars/matrix_servers`, `docs/README.md`, `README.md`, `docs/container-images.md`, and get a `CHANGELOG.md` entry." +msgstr "" + +#: ../../../AGENTS.md:35 +msgid "Other notes" +msgstr "" + +#: ../../../AGENTS.md:37 +msgid "Documentation examples use `example.com`, `@alice:example.com`, and the other placeholder values listed in the style guide." +msgstr "" + +#: ../../../AGENTS.md:38 +msgid "Write role tasks concurrency-safe: use `ansible.builtin.tempfile` for temporary files (removed in an `always` block), never fixed shared paths." +msgstr "" + +#: ../../../AGENTS.md:39 +msgid "One logical change per commit." +msgstr "" diff --git a/i18n/translation-templates/CHANGELOG.pot b/i18n/translation-templates/CHANGELOG.pot index 61b4ea062..40de00c89 100644 --- a/i18n/translation-templates/CHANGELOG.pot +++ b/i18n/translation-templates/CHANGELOG.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-13 05:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,7851 +17,9046 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #: ../../../CHANGELOG.md:1 +msgid "2026-08-13" +msgstr "" + +#: ../../../CHANGELOG.md:3 +msgid "The homeserver root path redirects to clients other than Element Web" +msgstr "" + +#: ../../../CHANGELOG.md:5 +msgid "Visiting `https://matrix.example.com/` used to redirect you to [Element Web](docs/configuring-playbook-client-element-web.md), but only if Element Web was the client installed by the playbook. With any of the other web clients (Cinny, Commet, FluffyChat, Hydrogen, SchildiChat, Sable), you would land on a bare Synapse page." +msgstr "" + +#: ../../../CHANGELOG.md:7 +msgid "The redirection now follows whichever of these clients you have enabled. When several are enabled, Element Web wins, followed by the others in the order that [`group_vars/matrix_servers`](group_vars/matrix_servers) lists them." +msgstr "" + +#: ../../../CHANGELOG.md:9 +msgid "To send people somewhere else (or nowhere at all), define `matrix_playbook_public_client_root_redirection_url` in your `vars.yml` file. An empty value disables the redirection." +msgstr "" + +#: ../../../CHANGELOG.md:11 +msgid "Support for Meowlnir" +msgstr "" + +#: ../../../CHANGELOG.md:13 +msgid "The playbook can now install [Meowlnir](https://github.com/maunium/meowlnir), an opinionated Matrix moderation bot, optimized for Synapse." +msgstr "" + +#: ../../../CHANGELOG.md:15 +msgid "Meowlnir joins [Draupnir](docs/configuring-playbook-bot-draupnir.md) and [Mjolnir](docs/configuring-playbook-bot-mjolnir.md) as a 3rd moderation option, speaking the same [policy list](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists) protocol so that it can subscribe to the same community ban lists. Unlike the others, it can override individual policies coming from lists you do not control (by way of an unban policy in a list of your own which is ordered ahead of other policy lists)." +msgstr "" + +#: ../../../CHANGELOG.md:17 +msgid "You can run it alongside Draupnir while evaluating it — see the documentation for the caveats, the main one being that both want the [synapse-http-antispam](https://github.com/maunium/synapse-http-antispam) module, which only reports to a single consumer." +msgstr "" + +#: ../../../CHANGELOG.md:19 +msgid "To get started, see the [Setting up Meowlnir](docs/configuring-playbook-bot-meowlnir.md) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:22 +msgid "2026-08-06" +msgstr "" + +#: ../../../CHANGELOG.md:24 +msgid "(Backward Compatibility Break) Jitsi no longer uses Colibri WebSockets" +msgstr "" + +#: ../../../CHANGELOG.md:26 +msgid "This only affects you if you have [Jitsi](docs/configuring-playbook-jitsi.md) enabled." +msgstr "" + +#: ../../../CHANGELOG.md:28 +msgid "Jitsi has been updated to `stable-11146-1`, which [removes Colibri WebSocket support](https://github.com/jitsi/docker-jitsi-meet/pull/2285) in favour of SCTP data channels. The Jitsi Video Bridge no longer serves HTTP at all, so a few `jitsi_jvb_*` variables are gone. The playbook will tell you which ones, if your configuration still sets them." +msgstr "" + +#: ../../../CHANGELOG.md:30 +msgid "If you run [additional JVBs on other hosts](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md#set-up-additional-jvbs-for-more-video-conferences-optional), the Traefik configuration which routed `/colibri-ws//` to them is now dead and can be removed. Nothing will warn you about that one, as it lives in a free-form `traefik_provider_configuration_extension_yaml` block." +msgstr "" + +#: ../../../CHANGELOG.md:32 +msgid "2026-07-28" +msgstr "" + +#: ../../../CHANGELOG.md:34 +msgid "(Backward Compatibility Break) ntfy users are now declared with hashed passwords" +msgstr "" + +#: ../../../CHANGELOG.md:36 +msgid "This only affects you if you have enabled authentication for [ntfy](docs/configuring-playbook-ntfy.md) via `ntfy_credentials`." +msgstr "" + +#: ../../../CHANGELOG.md:38 +msgid "The ntfy role used to create users by invoking `ntfy user` commands against the running container. Since v2.14.0, ntfy can provision users and access-control entries from its own configuration file, so the role now does that instead. Besides being a lot simpler, this fixes passwords containing spaces never arriving intact." +msgstr "" + +#: ../../../CHANGELOG.md:40 +msgid "Replace `ntfy_credentials` with `ntfy_auth_users_custom`, which takes bcrypt password hashes rather than plaintext passwords:" +msgstr "" + +#: ../../../CHANGELOG.md:49 +msgid "Generate a hash for each of your passwords by running the following command on any machine which has Docker installed. It asks for the password and prints its hash:" +msgstr "" + +#: ../../../CHANGELOG.md:55 +msgid "The playbook will let you know if your configuration still uses `ntfy_credentials`." +msgstr "" + +#: ../../../CHANGELOG.md:57 +msgid "Your existing ntfy users are left alone and keep working until you declare them again this way. Note that ntfy manages declared users and access-control entries declaratively, so removing one from your configuration later deletes it from ntfy's user database." +msgstr "" + +#: ../../../CHANGELOG.md:59 +msgid "Users with the `admin` role get access to all topics. Others start with no access at all, and can be granted access to specific topics via `ntfy_auth_access_custom`. It is also now possible to control what unauthenticated visitors may do (`ntfy_auth_default_access`) and whether users may log in at all (`ntfy_enable_login`, which follows your authentication setup by default). See the role's [documentation on access control](https://github.com/mother-of-all-self-hosting/ansible-role-ntfy/blob/main/docs/configuring-ntfy.md#enable-access-control-with-authentication-optional) for details." +msgstr "" + +#: ../../../CHANGELOG.md:61 +msgid "Support for bridging to LinkedIn via mautrix-linkedin" +msgstr "" + +#: ../../../CHANGELOG.md:63 +msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook now supports bridging to [LinkedIn](https://www.linkedin.com/) via [mautrix-linkedin](https://github.com/mautrix/linkedin)." +msgstr "" + +#: ../../../CHANGELOG.md:65 +msgid "Logging in requires copying a request out of your browser's developer tools, and only works with Chrome or another Chrome-based browser. To learn more, see our [Setting up Mautrix LinkedIn bridging](./docs/configuring-playbook-bridge-mautrix-linkedin.md) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:67 +msgid "This bridge supersedes [beeper-linkedin](./docs/configuring-playbook-bridge-beeper-linkedin.md), which is now considered unmaintained (its [upstream repository](https://github.com/beeper/linkedin) has been archived). The old bridge remains installable, but you may wish to switch. Both bridges claim the same appservice namespaces, so the playbook refuses to install mautrix-linkedin while beeper-linkedin is still enabled." +msgstr "" + +#: ../../../CHANGELOG.md:69 +msgid "Support for bridging to LINE via beeper-line" +msgstr "" + +#: ../../../CHANGELOG.md:71 +msgid "Thanks to [Co van Leeuwen](https://github.com/c00), the playbook can now bridge [LINE](https://line.me/) via [beeper-line](https://github.com/beeper/line), a bridge based on the modern mautrix bridge framework. It supports LINE accounts with Letter Sealing enabled or disabled and bridges messages, media, reactions, replies, receipts, and other common chat features." +msgstr "" + +#: ../../../CHANGELOG.md:73 +msgid "The bridge identifies itself as a LINE Chrome Extension client, so it cannot be used at the same time as the real LINE Chrome Extension. See [Setting up Beeper LINE bridging](docs/configuring-playbook-bridge-beeper-line.md) to get started." +msgstr "" + +#: ../../../CHANGELOG.md:76 +msgid "2026-07-19" +msgstr "" + +#: ../../../CHANGELOG.md:78 +msgid "Tuwunel now exposes its administration and /_tuwunel API paths" +msgstr "" + +#: ../../../CHANGELOG.md:80 +msgid "The [Tuwunel](docs/configuring-playbook-tuwunel.md) role previously routed only the `/_matrix` path through the reverse proxy. It now also exposes the two other API paths that Tuwunel serves." +msgstr "" + +#: ../../../CHANGELOG.md:82 +msgid "The Synapse-compatible administration API (`/_synapse/admin`) powers administration dashboards and moderation bots. As with Synapse and Dendrite, the playbook now exposes it automatically when such a tool is installed: publicly for [Ketesa](docs/configuring-playbook-ketesa.md) or [Element Admin](docs/configuring-playbook-element-admin.md), and on the internal entrypoint for [Draupnir](docs/configuring-playbook-bot-draupnir.md). To expose it yourself, set `matrix_tuwunel_container_labels_public_client_synapse_admin_api_enabled: true` (or the `internal_` variant)." +msgstr "" + +#: ../../../CHANGELOG.md:84 +msgid "Tuwunel also serves first-party routes under `/_tuwunel`, including its native OpenID Connect provider endpoints, which the reverse proxy must route for OIDC login to work. This path is now routed on the public entrypoint by default. To keep it off the public entrypoint, set `matrix_tuwunel_container_labels_public_tuwunel_api_enabled: false`." +msgstr "" + +#: ../../../CHANGELOG.md:87 +msgid "2026-07-18" +msgstr "" + +#: ../../../CHANGELOG.md:89 +msgid "LiveKit Server port configuration must be unambiguous now" +msgstr "" + +#: ../../../CHANGELOG.md:91 +msgid "This only affects you if you have configured a LiveKit Server RTC port range (`livekit_server_config_rtc_port_range_start` and `livekit_server_config_rtc_port_range_end`)." +msgstr "" + +#: ../../../CHANGELOG.md:93 +msgid "LiveKit only uses one of the two port configuration mechanisms: when a port range is defined, the multiplexed UDP port (`livekit_server_config_rtc_udp_port`) is ignored entirely. Previously, the role would silently render its default UDP port (7882) into the configuration alongside your port range, misleadingly suggesting that both are in effect." +msgstr "" + +#: ../../../CHANGELOG.md:95 +msgid "The role now asks you to make the choice explicit: if you define a port range, unset the UDP port by adding `livekit_server_config_rtc_udp_port: ''` to your `vars.yml` file. A validation error will guide you, if your configuration is affected." +msgstr "" + +#: ../../../CHANGELOG.md:98 +msgid "2026-07-17" +msgstr "" + +#: ../../../CHANGELOG.md:100 +msgid "prometheus-nginxlog-exporter metric names have changed" +msgstr "" + +#: ../../../CHANGELOG.md:102 +msgid "If you have enabled [metrics for nginx logs](docs/configuring-playbook-prometheus-grafana.md) (`prometheus_nginxlog_exporter_enabled: true`), note that the exporter's metric names have changed." +msgstr "" + +#: ../../../CHANGELOG.md:104 +msgid "The exporter's configuration used to ship a leftover `myprefix` placeholder as the metric name prefix, producing metrics like `myprefix_http_response_count_total`. The bundled Grafana dashboard queries unprefixed metric names (`http_response_count_total`), so it could never show any data (reported in [#3380](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3380))." +msgstr "" + +#: ../../../CHANGELOG.md:106 +msgid "Metric names are now unprefixed, matching the bundled dashboard, which should start working. Each metric carries a `namespace` label, whose value is now `nginx` (previously `matrix`); it is configurable via `prometheus_nginxlog_exporter_config_namespace_name`. If you have built custom dashboards or alerts on top of the old `myprefix_*` metric names, adjust them accordingly, or restore the old behavior by setting `prometheus_nginxlog_exporter_config_namespace_metrics_prefix: myprefix` in your `vars.yml` file." +msgstr "" + +#: ../../../CHANGELOG.md:109 +msgid "2026-07-16" +msgstr "" + +#: ../../../CHANGELOG.md:111 +msgid "(Backward Compatibility Break) Bridge variables have been renamed" +msgstr "" + +#: ../../../CHANGELOG.md:113 +msgid "All bridge roles (`roles/custom/matrix-bridge-*`) now use a uniform variable naming scheme, where the variable prefix matches the role directory name. This adopts the naming policy proposed in [#4705](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/4705) and requested in [#5096](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/5096)." +msgstr "" + +#: ../../../CHANGELOG.md:115 +msgid "Previously, bridge variable prefixes were all over the place (`matrix_mautrix_telegram_*`, `matrix_heisenbridge_*`, `matrix_steam_bridge_*`, etc.). Now, they all follow the same pattern that bot roles (`matrix_bot__*`) have been using for years: the `matrix-bridge-mautrix-telegram` role uses `matrix_bridge_mautrix_telegram_*` variables, the `matrix-bridge-steam` role uses `matrix_bridge_steam_*` variables, and so on." +msgstr "" + +#: ../../../CHANGELOG.md:117 +msgid "Only Ansible variables were renamed. Systemd service names, container names, `/matrix/*` directories, database names and usernames, and appservice registration contents (tokens, bot usernames) all remain the same. No data migration is necessary and bridges keep working as before, once you rename the variables in your `vars.yml` configuration file." +msgstr "" + +#: ../../../CHANGELOG.md:119 +msgid "The playbook will let you know if your configuration still uses old-style variable names." +msgstr "" + +#: ../../../CHANGELOG.md:121 +msgid "Here is the full rename map:" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "Old variable prefix" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "New variable prefix" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_appservice_discord_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_appservice_discord_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_appservice_irc_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_appservice_irc_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_beeper_linkedin_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_beeper_linkedin_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_heisenbridge_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_heisenbridge_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_hookshot_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_hookshot_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_androidsms_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_wsproxy_androidsms_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_bluesky_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_bluesky_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_discord_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_discord_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_gmessages_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_gmessages_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_googlechat_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_googlechat_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_gvoice_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_gvoice_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_imessage_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_wsproxy_imessage_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_meta_instagram_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_meta_instagram_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_meta_messenger_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_meta_messenger_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_signal_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_signal_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_slack_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_slack_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_telegram_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_telegram_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_twitter_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_twitter_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_whatsapp_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_whatsapp_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mautrix_wsproxy_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mautrix_wsproxy_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_meshtastic_relay_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_meshtastic_relay_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mx_puppet_groupme_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mx_puppet_groupme_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_mx_puppet_steam_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_mx_puppet_steam_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_postmoogle_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_postmoogle_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_rustpush_bridge_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_rustpush_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_sms_bridge_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_sms_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_steam_bridge_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_steam_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_wechat_`" +msgstr "" + +#: ../../../CHANGELOG.md:0 +msgid "`matrix_bridge_wechat_`" +msgstr "" + +#: ../../../CHANGELOG.md:154 +msgid "A few special cases beyond the prefix map:" +msgstr "" + +#: ../../../CHANGELOG.md:156 +msgid "`matrix_mautrix_signal_wsproxy_syncproxy_connection_string` (a variable of the mautrix-wsproxy role, despite its name) is now `matrix_bridge_mautrix_wsproxy_syncproxy_connection_string`" +msgstr "" + +#: ../../../CHANGELOG.md:157 +msgid "`matrix_playbook_migration_matrix_postmoogle_migration_validation_enabled` is now `matrix_playbook_migration_matrix_bridge_postmoogle_migration_validation_enabled`" +msgstr "" + +#: ../../../CHANGELOG.md:159 +msgid "You can update your `vars.yml` file automatically with this `sed` command (on macOS, use `sed -i ''` instead of `sed -i`):" +msgstr "" + +#: ../../../CHANGELOG.md:196 +msgid "The `sed` command only replaces prefixes followed by an underscore, so values that intentionally match old prefixes (like the default database names, e.g. `matrix_mautrix_telegram`) are not affected." +msgstr "" + +#: ../../../CHANGELOG.md:198 +msgid "**Note**: if you have defined your own custom variables whose names embed an old prefix (e.g. `vault_matrix_postmoogle_password` referencing a secret in an Ansible Vault file), the `sed` command renames such references too. Either rename your custom variables to match (including their definitions in encrypted vault files, which `sed` cannot reach), or revert those spots manually." +msgstr "" + +#: ../../../CHANGELOG.md:200 +msgid "2026-07-15" +msgstr "" + +#: ../../../CHANGELOG.md:202 +msgid "Google Voice bridging" +msgstr "" + +#: ../../../CHANGELOG.md:204 +msgid "The playbook can now bridge [Google Voice](https://voice.google.com/) via the [mautrix-gvoice](https://github.com/mautrix/gvoice) bridge. Text and media flow both ways, and portal rooms build themselves for your recent conversations." +msgstr "" + +#: ../../../CHANGELOG.md:206 +msgid "Login is by cookie, not a paired phone: you copy the cookies from a browser signed in to voice.google.com and hand them to the bot. Google expires them on its own schedule, so expect to log in again every so often. See [Setting up Mautrix Google Voice bridging](./docs/configuring-playbook-bridge-mautrix-gvoice.md) to get started." +msgstr "" + +#: ../../../CHANGELOG.md:208 +msgid "matrix-appservice-kakaotalk has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:210 +msgid "The [matrix-appservice-kakaotalk](./docs/configuring-playbook-bridge-appservice-kakaotalk.md) bridge has been removed from the playbook. This component could only be installed by self-building its source code, and its upstream repository has become unreachable, which makes installation impossible. The bridge was also based on the unmaintained node-kakao library, and there have been reports that using it may get KakaoTalk accounts banned." +msgstr "" + +#: ../../../CHANGELOG.md:212 +msgid "The playbook will let you know if you're using any `matrix_appservice_kakaotalk_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-bridge-appservice-kakaotalk.md#uninstalling-the-component-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:214 +msgid "Dedicated CAPTCHA variables for Matrix Authentication Service" +msgstr "" + +#: ../../../CHANGELOG.md:216 +msgid "[Matrix Authentication Service](./docs/configuring-playbook-matrix-authentication-service.md) can now be protected with CAPTCHA (ReCaptcha v2, Cloudflare Turnstile, or hCaptcha) via dedicated variables, instead of going through `matrix_authentication_service_configuration_extension_yaml`. See the [captcha documentation](./docs/configuring-captcha.md#matrix-authentication-service) for details." +msgstr "" + +#: ../../../CHANGELOG.md:218 +msgid "2026-07-14" +msgstr "" + +#: ../../../CHANGELOG.md:220 +msgid "The playbook no longer ships a custom welcome page for Element Web" +msgstr "" + +#: ../../../CHANGELOG.md:222 +msgid "Element Web [redesigned its welcome page](https://github.com/element-hq/element-web/pull/33211) (the screen shown at `/#/welcome` before logging in) into a built-in component and no longer loads a custom `welcome.html` file by default. Since the playbook upgraded to an Element Web version containing that change (spring 2026), the custom welcome page the playbook installed (and the variables customizing it) had silently stopped having any effect." +msgstr "" + +#: ../../../CHANGELOG.md:224 +msgid "The playbook now embraces the new upstream behavior and no longer ships its own `welcome.html`. The following variables have been removed and the playbook will let you know if you're still using them: `matrix_client_element_welcome_headline`, `matrix_client_element_welcome_text`, `matrix_client_element_welcome_logo_link` and `matrix_client_element_page_template_welcome_path`." +msgstr "" + +#: ../../../CHANGELOG.md:226 +msgid "Most welcome page customizations keep working, because they go through Element Web's branding configuration, which the new welcome page still honors:" +msgstr "" + +#: ../../../CHANGELOG.md:228 +msgid "a custom logo, via `matrix_client_element_welcome_logo` (or `matrix_client_element_branding_auth_header_logo_url`)" +msgstr "" + +#: ../../../CHANGELOG.md:229 +msgid "a custom background, via `matrix_client_element_branding_welcome_background_url`" +msgstr "" + +#: ../../../CHANGELOG.md:231 +msgid "If you need a fully custom welcome page, you can self-host an HTML page and point Element Web at it, like this:" +msgstr "" + +#: ../../../CHANGELOG.md:242 +msgid "BorgBackup now includes Synapse's local thumbnails" +msgstr "" + +#: ../../../CHANGELOG.md:244 +msgid "For Synapse servers, the built-in [BorgBackup](./docs/configuring-playbook-backup-borg.md) integration no longer excludes the media store's `local_thumbnails` directory from backups." +msgstr "" + +#: ../../../CHANGELOG.md:246 +msgid "Synapse only generates thumbnails of local media at upload time (unless `dynamic_thumbnails` is enabled, which the playbook does not do), and there is no tooling to regenerate them. Restoring a backup made with the previous exclusion list therefore left all previously uploaded local images without thumbnails. The [official Synapse backup guide](https://element-hq.github.io/synapse/latest/usage/administration/backups.html) recommends backing this directory up, and the playbook now follows that recommendation." +msgstr "" + +#: ../../../CHANGELOG.md:248 +msgid "Expect your backups to grow somewhat, depending on how much image media your local users have uploaded. If you prefer the old behavior, you can redefine `backup_borg_location_exclude_patterns` in your `vars.yml`." +msgstr "" + +#: ../../../CHANGELOG.md:250 +msgid "2026-07-12" +msgstr "" + +#: ../../../CHANGELOG.md:252 +msgid "matrix-registration-bot has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:254 +msgid "The [matrix-registration-bot](./docs/configuring-playbook-bot-matrix-registration-bot.md) service has been removed from the playbook, as it has been unmaintained." +msgstr "" + +#: ../../../CHANGELOG.md:256 +msgid "The playbook will let you know if you're using any `matrix_bot_matrix_registration_bot_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-bot-matrix-registration-bot.md#uninstalling-the-component-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:258 +msgid "Continuwuity v26 no longer supports LDAP" +msgstr "" + +#: ../../../CHANGELOG.md:260 +msgid "The playbook now installs [Continuwuity](./docs/configuring-playbook-continuwuity.md) v26, a major upgrade from the v0.5.x series which **removes LDAP authentication support** (see the [v26.6.0 release notes](https://forgejo.ellis.link/continuwuation/continuwuity/releases/tag/v26.6.0))." +msgstr "" + +#: ../../../CHANGELOG.md:262 +msgid "The playbook never exposed dedicated variables for Continuwuity's LDAP support, so most people are unaffected. However, if you had enabled LDAP via `matrix_continuwuity_environment_variables_extension` or a custom configuration template, you'll need to migrate to another authentication method, such as the newly introduced [OpenID Connect support](https://continuwuity.org/guides/oidc)." +msgstr "" + +#: ../../../CHANGELOG.md:264 +msgid "2026-06-29" +msgstr "" + +#: ../../../CHANGELOG.md:266 +msgid "Support for running on Synology DSM" +msgstr "" + +#: ../../../CHANGELOG.md:268 +msgid "Thanks to [cksit](https://github.com/cksit), the playbook can now run on [Synology DSM](https://www.synology.com/dsm) 7 and later." +msgstr "" + +#: ../../../CHANGELOG.md:270 +msgid "Synology hosts are detected automatically (via `/etc/synoinfo.conf`), so other systems are unaffected. On DSM, the playbook uses the platform's native user management (`synouser`/`synogroup`), works around a Docker SDK incompatibility, and installs a small boot-fix service that handles a few DSM-specific boot quirks." +msgstr "" + +#: ../../../CHANGELOG.md:272 +msgid "To get started, see the new [Configuring Synology DSM](./docs/configuring-playbook-synology.md) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:274 +msgid "Mautrix bridges now expose their API (for Mautrix Manager and similar tools)" +msgstr "" + +#: ../../../CHANGELOG.md:276 +msgid "The playbook now exposes the HTTP API of each [mautrix](https://github.com/mautrix) bridge, so tools like [Mautrix Manager](https://github.com/mautrix/manager) can help you log into them. This is especially useful for [mautrix-gmessages](./docs/configuring-playbook-bridge-mautrix-gmessages.md): Google has removed its QR-code login, leaving a [manual cookie-extraction flow](https://docs.mau.fi/bridges/go/gmessages/authentication.html) that tools like Mautrix Manager can streamline." +msgstr "" + +#: ../../../CHANGELOG.md:278 +msgid "The API is exposed at `https://matrix.example.com/bridges/SERVICENAME` (for example, `https://matrix.example.com/bridges/gmessages`) and is advertised via a new `/.well-known/matrix/mautrix` file, so compatible tools can discover your bridges automatically. Such tools authenticate with your own Matrix access token, so no bridge secret needs to be shared with them." +msgstr "" + +#: ../../../CHANGELOG.md:280 +msgid "This affects all mautrix bridges based on the new bridge framework (bluesky, gmessages, meta-instagram, meta-messenger, signal, slack, telegram, twitter and whatsapp) and is enabled by default." +msgstr "" + +#: ../../../CHANGELOG.md:282 +msgid "To learn more (including how to turn it off), see the [Expose the bridge's API](./docs/configuring-playbook-bridge-mautrix-bridges.md#expose-the-bridges-api-for-mautrix-manager-and-similar-tools) section on our common mautrix bridges documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:284 +msgid "2026-06-28" +msgstr "" + +#: ../../../CHANGELOG.md:286 +msgid "baibot now supports Venice, our recommended provider" +msgstr "" + +#: ../../../CHANGELOG.md:288 +msgid "[baibot](./docs/configuring-playbook-bot-baibot.md) now ships a preset for the [Venice](./docs/configuring-playbook-bot-baibot.md#venice) provider, and it's the one we recommend. It's the most capable provider baibot supports (text generation with vision, file inputs and web search, speech-to-text, text-to-speech, and image generation and editing), and the only one that runs inference with no logging and no training on your data." +msgstr "" + +#: ../../../CHANGELOG.md:290 +msgid "Enabling it takes a preset toggle and an API key:" +msgstr "" + +#: ../../../CHANGELOG.md:298 +msgid "[OpenAI](https://openai.com/) and baibot's other providers remain fully supported. To get started, see the [Setting up baibot](./docs/configuring-playbook-bot-baibot.md#venice) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:300 +msgid "2026-06-24" +msgstr "" + +#: ../../../CHANGELOG.md:302 +msgid "Support for bridging to iMessage via RustPush" +msgstr "" + +#: ../../../CHANGELOG.md:304 +msgid "Thanks to [jasonlaguidice](https://github.com/jasonlaguidice), the playbook now supports bridging to [iMessage](https://support.apple.com/messages) via a new [RustPush](https://github.com/OpenBubbles/rustpush)-based bridge ([jasonlaguidice/imessage](https://github.com/jasonlaguidice/imessage))." +msgstr "" + +#: ../../../CHANGELOG.md:306 +msgid "Unlike the existing [mautrix-wsproxy](./docs/configuring-playbook-bridge-mautrix-wsproxy.md) iMessage bridge, this one talks directly to Apple's push notification service, so it needs neither a running Mac nor a wsproxy on the homeserver. Each user supplies a hardware key extracted from a Mac through the bridge bot's login flow." +msgstr "" + +#: ../../../CHANGELOG.md:308 +msgid "To learn more, see our [Setting up RustPush (iMessage) bridging](./docs/configuring-playbook-bridge-rustpush.md) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:310 +msgid "2026-05-24" +msgstr "" + +#: ../../../CHANGELOG.md:312 +msgid "matrix-ldap-registration-proxy has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:314 +msgid "The [matrix-ldap-registration-proxy](./docs/configuring-playbook-matrix-ldap-registration-proxy.md) service has been removed from the playbook, as the source code and the container image have become unavailable." +msgstr "" + +#: ../../../CHANGELOG.md:316 +msgid "The playbook will let you know if you're using any `matrix_ldap_registration_proxy_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-matrix-ldap-registration-proxy.md#uninstalling-the-component-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:318 +msgid "2026-05-23" +msgstr "" + +#: ../../../CHANGELOG.md:320 +msgid "Go-NEB has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:322 +msgid "[Go-NEB](./docs/configuring-playbook-bot-go-neb.md) has been removed from the playbook, as it has been discontinued since June 2023." +msgstr "" + +#: ../../../CHANGELOG.md:324 +msgid "The playbook will let you know if you're using any `matrix_bot_go_neb_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the bot manually](./docs/configuring-playbook-bot-go-neb.md#uninstalling-go-neb-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:326 +msgid "2026-05-19" +msgstr "" + +#: ../../../CHANGELOG.md:328 +msgid "matrix-registration has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:330 +msgid "The [matrix-registration](./docs/configuring-playbook-matrix-registration.md) service has been removed from the playbook, as it has been unmaintained (archived) since November, 2025." +msgstr "" + +#: ../../../CHANGELOG.md:332 +msgid "The playbook will let you know if you're using any `matrix_registration_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-matrix-registration.md#uninstalling-the-component-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:334 +msgid "2026-05-18" +msgstr "" + +#: ../../../CHANGELOG.md:336 +msgid "LiveKit Server has been upgraded to v1.12.0" +msgstr "" + +#: ../../../CHANGELOG.md:338 +msgid "The playbook now ships [LiveKit Server](./docs/configuring-playbook-livekit-server.md) v1.12.0. See the [upstream release notes](https://github.com/livekit/livekit/releases/tag/v1.12.0) for details." +msgstr "" + +#: ../../../CHANGELOG.md:340 +msgid "This release tightens TURN security:" +msgstr "" + +#: ../../../CHANGELOG.md:342 +msgid "**TURN credentials now carry a TTL** (default: 300 seconds), exposed via `livekit_server_config_turn_ttl_seconds`." +msgstr "" + +#: ../../../CHANGELOG.md:343 +msgid "**TURN no longer relays traffic to restricted peer CIDRs** (loopback, link-local, multicast, private, unspecified) by default. If your setup legitimately requires it, list the ranges in `livekit_server_config_turn_allow_restricted_peer_cidrs`." +msgstr "" + +#: ../../../CHANGELOG.md:345 +msgid "For example, to allow TURN to reach the common [RFC1918](https://www.rfc-editor.org/rfc/rfc1918) private ranges, add to your `vars.yml`:" +msgstr "" + +#: ../../../CHANGELOG.md:353 +msgid "Adjust the ranges to match your network. To deny specific CIDRs (taking precedence over the allow list above), use `livekit_server_config_turn_deny_peer_cidrs` in the same shape." +msgstr "" + +#: ../../../CHANGELOG.md:356 +msgid "2026-05-07" +msgstr "" + +#: ../../../CHANGELOG.md:358 +msgid "Tuwunel support" +msgstr "" + +#: ../../../CHANGELOG.md:360 +msgid "Thanks to [Jason Volk](https://github.com/jevolk), the playbook now supports the [Tuwunel](./docs/configuring-playbook-tuwunel.md) homeserver as an optional alternative to Synapse." +msgstr "" + +#: ../../../CHANGELOG.md:362 +msgid "Tuwunel is a fork of [conduwuit](./docs/configuring-playbook-conduwuit.md) written in Rust. The former conduwuit maintainer [endorses Tuwunel as conduwuit's successor](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/5200#issuecomment-4396211185). Like [Continuwuity](./docs/configuring-playbook-continuwuity.md), Tuwunel continues development on top of conduwuit's database format." +msgstr "" + +#: ../../../CHANGELOG.md:364 +#: ../../../CHANGELOG.md:868 +#: ../../../CHANGELOG.md:1081 +msgid "Existing installations do **not** need to be updated. **Synapse is still the default homeserver implementation** installed by the playbook." +msgstr "" + +#: ../../../CHANGELOG.md:366 +msgid "People that used to run conduwuit may wish to [migrate from conduwuit to Tuwunel](./docs/configuring-playbook-tuwunel.md#migrating-from-conduwuit) via the new `tuwunel-migrate-from-conduwuit` tag, which performs an in-place binary-swap migration that reads the conduwuit database directly." +msgstr "" + +#: ../../../CHANGELOG.md:368 +msgid "**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse/Conduit/Dendrite/Continuwuity to Tuwunel) without data loss. The exception is conduwuit, due to the shared database format." +msgstr "" + +#: ../../../CHANGELOG.md:371 +msgid "2026-04-24" +msgstr "" + +#: ../../../CHANGELOG.md:373 +msgid "Support for bridging to Meshtastic via meshtastic-matrix-relay" +msgstr "" + +#: ../../../CHANGELOG.md:375 +msgid "Thanks to [luschmar](https://github.com/luschmar), the playbook now supports bridging to [Meshtastic](https://meshtastic.org/) mesh networks via [meshtastic-matrix-relay](https://github.com/jeremiah-k/meshtastic-matrix-relay) (mmrelay)." +msgstr "" + +#: ../../../CHANGELOG.md:377 +msgid "To learn more, see our [Setting up a Matrix <-> Meshtastic bridge](./docs/configuring-playbook-bridge-meshtastic-relay.md) documentation page." +msgstr "" + +#: ../../../CHANGELOG.md:379 +msgid "(BC Break) mautrix-telegram has been rewritten in Go (bridgev2)" +msgstr "" + +#: ../../../CHANGELOG.md:381 +msgid "The [mautrix-telegram](./docs/configuring-playbook-bridge-mautrix-telegram.md) bridge has been [rewritten in Go](https://mau.fi/blog/2026-04-mautrix-release/) on top of the [bridgev2](https://docs.mau.fi/bridges/go/) architecture. See the [upstream v26.04 release notes](https://github.com/mautrix/telegram/releases/tag/v0.2604.0) for what changed in the bridge itself (shared-portal behavior, management-room state, new features, etc.)." +msgstr "" + +#: ../../../CHANGELOG.md:383 +msgid "**Most users won't have to do anything.** If you use the playbook's integrated Postgres (the default) and haven't customized telegram-bridge variables beyond `matrix_mautrix_telegram_api_id` and `matrix_mautrix_telegram_api_hash`, just re-run the playbook; the bridge will migrate itself on first start. Taking a backup beforehand is still a good idea." +msgstr "" + +#: ../../../CHANGELOG.md:385 +msgid "⚠️ **SQLite users: do not upgrade yet.** Upstream v0.2604.0 has a [known bug in the legacy SQLite migration](https://github.com/mautrix/telegram/releases/tag/v0.2604.0) that can corrupt your data. The playbook detects this case and will refuse to proceed. Either switch to Postgres first (set `matrix_mautrix_telegram_database_engine: postgres`; the playbook handles the pgloader migration), or wait for the next upstream release." +msgstr "" + +#: ../../../CHANGELOG.md:387 +msgid "Playbook-specific things to know. The playbook will fail loudly if you're affected:" +msgstr "" + +#: ../../../CHANGELOG.md:389 +msgid "Many `matrix_mautrix_telegram_*` variables have been **removed** (web-login endpoint, lottieconverter, username/alias/displayname templates, filter-mode, bot-token relaybot, Shared-Secret-Auth map). The deprecation check will tell you exactly what to rename or drop when you run the playbook." +msgstr "" + +#: ../../../CHANGELOG.md:390 +msgid "**Old-style relaybot users** (`matrix_mautrix_telegram_bot_token`): switch to the common [mautrix bridge relay mode](./docs/configuring-playbook-bridge-mautrix-bridges.md#enable-relay-mode-optional) via `matrix_mautrix_telegram_bridge_relay_enabled: true`." +msgstr "" + +#: ../../../CHANGELOG.md:391 +msgid "**Shared-Secret-Auth double-puppeting users**: switch to [Appservice Double Puppet](./docs/configuring-playbook-appservice-double-puppet.md); the playbook wires it up automatically." +msgstr "" + +#: ../../../CHANGELOG.md:392 +msgid "**Custom `matrix_mautrix_telegram_bridge_permissions`**: map `relaybot` to `relay`, `puppeting` to `user`, `full` to `user`. Validated at playbook time." +msgstr "" + +#: ../../../CHANGELOG.md:394 +msgid "2026-04-03" +msgstr "" + +#: ../../../CHANGELOG.md:396 +msgid "(BC Break) Synapse Admin (fork by etke.cc) is now Ketesa" +msgstr "" + +#: ../../../CHANGELOG.md:398 +msgid "Synapse Admin has been rebranded to **[Ketesa](https://github.com/etkecc/ketesa)** — a landmark release that introduces a new identity, a full UI redesign, mobile-first layout, and deep Matrix Authentication Service (MAS) integration. For the full story behind the rename and a tour of what's new, see the [Ketesa v1.0.0 announcement](https://etke.cc/blog/introducing-ketesa/)." +msgstr "" + +#: ../../../CHANGELOG.md:400 +msgid "Ketesa is a zero-configuration drop-in replacement for Synapse Admin: no server-side changes required, just update the role variables." +msgstr "" + +#: ../../../CHANGELOG.md:402 +msgid "The `matrix-synapse-admin` role has been **renamed** to `matrix-ketesa`. All `matrix_synapse_admin_*` variables must be **renamed** to `matrix_ketesa_*` in your `vars.yml`." +msgstr "" + +#: ../../../CHANGELOG.md:404 +msgid "Additionally, the **Docker image** changed from `ghcr.io/etkecc/synapse-admin` to `ghcr.io/etkecc/ketesa`. The default path prefix remains `/synapse-admin` for backward compatibility — updating to `/ketesa` is recommended but not required." +msgstr "" + +#: ../../../CHANGELOG.md:406 +msgid "The playbook will automatically detect leftover `matrix_synapse_admin_*` variables and fail with a helpful message listing what needs to be renamed." +msgstr "" + +#: ../../../CHANGELOG.md:408 +msgid "The playbook handles reverse-proxy routing for subpath deployments (e.g. `/ketesa`), including MAS-enabled setups — though OIDC auth flows on real servers still have some rough edges. Feedback is appreciated in [#ketesa:etke.cc](https://matrix.to/#/#ketesa:etke.cc)." +msgstr "" + +#: ../../../CHANGELOG.md:410 +msgid "See the [Ketesa documentation](docs/configuring-playbook-ketesa.md) for details." +msgstr "" + +#: ../../../CHANGELOG.md:412 +msgid "2026-04-02" +msgstr "" + +#: ../../../CHANGELOG.md:414 +msgid "(BC Break) Draupnir for all Self Service Provisioning is now disabled by default" +msgstr "" + +#: ../../../CHANGELOG.md:416 +msgid "💡 If you don't use [Draupnir for all](./docs/configuring-playbook-appservice-draupnir-for-all.md), then this breaking change does not concern you.." +msgstr "" + +#: ../../../CHANGELOG.md:418 +msgid "[Draupnir for all](./docs/configuring-playbook-appservice-draupnir-for-all.md) now ships with `allowSelfServiceProvisioning: false` as default upstream and in this playbook." +msgstr "" + +#: ../../../CHANGELOG.md:420 +msgid "This means users can no longer provision Draupnir instances by inviting the appservice bot unless you explicitly opt in." +msgstr "" + +#: ../../../CHANGELOG.md:422 +msgid "Manual provisioning by administrators is now the recommended approach. You do not want to enable Self Service Provisioning unless you have additional custom safeguards like those used by asgard.chat in place." +msgstr "" + +#: ../../../CHANGELOG.md:424 +msgid "If you want to enable Self Service Provisioning, add the following to your `vars.yml`:" +msgstr "" + +#: ../../../CHANGELOG.md:431 +msgid "2026-03-23" +msgstr "" + +#: ../../../CHANGELOG.md:433 +msgid "Migration validation system introduced" +msgstr "" + +#: ../../../CHANGELOG.md:435 +msgid "Previously, when updating your setup, you had to remember to read the [CHANGELOG](CHANGELOG.md) file or risk breakage." +msgstr "" + +#: ../../../CHANGELOG.md:437 +msgid "Now, the playbook includes a migration validation system that ensures you're aware of breaking changes before they affect your deployment. You're now forced to acknowledge each breaking change, unless you wish to live dangerously (see below)." +msgstr "" + +#: ../../../CHANGELOG.md:440 +msgid "A new `matrix_playbook_migration_validated_version` variable has been introduced." +msgstr "" + +#: ../../../CHANGELOG.md:442 +msgid "**New users** who started from the [example `vars.yml`](examples/vars.yml) file already have this variable set and do not need to do anything." +msgstr "" + +#: ../../../CHANGELOG.md:444 +msgid "**Existing users** will need to add the following to their `vars.yml` file after reviewing all changelog entries up to now:" +msgstr "" + +#: ../../../CHANGELOG.md:450 +msgid "Going forward, whenever a breaking change is introduced the playbook will:" +msgstr "" + +#: ../../../CHANGELOG.md:452 +msgid "bump its expected version value (`matrix_playbook_migration_expected_version`), causing a discrepancy with what you validated (`matrix_playbook_migration_validated_version`)" +msgstr "" + +#: ../../../CHANGELOG.md:454 +msgid "fail when you run it with a helpful message listing what changed and linking to the relevant changelog entries" +msgstr "" + +#: ../../../CHANGELOG.md:456 +msgid "After reviewing and adapting your setup, you simply update the variable to the new version." +msgstr "" + +#: ../../../CHANGELOG.md:458 +msgid "If you'd like to live dangerously and skip these checks (not recommended), you can set this once and be done with it:" +msgstr "" + +#: ../../../CHANGELOG.md:464 +msgid "2026-03-19" +msgstr "" + +#: ../../../CHANGELOG.md:466 +msgid "Matrix Authentication Service now prefers UNIX sockets for playbook-managed Postgres" +msgstr "" + +#: ../../../CHANGELOG.md:468 +msgid "When [Matrix Authentication Service](docs/configuring-playbook-matrix-authentication-service.md) (MAS) uses the playbook-managed Postgres service, it now connects to it via a [UNIX socket](https://en.wikipedia.org/wiki/Unix_domain_socket) by default instead of TCP." +msgstr "" + +#: ../../../CHANGELOG.md:470 +msgid "This follows the same approach [applied to Synapse](#synapse-now-prefers-unix-sockets-for-playbook-managed-postgres-and-valkey) and reduces unnecessary container-network wiring, keeping local IPC off the network stack." +msgstr "" + +#: ../../../CHANGELOG.md:472 +msgid "If you use an external Postgres server for MAS, this does not change your setup." +msgstr "" + +#: ../../../CHANGELOG.md:474 +#: ../../../CHANGELOG.md:490 +msgid "If you'd like to keep the previous TCP-based behavior, add the following configuration to your `vars.yml`:" +msgstr "" + +#: ../../../CHANGELOG.md:480 +msgid "2026-03-17" +msgstr "" + +#: ../../../CHANGELOG.md:482 +msgid "Synapse now prefers UNIX sockets for playbook-managed Postgres and Valkey" +msgstr "" + +#: ../../../CHANGELOG.md:484 +msgid "When Synapse uses the playbook-managed Postgres and Valkey services, it now connects to them via [UNIX sockets](https://en.wikipedia.org/wiki/Unix_domain_socket) by default instead of TCP." +msgstr "" + +#: ../../../CHANGELOG.md:486 +msgid "This reduces unnecessary container-network wiring and keeps local IPC off the network stack, which is a bit simpler and slightly more secure." +msgstr "" + +#: ../../../CHANGELOG.md:488 +msgid "If you use an external Postgres server or external Redis/Valkey for Synapse, this does not change your setup." +msgstr "" + +#: ../../../CHANGELOG.md:497 +msgid "2026-03-01" +msgstr "" + +#: ../../../CHANGELOG.md:499 +msgid "(Potential BC Break) Synapse S3 media prefix is now applied consistently" +msgstr "" + +#: ../../../CHANGELOG.md:501 +msgid "The `matrix_synapse_ext_synapse_s3_storage_provider_config_prefix` variable is now wired consistently for both:" +msgstr "" + +#: ../../../CHANGELOG.md:503 +msgid "the Synapse `s3_storage_provider` module configuration" +msgstr "" + +#: ../../../CHANGELOG.md:504 +msgid "the `matrix-synapse-s3-storage-provider-migrate` migration script (`s3_media_upload --prefix`)" +msgstr "" + +#: ../../../CHANGELOG.md:506 +msgid "Previously, this variable could be set, but was not effectively applied by either of these paths." +msgstr "" + +#: ../../../CHANGELOG.md:508 +msgid "**Affects**: users of [synapse-s3-storage-provider](docs/configuring-playbook-synapse-s3-storage-provider.md) who have configured a non-empty `matrix_synapse_ext_synapse_s3_storage_provider_config_prefix` value." +msgstr "" + +#: ../../../CHANGELOG.md:510 +msgid "If your bucket data was uploaded without the prefix before this fix, enabling proper prefix usage can make existing objects appear missing until data is migrated/copied to the prefixed key namespace." +msgstr "" + +#: ../../../CHANGELOG.md:512 +msgid "2026-02-26" +msgstr "" + +#: ../../../CHANGELOG.md:514 +msgid "Internal refactor: merged the Synapse reverse-proxy companion role into `matrix-synapse`" +msgstr "" + +#: ../../../CHANGELOG.md:516 +msgid "The standalone `matrix-synapse-reverse-proxy-companion` role has been merged into the [matrix-synapse](roles/custom/matrix-synapse/) role." +msgstr "" + +#: ../../../CHANGELOG.md:518 +msgid "This is not a user-facing change and does not change variable names (`matrix_synapse_reverse_proxy_companion_*` remain the same). The split looked clean on paper, but in practice both parts are tightly coupled through worker routing, tags (`setup-synapse`/`install-synapse`), and lifecycle ordering, so keeping them separate added coordination overhead with little practical benefit." +msgstr "" + +#: ../../../CHANGELOG.md:520 +msgid "Compatibility note: existing companion-specific tags (`setup-synapse-reverse-proxy-companion` and `install-synapse-reverse-proxy-companion`) are still available." +msgstr "" + +#: ../../../CHANGELOG.md:522 +msgid "With this change, Synapse and its reverse-proxy companion are managed in one role (`matrix-synapse`) while still keeping companion logic in dedicated task/template subdirectories for maintainability." +msgstr "" + +#: ../../../CHANGELOG.md:524 +msgid "2026-02-21" +msgstr "" + +#: ../../../CHANGELOG.md:526 +msgid "(BC Break) coturn is no longer auto-enabled by default" +msgstr "" + +#: ../../../CHANGELOG.md:528 +msgid "By default, the [coturn](./docs/configuring-playbook-turn.md) TURN server component is no longer enabled for every deployment." +msgstr "" + +#: ../../../CHANGELOG.md:530 +msgid "This reduces resources and attach surface for deployments which:" +msgstr "" + +#: ../../../CHANGELOG.md:532 +msgid "either don't need calls at all" +msgstr "" + +#: ../../../CHANGELOG.md:533 +msgid "or use the modern [Matrix RTC](docs/configuring-playbook-matrix-rtc.md)/[Element Call](docs/configuring-playbook-element-call.md) stack." +msgstr "" + +#: ../../../CHANGELOG.md:535 +msgid "Coturn is still auto-enabled when [Jitsi](./docs/configuring-playbook-jitsi.md) is enabled (`jitsi_enabled: true`), because Jitsi still depends on TURN for legacy Matrix integration." +msgstr "" + +#: ../../../CHANGELOG.md:537 +msgid "Additionally, Coturn (when enabled) now defaults to using automatic IP detection of your server's external IP address, instead of assuming your Ansible inventory (`ansible_host`) points to a public address and using it for configuring `coturn_turn_external_ip_address`." +msgstr "" + +#: ../../../CHANGELOG.md:539 +msgid "To restore the old behavior (needed for legacy call setups), add the following configuration to your `vars.yml`:" +msgstr "" + +#: ../../../CHANGELOG.md:548 +msgid "LiveKit TURN TLS is now automatically fronted by playbook-managed Traefik" +msgstr "" + +#: ../../../CHANGELOG.md:550 +msgid "For deployments that use the playbook-managed Traefik reverse-proxy, LiveKit TURN over TCP is now SSL-terminated at Traefik and passed as plain TCP to LiveKit (`turn.external_tls = true`) by default." +msgstr "" + +#: ../../../CHANGELOG.md:552 +msgid "To disable this behavior, set `livekit_server_config_turn_external_tls: false` and the playbook will revert to the old behavior - using traefik-certs-dumper to extract SSL certificates out of Traefik and pass them to LiveKit for explicit SSL termination there." +msgstr "" + +#: ../../../CHANGELOG.md:554 +msgid "If you are using `other-traefik-container` or [another reverse-proxy](./configuring-playbook-own-webserver.md), this change does **not** switch behavior automatically. That mode remains using certificate files in the container (Traefik certificates dumper flow) unless you explicitly set the TURN-Traefik mode variables to opt in." +msgstr "" + +#: ../../../CHANGELOG.md:556 +msgid "2026-02-17" +msgstr "" + +#: ../../../CHANGELOG.md:558 +msgid "(BC Break) prometheus-nginxlog-exporter role has been relocated and variable names need adjustments" +msgstr "" + +#: ../../../CHANGELOG.md:560 +msgid "The role for prometheus-nginxlog-exporter has been relocated to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." +msgstr "" + +#: ../../../CHANGELOG.md:562 +msgid "Along with the relocation, the `matrix_prometheus_nginxlog_exporter_` prefix on its variable names has been renamed to `prometheus_nginxlog_exporter_`, so you need to adjust your `vars.yml` configuration." +msgstr "" + +#: ../../../CHANGELOG.md:564 +#: ../../../CHANGELOG.md:626 +#: ../../../CHANGELOG.md:636 +#: ../../../CHANGELOG.md:697 +#: ../../../CHANGELOG.md:719 +#: ../../../CHANGELOG.md:1254 +msgid "As always, the playbook would let you know about this and point out any variables you may have missed." +msgstr "" + +#: ../../../CHANGELOG.md:566 +msgid "synapse-auto-invite-accept has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:568 +msgid "[synapse-auto-invite-accept](./docs/configuring-playbook-synapse-auto-accept-invite.md) has been removed from the playbook, as the same functionality [has been integrated](https://github.com/element-hq/synapse/pull/17147) to Synapse since [v1.109.0](https://github.com/element-hq/synapse/releases/tag/v1.109.0)." +msgstr "" + +#: ../../../CHANGELOG.md:570 +msgid "See [this section](./docs/configuring-playbook-synapse-auto-accept-invite.md#native-alternative) for details about how to enable the function on Synapse." +msgstr "" + +#: ../../../CHANGELOG.md:572 +msgid "If you're using any `matrix_synapse_ext_synapse_auto_accept_invite_*` variables, the playbook will let you know which one you'll need to remove from `vars.yml`." +msgstr "" + +#: ../../../CHANGELOG.md:574 +msgid "2026-02-16" +msgstr "" + +#: ../../../CHANGELOG.md:576 +msgid "matrix-appservice-slack has been removed from the playbook" +msgstr "" + +#: ../../../CHANGELOG.md:578 +msgid "[matrix-appservice-slack](./docs/configuring-playbook-bridge-appservice-slack.md) has been removed from the playbook, as it has been discontinued because the public Matrix.org Slack bridge has been decommissioned on January 14th, 2026." +msgstr "" + +#: ../../../CHANGELOG.md:580 +msgid "The playbook will let you know if you're using any `matrix_appservice_slack_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-bridge-appservice-slack.md#uninstalling-the-component-manually)." +msgstr "" + +#: ../../../CHANGELOG.md:582 +msgid "**Note**: Bridging to [Slack](https://slack.com) can also happen via the [mautrix-slack](./docs/configuring-playbook-bridge-mautrix-slack.md) bridge supported by the playbook." +msgstr "" + +#: ../../../CHANGELOG.md:584 +msgid "2026-02-13" +msgstr "" + +#: ../../../CHANGELOG.md:586 +msgid "Conditional service restart for `install-*` commands" +msgstr "" + +#: ../../../CHANGELOG.md:588 +msgid "When running `install-all` or `install-service` (whether via `just` or raw `ansible-playbook`), only services whose configuration or container image actually changed during the playbook run will now be restarted. Unchanged services are left running (or get started if they were stopped). This reduces unnecessary downtime — particularly for services like Traefik (the reverse proxy), which previously caused brief connectivity interruptions on every playbook run even when nothing changed." +msgstr "" + +#: ../../../CHANGELOG.md:590 +msgid "When running with `setup-*` tags (e.g. `setup-all`, `setup-synapse`), all services continue to be unconditionally restarted as before." +msgstr "" + +#: ../../../CHANGELOG.md:592 +msgid "Currently, only Traefik tracks its own changes and benefits from conditional restart. All other services default to being restarted (the previous behavior). This is just the beginning — as more roles gain change-tracking support, playbook performance will improve and downtime will decrease dramatically, especially for `install-all` runs where most services haven't changed." +msgstr "" + +#: ../../../CHANGELOG.md:594 +msgid "Some benchmarks for `just install-service traefik` when Traefik settings did not change:" +msgstr "" + +#: ../../../CHANGELOG.md:596 +msgid "**Before**:" +msgstr "" + +#: ../../../CHANGELOG.md:597 +msgid "total time: ~56 seconds 🐌" +msgstr "" + +#: ../../../CHANGELOG.md:598 +msgid "Traefik restarted: yes (unnecessarily) ❌" +msgstr "" + +#: ../../../CHANGELOG.md:599 +msgid "dependent services restarted: yes, all of them ❌" +msgstr "" + +#: ../../../CHANGELOG.md:600 +msgid "**After**:" +msgstr "" + +#: ../../../CHANGELOG.md:601 +msgid "total time: ~27 seconds ⚡" +msgstr "" + +#: ../../../CHANGELOG.md:602 +msgid "Traefik restarted: no ✅" +msgstr "" + +#: ../../../CHANGELOG.md:603 +msgid "dependent services restarted: no ✅" +msgstr "" + +#: ../../../CHANGELOG.md:605 +msgid "This behavior can be overridden via `--extra-vars='devture_systemd_service_manager_conditional_restart_enabled=false'` to force unconditional restarts. See [Conditional service restart](docs/just.md#conditional-service-restart) for details." +msgstr "" + +#: ../../../CHANGELOG.md:608 msgid "2026-02-12" msgstr "" -#: ../../../CHANGELOG.md:3 +#: ../../../CHANGELOG.md:610 msgid "Dimension integration manager has been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:5 +#: ../../../CHANGELOG.md:612 msgid "The [Dimension integration manager](./docs/configuring-playbook-dimension.md) has been removed from the playbook, as it has been unmaintained." msgstr "" -#: ../../../CHANGELOG.md:7 +#: ../../../CHANGELOG.md:614 msgid "The playbook will let you know if you're using any `matrix_dimension_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-dimension.md#uninstalling-the-component-manually)." msgstr "" -#: ../../../CHANGELOG.md:9 +#: ../../../CHANGELOG.md:616 msgid "(BC Break) Hydrogen role has been relocated and variable names need adjustments" msgstr "" -#: ../../../CHANGELOG.md:11 +#: ../../../CHANGELOG.md:618 msgid "The role for Hydrogen has been relocated to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." msgstr "" -#: ../../../CHANGELOG.md:13 +#: ../../../CHANGELOG.md:620 msgid "Along with the relocation, the `matrix_client_hydrogen_` prefix was dropped from its variable names, so you need to adjust your `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:15 -#: ../../../CHANGELOG.md:108 +#: ../../../CHANGELOG.md:622 +#: ../../../CHANGELOG.md:715 msgid "You need to do the following replacement:" msgstr "" -#: ../../../CHANGELOG.md:17 +#: ../../../CHANGELOG.md:624 msgid "`matrix_client_hydrogen_` -> `hydrogen_`" msgstr "" -#: ../../../CHANGELOG.md:19 -#: ../../../CHANGELOG.md:29 -#: ../../../CHANGELOG.md:90 -#: ../../../CHANGELOG.md:112 -#: ../../../CHANGELOG.md:647 -msgid "As always, the playbook would let you know about this and point out any variables you may have missed." -msgstr "" - -#: ../../../CHANGELOG.md:21 +#: ../../../CHANGELOG.md:628 msgid "2026-02-11" msgstr "" -#: ../../../CHANGELOG.md:23 +#: ../../../CHANGELOG.md:630 msgid "(BC Break) coturn role has been relocated and variable names need adjustments" msgstr "" -#: ../../../CHANGELOG.md:25 +#: ../../../CHANGELOG.md:632 msgid "The role for coturn has been relocated to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." msgstr "" -#: ../../../CHANGELOG.md:27 +#: ../../../CHANGELOG.md:634 msgid "Along with the relocation, the `matrix_coturn_` prefix on its variable names has been renamed to `coturn_`, so you need to adjust your `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:31 +#: ../../../CHANGELOG.md:638 msgid "conduwuit has been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:33 +#: ../../../CHANGELOG.md:640 msgid "[conduwuit](./docs/configuring-playbook-conduwuit.md) has been removed from the playbook, as it has been abandoned." msgstr "" -#: ../../../CHANGELOG.md:35 +#: ../../../CHANGELOG.md:642 msgid "The playbook will let you know if you're using any `matrix_conduwuit_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the service manually](./docs/configuring-playbook-conduwuit.md#uninstalling-the-service-manually)." msgstr "" -#: ../../../CHANGELOG.md:37 +#: ../../../CHANGELOG.md:644 msgid "Since [Continuwuity](configuring-playbook-continuwuity.md) is a drop-in replacement for conduwuit, migration is possible. Please refer to [this section](./configuring-playbook-continuwuity.md#migrating-from-conduwuit) for details." msgstr "" -#: ../../../CHANGELOG.md:39 +#: ../../../CHANGELOG.md:646 msgid "2026-02-09" msgstr "" -#: ../../../CHANGELOG.md:41 +#: ../../../CHANGELOG.md:648 msgid "(BC Break) matrix-media-repo datastore IDs are now required in `vars.yml`" msgstr "" -#: ../../../CHANGELOG.md:43 +#: ../../../CHANGELOG.md:650 msgid "**Affects**: users with [matrix-media-repo](docs/configuring-playbook-matrix-media-repo.md) enabled (`matrix_media_repo_enabled: true`)" msgstr "" -#: ../../../CHANGELOG.md:45 +#: ../../../CHANGELOG.md:652 msgid "The `matrix_media_repo_datastore_file_id` and `matrix_media_repo_datastore_s3_id` variables are no longer auto-configured with values. They must now be explicitly defined in your `vars.yml` file. The playbook will fail with a helpful error if they are not set (when needed)." msgstr "" -#: ../../../CHANGELOG.md:47 +#: ../../../CHANGELOG.md:654 msgid "These were never meant to be auto-configured. They were derived from `matrix_homeserver_generic_secret_key`, which is intended for secrets that are OK to change subsequently (and Ansible would assist in propagating these changes). matrix-media-repo datastore IDs are not secrets — they are static identifiers linking media to storage backends, and **must not change** after first use." msgstr "" -#: ../../../CHANGELOG.md:49 +#: ../../../CHANGELOG.md:656 msgid "**For existing installations**, retrieve your current values from the server:" msgstr "" -#: ../../../CHANGELOG.md:55 +#: ../../../CHANGELOG.md:662 msgid "Then add to your `vars.yml`:" msgstr "" -#: ../../../CHANGELOG.md:64 +#: ../../../CHANGELOG.md:671 msgid "**Why do this?**: This change allows us to **remove the [passlib](https://passlib.readthedocs.io/en/stable/index.html) Python library** from the [prerequisites](docs/prerequisites.md), as it was the last component that depended on it." msgstr "" -#: ../../../CHANGELOG.md:66 +#: ../../../CHANGELOG.md:673 msgid "2026-02-08" msgstr "" -#: ../../../CHANGELOG.md:68 +#: ../../../CHANGELOG.md:675 msgid "Zulip bridge has been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:70 +#: ../../../CHANGELOG.md:677 msgid "Zulip bridge has been removed from the playbook, as it doesn't work, and the maintainer seems to have abandoned it. See [this issue](https://github.com/GearKite/MatrixZulipBridge/issues/23) for more context." msgstr "" -#: ../../../CHANGELOG.md:72 +#: ../../../CHANGELOG.md:679 msgid "Switched to faster secret derivation for service passwords" msgstr "" -#: ../../../CHANGELOG.md:74 +#: ../../../CHANGELOG.md:681 msgid "We've switched the method used for deriving service passwords (database passwords, appservice tokens, etc.) from the `matrix_homeserver_generic_secret_key` variable." msgstr "" -#: ../../../CHANGELOG.md:76 +#: ../../../CHANGELOG.md:683 msgid "The old method used `password_hash('sha512', rounds=655555)` (655,555 rounds of SHA-512 hashing), which was designed for protecting low-entropy human passwords against brute-force attacks. For deriving secrets from an already high-entropy secret key, this many rounds provide no additional security - the secret key's entropy is what protects the derived passwords, not the computational cost of hashing." msgstr "" -#: ../../../CHANGELOG.md:78 +#: ../../../CHANGELOG.md:685 msgid "The new method uses a single-round `hash('sha512')` with a unique salt per service. This is equally secure for this use case (SHA-512 remains preimage-resistant; brute-forcing a high-entropy key is infeasible regardless of rounds), while being dramatically faster." msgstr "" -#: ../../../CHANGELOG.md:80 +#: ../../../CHANGELOG.md:687 msgid "On a fast mini PC, evaluating `postgres_managed_databases` (which references multiple database passwords) dropped from **~10.7 seconds to ~0.6 seconds**. The Postgres role evaluates this variable multiple times during a run, so the cumulative savings are significant. All other roles that reference derived passwords also benefit." msgstr "" -#: ../../../CHANGELOG.md:82 +#: ../../../CHANGELOG.md:689 msgid "**What this means for users**: all derived service passwords (database passwords, appservice tokens, etc.) will change on the next playbook run. The main/superuser database password (`postgres_connection_password`) is not affected, as it is hardcoded in inventory variables rather than derived via hashing. All services will receive their new passwords as part of the same run, so this should be a seamless, non-user-impacting change." msgstr "" -#: ../../../CHANGELOG.md:84 +#: ../../../CHANGELOG.md:691 msgid "(BC Break) Dynamic DNS role has been relocated and variable names need adjustments" msgstr "" -#: ../../../CHANGELOG.md:86 +#: ../../../CHANGELOG.md:693 msgid "The role for Dynamic DNS has been relocated to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." msgstr "" -#: ../../../CHANGELOG.md:88 +#: ../../../CHANGELOG.md:695 msgid "Along with the relocation, the `matrix_dynamic_dns_` prefix on its variable names has been renamed to `ddclient_`, so you need to adjust your `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:92 +#: ../../../CHANGELOG.md:699 msgid "ma1sd has been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:94 +#: ../../../CHANGELOG.md:701 msgid "[ma1sd](./docs/configuring-playbook-ma1sd.md) has been removed from the playbook, as it has been unmaintained for a long time." msgstr "" -#: ../../../CHANGELOG.md:96 +#: ../../../CHANGELOG.md:703 msgid "The playbook will let you know if you're using any `matrix_ma1sd_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the component manually](./docs/configuring-playbook-ma1sd.md#uninstalling-the-component-manually)." msgstr "" -#: ../../../CHANGELOG.md:98 +#: ../../../CHANGELOG.md:705 msgid "Please note that some of the functions can be achieved with other components. For example, if you wish to implement LDAP integration, you might as well check out [the LDAP provider module for Synapse](./docs/configuring-playbook-ldap-auth.md) instead." msgstr "" -#: ../../../CHANGELOG.md:100 +#: ../../../CHANGELOG.md:707 msgid "2026-02-07" msgstr "" -#: ../../../CHANGELOG.md:102 +#: ../../../CHANGELOG.md:709 msgid "(BC Break) Cinny role has been relocated and variable names need adjustments" msgstr "" -#: ../../../CHANGELOG.md:104 +#: ../../../CHANGELOG.md:711 msgid "The role for Cinny has been relocated to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." msgstr "" -#: ../../../CHANGELOG.md:106 +#: ../../../CHANGELOG.md:713 msgid "Along with the relocation, the `matrix_client_cinny_` prefix was dropped from its variable names, so you need to adjust your `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:110 +#: ../../../CHANGELOG.md:717 msgid "`matrix_client_cinny_` -> `cinny_`" msgstr "" -#: ../../../CHANGELOG.md:114 +#: ../../../CHANGELOG.md:721 msgid "The Sliding Sync proxy has been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:116 +#: ../../../CHANGELOG.md:723 msgid "The [Sliding Sync proxy](./docs/configuring-playbook-sliding-sync-proxy.md) has been removed from the playbook, as it's been replaced with a different method (called Simplified Sliding Sync) integrated to newer homeservers by default (**Conduit** homeserver from version `0.6.0` or **Synapse** from version `1.114`)." msgstr "" -#: ../../../CHANGELOG.md:118 +#: ../../../CHANGELOG.md:725 msgid "The playbook will let you know if you're using any `matrix_sliding_sync_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the proxy manually](./docs/configuring-playbook-sliding-sync-proxy.md#uninstalling-the-proxy-manually)." msgstr "" -#: ../../../CHANGELOG.md:120 +#: ../../../CHANGELOG.md:727 msgid "2026-02-04" msgstr "" -#: ../../../CHANGELOG.md:122 +#: ../../../CHANGELOG.md:729 msgid "baibot now supports OpenAI's built-in tools (Web Search and Code Interpreter)" msgstr "" -#: ../../../CHANGELOG.md:124 +#: ../../../CHANGELOG.md:731 msgid "**TLDR**: if you're using the [OpenAI provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openai) with [baibot](docs/configuring-playbook-bot-baibot.md), you can now enable [built-in tools](https://github.com/etkecc/baibot/blob/61d18b2/docs/features.md#%EF%B8%8F-built-in-tools-openai-only) (`web_search` and `code_interpreter`) to extend the model's capabilities." msgstr "" -#: ../../../CHANGELOG.md:126 +#: ../../../CHANGELOG.md:733 msgid "These tools are **disabled by default** and can be enabled via Ansible variables for static agent configurations:" msgstr "" -#: ../../../CHANGELOG.md:133 +#: ../../../CHANGELOG.md:740 msgid "Users who define agents dynamically at runtime will need to [update their agents](https://github.com/etkecc/baibot/blob/61d18b2/docs/agents.md#updating-agents) to enable these tools. See the [baibot v1.14.0 changelog](https://github.com/etkecc/baibot/blob/61d18b2/CHANGELOG.md) for details." msgstr "" -#: ../../../CHANGELOG.md:135 +#: ../../../CHANGELOG.md:742 msgid "Whoami-based sync worker routing for improved sticky sessions for Synapse" msgstr "" -#: ../../../CHANGELOG.md:137 +#: ../../../CHANGELOG.md:744 msgid "Deployments using [Synapse workers](./docs/configuring-playbook-synapse.md#load-balancing-with-workers) now benefit from improved sync worker routing via a new whoami-based mechanism (making use of the [whoami Matrix Client-Server API](https://spec.matrix.org/v1.17/client-server-api/#get_matrixclientv3accountwhoami))." msgstr "" -#: ../../../CHANGELOG.md:139 +#: ../../../CHANGELOG.md:746 msgid "Previously, sticky routing for sync workers relied on parsing usernames from access tokens, which only worked with native Synapse tokens (`syt__...`). This approach failed for [Matrix Authentication Service](docs/configuring-playbook-matrix-authentication-service.md) (MAS) deployments, where tokens are opaque and don't contain username information. This resulted in device-level stickiness (same token → same worker) rather than user-level stickiness (same user → same worker regardless of device), leading to suboptimal cache utilization on sync workers." msgstr "" -#: ../../../CHANGELOG.md:141 +#: ../../../CHANGELOG.md:748 msgid "The new implementation calls Synapse's `/whoami` endpoint to resolve access tokens to usernames, enabling proper user-level sticky routing regardless of the authentication system in use (native Synapse auth, MAS, etc.). Results are cached to minimize overhead." msgstr "" -#: ../../../CHANGELOG.md:143 +#: ../../../CHANGELOG.md:750 msgid "This change:" msgstr "" -#: ../../../CHANGELOG.md:144 +#: ../../../CHANGELOG.md:751 msgid "**Automatically enables** when sync workers are configured (no action required)" msgstr "" -#: ../../../CHANGELOG.md:145 +#: ../../../CHANGELOG.md:752 msgid "**Works universally** with any authentication system" msgstr "" -#: ../../../CHANGELOG.md:146 +#: ../../../CHANGELOG.md:753 msgid "**Replaces the old implementation** entirely to keep the codebase simple" msgstr "" -#: ../../../CHANGELOG.md:147 +#: ../../../CHANGELOG.md:754 msgid "**Adds minimal overhead** (one cached internal subrequest per sync request) for non-MAS deployments" msgstr "" -#: ../../../CHANGELOG.md:149 +#: ../../../CHANGELOG.md:756 msgid "For debugging, you can enable verbose logging and/or response headers showing routing decisions:" msgstr "" -#: ../../../CHANGELOG.md:160 +#: ../../../CHANGELOG.md:767 msgid "2025-12-09" msgstr "" -#: ../../../CHANGELOG.md:162 +#: ../../../CHANGELOG.md:769 msgid "Traefik Cert Dumper upgrade" msgstr "" -#: ../../../CHANGELOG.md:164 +#: ../../../CHANGELOG.md:771 msgid "The variable `traefik_certs_dumper_ssl_dir_path` was renamed to `traefik_certs_dumper_ssl_path`. Users who use [their own webserver with Traefik](docs/configuring-playbook-own-webserver.md) may need to adjust their configuration." msgstr "" -#: ../../../CHANGELOG.md:166 +#: ../../../CHANGELOG.md:773 msgid "The variable `traefik_certs_dumper_dumped_certificates_dir_path` was renamed to `traefik_certs_dumper_dumped_certificates_path`. Users who use [SRV Server Delegation](docs/howto-srv-server-delegation.md) may need to adjust their configuration." msgstr "" -#: ../../../CHANGELOG.md:168 +#: ../../../CHANGELOG.md:775 msgid "2025-11-23" msgstr "" -#: ../../../CHANGELOG.md:170 +#: ../../../CHANGELOG.md:777 msgid "Matrix.to support" msgstr "" -#: ../../../CHANGELOG.md:172 +#: ../../../CHANGELOG.md:779 msgid "The playbook now supports [Matrix.to](https://github.com/matrix-org/matrix.to) — a simple URL redirection service which powers [matrix.to](https://matrix.to)." msgstr "" -#: ../../../CHANGELOG.md:174 +#: ../../../CHANGELOG.md:781 msgid "To learn more, see our [Setting up Matrix.to](docs/configuring-playbook-matrixto.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:176 +#: ../../../CHANGELOG.md:783 msgid "2025-11-09" msgstr "" -#: ../../../CHANGELOG.md:178 +#: ../../../CHANGELOG.md:785 msgid "matrix-appservice-webhooks has been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:180 +#: ../../../CHANGELOG.md:787 msgid "[matrix-appservice-webhooks](./docs/configuring-playbook-bridge-appservice-webhooks.md) has been removed from the playbook, as it has been deprecated since more than several years." msgstr "" -#: ../../../CHANGELOG.md:182 +#: ../../../CHANGELOG.md:789 msgid "The playbook will let you know if you're using any `matrix_appservice_webhooks_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the bridge manually](./docs/configuring-playbook-bridge-appservice-webhooks.md#uninstalling-the-bridge-manually)." msgstr "" -#: ../../../CHANGELOG.md:184 +#: ../../../CHANGELOG.md:791 msgid "mautrix-facebook and mautrix-instagram have been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:186 +#: ../../../CHANGELOG.md:793 msgid "[mautrix-facebook](./docs/configuring-playbook-bridge-mautrix-facebook.md) and [mautrix-instagram](./docs/configuring-playbook-bridge-mautrix-instagram.md) have been removed from the playbook, as they have been deprecated in favor of the [mautrix-meta](https://github.com/mautrix/meta) Messenger/Instagram bridge, integrated to the playbook at [2024-02-19](#2024-02-19)." msgstr "" -#: ../../../CHANGELOG.md:188 -#: ../../../CHANGELOG.md:220 +#: ../../../CHANGELOG.md:795 +#: ../../../CHANGELOG.md:827 msgid "The playbook will let you know if you're using any variables for those bridges:" msgstr "" -#: ../../../CHANGELOG.md:190 +#: ../../../CHANGELOG.md:797 msgid "`matrix_mautrix_facebook_*`" msgstr "" -#: ../../../CHANGELOG.md:191 +#: ../../../CHANGELOG.md:798 msgid "`matrix_mautrix_instagram_*`" msgstr "" -#: ../../../CHANGELOG.md:193 -#: ../../../CHANGELOG.md:227 +#: ../../../CHANGELOG.md:800 +#: ../../../CHANGELOG.md:834 msgid "You'll need to remove them from `vars.yml` and potentially uninstall them manually. Consult pages below for details:" msgstr "" -#: ../../../CHANGELOG.md:195 +#: ../../../CHANGELOG.md:802 msgid "[Instruction for mautrix-facebook](./docs/configuring-playbook-bridge-mautrix-facebook.md#uninstalling-the-bridge-manually)" msgstr "" -#: ../../../CHANGELOG.md:196 +#: ../../../CHANGELOG.md:803 msgid "[Instruction for mautrix-instagram](./docs/configuring-playbook-bridge-mautrix-instagram.md#uninstalling-the-bridge-manually)" msgstr "" -#: ../../../CHANGELOG.md:198 +#: ../../../CHANGELOG.md:805 msgid "2025-11-08" msgstr "" -#: ../../../CHANGELOG.md:200 +#: ../../../CHANGELOG.md:807 msgid "MatrixZulipBridge support" msgstr "" -#: ../../../CHANGELOG.md:202 +#: ../../../CHANGELOG.md:809 msgid "Thanks to [Suguru Hirahara](https://github.com/luixxiul), the playbook now supports the [GearKite/MatrixZulipBridge](https://github.com/GearKite/MatrixZulipBridg) bridge for bridging Matrix to [Zulip](https://zulip.com/)." msgstr "" -#: ../../../CHANGELOG.md:204 +#: ../../../CHANGELOG.md:811 msgid "To learn more, see our [Setting up Zulip bridging](docs/configuring-playbook-bridge-zulip.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:206 +#: ../../../CHANGELOG.md:813 msgid "2025-11-07" msgstr "" -#: ../../../CHANGELOG.md:208 +#: ../../../CHANGELOG.md:815 msgid "The matrix-chatgpt-bot has been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:210 +#: ../../../CHANGELOG.md:817 msgid "The [matrix-bot-chatgpt](./docs/configuring-playbook-bot-chatgpt.md) has been removed from the playbook, as it has been deprecated since September 2024." msgstr "" -#: ../../../CHANGELOG.md:212 +#: ../../../CHANGELOG.md:819 msgid "The playbook will let you know if you're using any `matrix_bot_chatgpt_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the bot manually](./docs/configuring-playbook-bot-chatgpt.md#uninstalling-matrix-chatgpt-bot-manually)." msgstr "" -#: ../../../CHANGELOG.md:214 +#: ../../../CHANGELOG.md:821 msgid "2025-11-05" msgstr "" -#: ../../../CHANGELOG.md:216 +#: ../../../CHANGELOG.md:823 msgid "The MX Puppet bridges for Discord, Instagram, Slack, and Twitter have been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:218 +#: ../../../CHANGELOG.md:825 msgid "The MX Puppet bridges for Discord, Instagram, Slack, and Twitter have been removed from the playbook, as they have been unmaintained for more than several years and do not support important features like authenticated media. See [this issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3867) for the context." msgstr "" -#: ../../../CHANGELOG.md:222 +#: ../../../CHANGELOG.md:829 msgid "`matrix_mx_puppet_discord_*`" msgstr "" -#: ../../../CHANGELOG.md:223 +#: ../../../CHANGELOG.md:830 msgid "`matrix_mx_puppet_instagram_*`" msgstr "" -#: ../../../CHANGELOG.md:224 +#: ../../../CHANGELOG.md:831 msgid "`matrix_mx_puppet_slack_*`" msgstr "" -#: ../../../CHANGELOG.md:225 +#: ../../../CHANGELOG.md:832 msgid "`matrix_mx_puppet_twitter_*`" msgstr "" -#: ../../../CHANGELOG.md:229 +#: ../../../CHANGELOG.md:836 msgid "[Instruction for MX Puppet Discord bridge](./docs/configuring-playbook-bridge-mx-puppet-discord.md#uninstalling-the-bridge-manually)" msgstr "" -#: ../../../CHANGELOG.md:230 +#: ../../../CHANGELOG.md:837 msgid "[Instruction for MX Puppet Instagram bridge](./docs/configuring-playbook-bridge-mx-puppet-instagram.md#uninstalling-the-bridge-manually)" msgstr "" -#: ../../../CHANGELOG.md:231 +#: ../../../CHANGELOG.md:838 msgid "[Instruction for MX Puppet Slack bridge](./docs/configuring-playbook-bridge-mx-puppet-slack.md#uninstalling-the-bridge-manually)" msgstr "" -#: ../../../CHANGELOG.md:232 +#: ../../../CHANGELOG.md:839 msgid "[Instruction for MX Puppet Twitter bridge](./docs/configuring-playbook-bridge-mx-puppet-twitter.md#uninstalling-the-bridge-manually)" msgstr "" -#: ../../../CHANGELOG.md:234 +#: ../../../CHANGELOG.md:841 msgid "2025-11-04" msgstr "" -#: ../../../CHANGELOG.md:236 +#: ../../../CHANGELOG.md:843 msgid "The Go Skype bridge has been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:238 +#: ../../../CHANGELOG.md:845 msgid "The [go-skype-bridge](./docs/configuring-playbook-bridge-go-skype-bridge.md) has been removed from the playbook, as Skype has been discontinued since the May 2025." msgstr "" -#: ../../../CHANGELOG.md:240 +#: ../../../CHANGELOG.md:847 msgid "The playbook will let you know if you're using any `matrix_go_skype_bridge_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the bridge manually](./docs/configuring-playbook-bridge-go-skype-bridge.md#uninstalling-the-bridge-manually)." msgstr "" -#: ../../../CHANGELOG.md:242 +#: ../../../CHANGELOG.md:849 msgid "2025-10-02" msgstr "" -#: ../../../CHANGELOG.md:244 +#: ../../../CHANGELOG.md:851 msgid "Element Admin support" msgstr "" -#: ../../../CHANGELOG.md:246 +#: ../../../CHANGELOG.md:853 msgid "The playbook now supports [Element Admin](./docs/configuring-playbook-element-admin.md) - a new web-based administration panel for Synapse and [Matrix Authentication Service](./docs/configuring-playbook-matrix-authentication-service.md)." msgstr "" -#: ../../../CHANGELOG.md:248 +#: ../../../CHANGELOG.md:855 msgid "Deployments based on Matrix Authentication Service may find it useful to run both Synapse Admin and Element Admin at the same time." msgstr "" -#: ../../../CHANGELOG.md:250 +#: ../../../CHANGELOG.md:857 msgid "Deployments that don't rely on Matrix Authentication Service are unlikely to find anything useful in Element Admin right now (it's too basic in its current form)." msgstr "" -#: ../../../CHANGELOG.md:253 +#: ../../../CHANGELOG.md:860 msgid "2025-04-26" msgstr "" -#: ../../../CHANGELOG.md:255 +#: ../../../CHANGELOG.md:862 msgid "Continuwuity support" msgstr "" -#: ../../../CHANGELOG.md:257 +#: ../../../CHANGELOG.md:864 msgid "Thanks to [Virkkunen](https://github.com/Virkkunen), we now have optional experimental [Continuwuity](./docs/configuring-playbook-continuwuity.md) homeserver support." msgstr "" -#: ../../../CHANGELOG.md:259 +#: ../../../CHANGELOG.md:866 msgid "Continuwuity is a fork of [conduwuit](./docs/configuring-playbook-conduwuit.md), which the playbook also supports. It appears that conduwuit has been abandoned and various forks (like Continuwuity, [Tuwunel](https://github.com/matrix-construct/tuwunel) and possibly others) are continuing in its path." msgstr "" -#: ../../../CHANGELOG.md:261 -#: ../../../CHANGELOG.md:474 -msgid "Existing installations do **not** need to be updated. **Synapse is still the default homeserver implementation** installed by the playbook." -msgstr "" - -#: ../../../CHANGELOG.md:263 +#: ../../../CHANGELOG.md:870 msgid "People that used to run conduwuit, may wish to:" msgstr "" -#: ../../../CHANGELOG.md:265 +#: ../../../CHANGELOG.md:872 msgid "either [migrate from conduwuit to Continuwuity](./docs/configuring-playbook-continuwuity.md#migrating-from-conduwuit)" msgstr "" -#: ../../../CHANGELOG.md:266 +#: ../../../CHANGELOG.md:873 msgid "or wait for some of the other forks to progress and for support for them to get added to the playbook" msgstr "" -#: ../../../CHANGELOG.md:268 +#: ../../../CHANGELOG.md:875 msgid "**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse/Conduit/Dendrite to Continuwuity) without data loss." msgstr "" -#: ../../../CHANGELOG.md:271 +#: ../../../CHANGELOG.md:878 msgid "2025-04-09" msgstr "" -#: ../../../CHANGELOG.md:273 +#: ../../../CHANGELOG.md:880 msgid "Element Call frontend installation is now optional" msgstr "" -#: ../../../CHANGELOG.md:275 +#: ../../../CHANGELOG.md:882 msgid "Because all Element clients (Element Web and Element X mobile) now embed and use their own Element Call frontend application (and not the one hosted via the playbook), it makes little sense for the playbook to self-host the Element Call frontend for you. Setting up the frontend requires an additional hostname (DNS setup) and it won't be used by Element clients anyway, so **we now recommend not installing the Element Call frontend**." msgstr "" -#: ../../../CHANGELOG.md:277 +#: ../../../CHANGELOG.md:884 msgid "💡 A reason you may wish to continue installing the Element Call frontend (despite Matrix clients not making use of it), is if you need to use it standalone - directly via a browser (without a Matrix client)." msgstr "" -#: ../../../CHANGELOG.md:279 +#: ../../../CHANGELOG.md:886 msgid "The playbook now lets you [Decide between Element Call vs just the Matrix RTC stack](./docs/configuring-playbook-element-call.md#decide-between-element-call-vs-just-the-matrix-rtc-stack)." msgstr "" -#: ../../../CHANGELOG.md:281 +#: ../../../CHANGELOG.md:888 msgid "If you've already installed Element Call (via `matrix_element_call_enabled: true`), you can switch to installing just the [Matrix RTC (Real-Time Communication) stack](./docs/configuring-playbook-matrix-rtc.md) (all supporting services **without the Element Call frontend**) by:" msgstr "" -#: ../../../CHANGELOG.md:283 +#: ../../../CHANGELOG.md:890 msgid "Adjusting your `vars.yml` configuration like this:" msgstr "" -#: ../../../CHANGELOG.md:290 +#: ../../../CHANGELOG.md:897 msgid "[Re-running the playbook](./docs/installing.md) with the `setup-all` Ansible tag (e.g. `just setup-all`)" msgstr "" -#: ../../../CHANGELOG.md:292 +#: ../../../CHANGELOG.md:899 msgid "Getting rid of the `call.element.example.com` DNS record" msgstr "" -#: ../../../CHANGELOG.md:295 +#: ../../../CHANGELOG.md:902 msgid "2025-03-15" msgstr "" -#: ../../../CHANGELOG.md:297 +#: ../../../CHANGELOG.md:904 msgid "Element Call support" msgstr "" -#: ../../../CHANGELOG.md:299 +#: ../../../CHANGELOG.md:906 msgid "The playbook now supports [Element Call](https://github.com/element-hq/element-call) as an optional feature. Thanks to [wjbeckett](https://github.com/wjbeckett) for getting us started via [PR#3562](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3562)." msgstr "" -#: ../../../CHANGELOG.md:301 +#: ../../../CHANGELOG.md:908 msgid "Element Call is a native Matrix video conferencing application developed by [Element](https://element.io/) that has the goal of replacing [Jitsi](./docs/configuring-playbook-jitsi.md) and the old WebRTC stack used in previous Element versions." msgstr "" -#: ../../../CHANGELOG.md:303 +#: ../../../CHANGELOG.md:910 msgid "💡 For now, Element Call is only supported with the [Synapse](docs/configuring-playbook-synapse.md) homeserver (with [federation](docs/configuring-playbook-federation.md) enabled) and [Element Web](docs/configuring-playbook-client-element-web.md) and Element X mobile clients. See the [Prerequisites](docs/configuring-playbook-element-call.md#prerequisites) section of the [Element Call documentation](docs/configuring-playbook-element-call.md) for more details." msgstr "" -#: ../../../CHANGELOG.md:305 +#: ../../../CHANGELOG.md:912 msgid "To get started, see the [Configuring Element Call](docs/configuring-playbook-element-call.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:308 +#: ../../../CHANGELOG.md:915 msgid "2025-03-08" msgstr "" -#: ../../../CHANGELOG.md:310 +#: ../../../CHANGELOG.md:917 msgid "6️⃣ IPv6 support enablement recommended by default" msgstr "" -#: ../../../CHANGELOG.md:312 +#: ../../../CHANGELOG.md:919 msgid "Our [default example configuration](./examples/vars.yml) and [Configuring DNS](./docs/configuring-dns.md) guides now recommend enabling [IPv6](https://en.wikipedia.org/wiki/IPv6) support. We recommend that everyone enables IPv6 support for their Matrix server, even if they don't have IPv6 connectivity yet." msgstr "" -#: ../../../CHANGELOG.md:314 +#: ../../../CHANGELOG.md:921 msgid "Our new [Configuring IPv6](./docs/configuring-ipv6.md) documentation page has more details about the playbook's IPv6 support." msgstr "" -#: ../../../CHANGELOG.md:316 +#: ../../../CHANGELOG.md:923 msgid "**Existing playbook users** will **need to do some manual work** to enable IPv6 support. This consists of:" msgstr "" -#: ../../../CHANGELOG.md:318 +#: ../../../CHANGELOG.md:925 msgid "enabling IPv6 support for the Docker container networks:" msgstr "" -#: ../../../CHANGELOG.md:319 +#: ../../../CHANGELOG.md:926 msgid "add `devture_systemd_docker_base_ipv6_enabled: true` to their `vars.yml` configuration file" msgstr "" -#: ../../../CHANGELOG.md:320 +#: ../../../CHANGELOG.md:927 msgid "stop all services (`just stop-all`)" msgstr "" -#: ../../../CHANGELOG.md:321 +#: ../../../CHANGELOG.md:928 msgid "delete all container networks on the server: `docker network rm $(docker network ls -q)`" msgstr "" -#: ../../../CHANGELOG.md:322 +#: ../../../CHANGELOG.md:929 msgid "re-run the playbook fully: `just install-all`" msgstr "" -#: ../../../CHANGELOG.md:324 +#: ../../../CHANGELOG.md:931 msgid "[configuring IPv6 (`AAAA`) DNS records](./docs/configuring-ipv6.md#configuring-dns-records-for-ipv6)" msgstr "" -#: ../../../CHANGELOG.md:326 +#: ../../../CHANGELOG.md:933 msgid "2025-02-26" msgstr "" -#: ../../../CHANGELOG.md:328 +#: ../../../CHANGELOG.md:935 msgid "🪦 Bye-bye, Email2Matrix" msgstr "" -#: ../../../CHANGELOG.md:330 +#: ../../../CHANGELOG.md:937 msgid "The [Email2Matrix](./docs/configuring-playbook-email2matrix.md) service has been superseded by the [Postmoogle](./docs/configuring-playbook-bridge-postmoogle.md) bridge for a long time now and was completely removed from the playbook today." msgstr "" -#: ../../../CHANGELOG.md:332 +#: ../../../CHANGELOG.md:939 msgid "If you still have the Email2Matrix component installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually as described in the [Uninstalling Email2Matrix manually](./docs/configuring-playbook-email2matrix.md#uninstalling-email2matrix-manually) section of the documentation. The playbook will warn you if there are any `matrix_email2matrix_*` variables still remaining in your configuration." msgstr "" -#: ../../../CHANGELOG.md:335 +#: ../../../CHANGELOG.md:942 msgid "2025-02-23" msgstr "" -#: ../../../CHANGELOG.md:337 +#: ../../../CHANGELOG.md:944 msgid "The playbook defaults to exposing the Coturn STUN port (3478) over UDP once again" msgstr "" -#: ../../../CHANGELOG.md:339 +#: ../../../CHANGELOG.md:946 msgid "Recently, we made the playbook [default to exposing the Coturn STUN port (3478) only over TCP](#the-playbook-now-defaults-to-exposing-the-coturn-stun-port-3478-only-over-tcp) to reduce the severity of DDoS amplification/reflection attacks." msgstr "" -#: ../../../CHANGELOG.md:341 +#: ../../../CHANGELOG.md:948 msgid "It seems like old Element clients on mobile devices only support talking to the STUN port over UDP, not TCP. To accommodate such ancient clients, we're now **reversing this change** and **defaulting to exposing the Coturn STUN port (3478) over UDP once again**." msgstr "" -#: ../../../CHANGELOG.md:344 +#: ../../../CHANGELOG.md:951 msgid "In light of this new information, you have 2 options:" msgstr "" -#: ../../../CHANGELOG.md:346 +#: ../../../CHANGELOG.md:953 msgid "**If you already adapted to the previous change and would like to adapt to this change one again**:" msgstr "" -#: ../../../CHANGELOG.md:348 +#: ../../../CHANGELOG.md:955 msgid "make sure the `3478/udp` port is whitelisted in your external firewall (if you have one) once again." msgstr "" -#: ../../../CHANGELOG.md:350 +#: ../../../CHANGELOG.md:957 msgid "**If you don't care about old Element clients and wish to reduce the severity of DDoS amplification/reflection attacks**:" msgstr "" -#: ../../../CHANGELOG.md:352 +#: ../../../CHANGELOG.md:959 msgid "Consider closing the STUN/UDP port with the following configuration:" msgstr "" -#: ../../../CHANGELOG.md:358 +#: ../../../CHANGELOG.md:965 msgid "Consider keeping `3478/udp` blocked in your external firewall (if you have one)" msgstr "" -#: ../../../CHANGELOG.md:360 +#: ../../../CHANGELOG.md:967 msgid "2025-02-21" msgstr "" -#: ../../../CHANGELOG.md:362 +#: ../../../CHANGELOG.md:969 msgid "Docker daemon options are no longer adjusted when IPv6 is enabled" msgstr "" -#: ../../../CHANGELOG.md:364 +#: ../../../CHANGELOG.md:971 msgid "We landed [initial IPv6 support](#initial-work-on-ipv6-support) in the past via a `devture_systemd_docker_base_ipv6_enabled` variable that one had to toggle to `true`." msgstr "" -#: ../../../CHANGELOG.md:366 +#: ../../../CHANGELOG.md:973 msgid "This variable did **2 different things at once**:" msgstr "" -#: ../../../CHANGELOG.md:368 +#: ../../../CHANGELOG.md:975 msgid "ensured that container networks were created with IPv6 being enabled" msgstr "" -#: ../../../CHANGELOG.md:369 +#: ../../../CHANGELOG.md:976 msgid "adjusted the Docker daemon's configuration to set `experimental: true` and `ip6tables: true` (a necessary prerequisite for creating IPv6-enabled networks)" msgstr "" -#: ../../../CHANGELOG.md:371 +#: ../../../CHANGELOG.md:978 msgid "Since Docker 27.0.1's [changes to how it handles IPv6](https://docs.docker.com/engine/release-notes/27/#ipv6), **adjusting the Docker daemon's configuration is no longer necessary**, because:" msgstr "" -#: ../../../CHANGELOG.md:372 +#: ../../../CHANGELOG.md:979 msgid "`ip6tables` defaults to `true` for everyone" msgstr "" -#: ../../../CHANGELOG.md:373 +#: ../../../CHANGELOG.md:980 msgid "`ip6tables` is out of the experimental phase, so `experimental` is no longer necessary" msgstr "" -#: ../../../CHANGELOG.md:375 +#: ../../../CHANGELOG.md:982 msgid "In light of this, we're introducing a new variable (`devture_systemd_docker_base_ipv6_daemon_options_changing_enabled`) for controlling if IPv6 should be force-enabled in the Docker daemon's configuration options. Since most people should be on a modern enough Docker daemon version which doesn't require such changes, this variable defaults to `false`." msgstr "" -#: ../../../CHANGELOG.md:378 +#: ../../../CHANGELOG.md:985 msgid "This change affects you like this:" msgstr "" -#: ../../../CHANGELOG.md:380 +#: ../../../CHANGELOG.md:987 msgid "✅ if you're **not explicitly enabling IPv6** (via `devture_systemd_docker_base_ipv6_enabled` in your configuration): you're unaffected" msgstr "" -#: ../../../CHANGELOG.md:381 +#: ../../../CHANGELOG.md:988 msgid "❓ if you're **explicitly enabling IPv6** (via `devture_systemd_docker_base_ipv6_enabled` in your configuration):" msgstr "" -#: ../../../CHANGELOG.md:382 +#: ../../../CHANGELOG.md:989 msgid "✅ .. and you're on a modern enough Docker version (which you most likely are): the playbook will no longer mess with your Docker daemon options. You're unaffected." msgstr "" -#: ../../../CHANGELOG.md:383 +#: ../../../CHANGELOG.md:990 msgid "🔧 .. and you're on an old Docker version, you **are affected** and need to use the following configuration to restore the old behavior:" msgstr "" -#: ../../../CHANGELOG.md:394 +#: ../../../CHANGELOG.md:1001 msgid "Support for bridging to Bluesky via mautrix-bluesky" msgstr "" -#: ../../../CHANGELOG.md:396 +#: ../../../CHANGELOG.md:1003 msgid "Thanks to [Zepmann](https://github.com/Zepmann), the playbook now supports bridging to [Bluesky](https://bsky.app/) via [mautrix-bluesky](https://github.com/mautrix/bluesky)." msgstr "" -#: ../../../CHANGELOG.md:398 +#: ../../../CHANGELOG.md:1005 msgid "To learn more, see our [Setting up mautrix-bluesky](./docs/configuring-playbook-bridge-mautrix-bluesky.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:401 +#: ../../../CHANGELOG.md:1008 msgid "2025-02-19" msgstr "" -#: ../../../CHANGELOG.md:403 +#: ../../../CHANGELOG.md:1010 msgid "The playbook now defaults to exposing the Coturn STUN port (3478) only over TCP" msgstr "" -#: ../../../CHANGELOG.md:405 +#: ../../../CHANGELOG.md:1012 msgid "We've previously done some work to **decrease the severity** of DDoS amplification attacks done through the [Coturn](./docs/configuring-playbook-turn.md)'s STUN port (2.8x -> 1.6x) as reported in [coturn: Lower DDoS amplification/reflection factor from 2.8 to 1.6 #2592](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2592)." msgstr "" -#: ../../../CHANGELOG.md:407 +#: ../../../CHANGELOG.md:1014 msgid "To **completely eliminate the problem** of DDoS amplification attacks done through the [Coturn](./docs/configuring-playbook-turn.md) STUN port even further (read more about this in [this article](https://stormwall.network/resources/blog/protect-against-ddos-based-on-stun-exploit)), the playbook now **disables exposure of the Coturn STUN port (`3478`) over UDP**. This is a bit heavy-handed, but is probably the only way to completely eliminate the problem." msgstr "" -#: ../../../CHANGELOG.md:409 +#: ../../../CHANGELOG.md:1016 msgid "The playbook now **only exposes the Coturn STUN port (`3478`) over TCP by default**." msgstr "" -#: ../../../CHANGELOG.md:411 +#: ../../../CHANGELOG.md:1018 msgid "💡 Users may wish to further remove the (now unnecessary) firewall rule allowing access to `3478/udp`." msgstr "" -#: ../../../CHANGELOG.md:413 +#: ../../../CHANGELOG.md:1020 msgid "If you'd like the Coturn STUN port to be exposed over UDP like before, you can revert to the previous behavior by using the following configuration in your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:419 -msgid "[!WARNING] People running Coturn directly on the `host` network (using `coturn_container_network: host`) will still have the STUN port exposed over UDP, as port exposure is done directly via Coturn and not via Docker. In such cases, the playbook cannot prevent `3478/udp` port exposure and you'd need to do it in another way (separate firewall rule, etc)." +#: ../../../CHANGELOG.md:1027 +msgid "People running Coturn directly on the `host` network (using `coturn_container_network: host`) will still have the STUN port exposed over UDP, as port exposure is done directly via Coturn and not via Docker. In such cases, the playbook cannot prevent `3478/udp` port exposure and you'd need to do it in another way (separate firewall rule, etc)." msgstr "" -#: ../../../CHANGELOG.md:423 +#: ../../../CHANGELOG.md:1030 msgid "2025-02-17" msgstr "" -#: ../../../CHANGELOG.md:425 +#: ../../../CHANGELOG.md:1032 msgid "FluffyChat Web support" msgstr "" -#: ../../../CHANGELOG.md:427 +#: ../../../CHANGELOG.md:1034 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook now supports [FluffyChat Web](https://github.com/krille-chan/fluffychat) as an additional Matrix client you can self-host." msgstr "" -#: ../../../CHANGELOG.md:429 +#: ../../../CHANGELOG.md:1036 msgid "To learn more, see our [Setting up FluffyChat Web](docs/configuring-playbook-client-fluffychat-web.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:432 +#: ../../../CHANGELOG.md:1039 msgid "2025-02-03" msgstr "" -#: ../../../CHANGELOG.md:434 +#: ../../../CHANGELOG.md:1041 msgid "The mautrix-hangouts bridge has been removed from the playbook" msgstr "" -#: ../../../CHANGELOG.md:436 +#: ../../../CHANGELOG.md:1043 msgid "The [mautrix-hangouts](./docs/configuring-playbook-bridge-mautrix-hangouts.md) bridge has been deprecated in the playbook since December 2024 and finally got completely removed from the playbook in February 2025." msgstr "" -#: ../../../CHANGELOG.md:438 +#: ../../../CHANGELOG.md:1045 msgid "This is because Google Hangouts has been discontinued since the 1st of November 2022." msgstr "" -#: ../../../CHANGELOG.md:440 +#: ../../../CHANGELOG.md:1047 msgid "The playbook will let you know if you're using any `matrix_mautrix_hangouts_*` variables. You'll need to remove them from `vars.yml` and potentially [uninstall the bridge manually](./docs/configuring-playbook-bridge-mautrix-hangouts.md#uninstalling-the-bridge-manually)." msgstr "" -#: ../../../CHANGELOG.md:443 +#: ../../../CHANGELOG.md:1050 msgid "2025-01-27" msgstr "" -#: ../../../CHANGELOG.md:445 +#: ../../../CHANGELOG.md:1052 msgid "Redis and KeyDB are no longer part of the playbook" msgstr "" -#: ../../../CHANGELOG.md:447 +#: ../../../CHANGELOG.md:1054 msgid "**TLDR**: The playbook now exclusively uses Valkey as its Redis-compatible memorystore implementation, removing support for Redis and KeyDB. Most users are unaffected by this change unless they explicitly configured Redis or KeyDB variables. Only users that were explicitly defining `redis_*` or `keydb_*` variables will need to update their configuration to use `valkey_*` variables instead." msgstr "" -#: ../../../CHANGELOG.md:449 +#: ../../../CHANGELOG.md:1056 msgid "The playbook has gone through several iterations of memorystore implementations:" msgstr "" -#: ../../../CHANGELOG.md:451 +#: ../../../CHANGELOG.md:1058 msgid "It initially used Redis, auto-installing it when needed by features/services" msgstr "" -#: ../../../CHANGELOG.md:452 +#: ../../../CHANGELOG.md:1059 msgid "[Switched to KeyDB](#backward-compatibility-break-the-playbook-now-defaults-to-keydb-instead-of-redis) as the default, while keeping Redis support for those who wished to remain on Redis" msgstr "" -#: ../../../CHANGELOG.md:453 +#: ../../../CHANGELOG.md:1060 msgid "[Switched to Valkey](#backward-compatibility-break-the-playbook-now-defaults-to-valkey-instead-of-keydb) due to [KeyDB issues](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3544), while keeping Redis and KeyDB support, for those who wished to remain on them" msgstr "" -#: ../../../CHANGELOG.md:455 +#: ../../../CHANGELOG.md:1062 msgid "To reduce configuration complexity and maintenance overhead, we are now:" msgstr "" -#: ../../../CHANGELOG.md:457 +#: ../../../CHANGELOG.md:1064 msgid "removing Redis and KeyDB support entirely" msgstr "" -#: ../../../CHANGELOG.md:458 +#: ../../../CHANGELOG.md:1065 msgid "using Valkey as the sole Redis-compatible memorystore implementation" msgstr "" -#: ../../../CHANGELOG.md:460 +#: ../../../CHANGELOG.md:1067 msgid "To update your configuration:" msgstr "" -#: ../../../CHANGELOG.md:462 +#: ../../../CHANGELOG.md:1069 msgid "**Most users** don't need to do anything" msgstr "" -#: ../../../CHANGELOG.md:463 +#: ../../../CHANGELOG.md:1070 msgid "**Users that were explicitly sticking to Redis/KeyDB** need to update their `vars.yml` to use `valkey_*` variables instead" msgstr "" -#: ../../../CHANGELOG.md:466 +#: ../../../CHANGELOG.md:1073 msgid "2025-01-19" msgstr "" -#: ../../../CHANGELOG.md:468 +#: ../../../CHANGELOG.md:1075 msgid "conduwuit support" msgstr "" -#: ../../../CHANGELOG.md:470 +#: ../../../CHANGELOG.md:1077 msgid "Thanks to [Virkkunen](https://github.com/Virkkunen), we now have optional experimental [conduwuit](https://conduwuit.puppyirl.gay/) homeserver support for new installations." msgstr "" -#: ../../../CHANGELOG.md:472 +#: ../../../CHANGELOG.md:1079 msgid "conduwuit is a fork of [Conduit](./docs/configuring-playbook-conduit.md), which the playbook also supports. See [Differences from upstream Conduit](https://conduwuit.puppyirl.gay/differences.html)." msgstr "" -#: ../../../CHANGELOG.md:476 +#: ../../../CHANGELOG.md:1083 msgid "To try out conduwuit, we recommend that you **use a new server**. Refer to our [Configuring conduwuit](./docs/configuring-playbook-conduwuit.md) guide for details." msgstr "" -#: ../../../CHANGELOG.md:478 +#: ../../../CHANGELOG.md:1085 msgid "**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse/Conduit/Dendrite to conduwuit) without data loss." msgstr "" -#: ../../../CHANGELOG.md:481 +#: ../../../CHANGELOG.md:1088 msgid "2025-01-14" msgstr "" -#: ../../../CHANGELOG.md:483 +#: ../../../CHANGELOG.md:1090 msgid "(Backward Compatibility Break) Synapse v1.122.0 requires Postgres v13" msgstr "" -#: ../../../CHANGELOG.md:485 +#: ../../../CHANGELOG.md:1092 msgid "The Synapse homeserver [requires Postgres v13 or newer](https://github.com/element-hq/synapse/issues/18034)." msgstr "" -#: ../../../CHANGELOG.md:487 +#: ../../../CHANGELOG.md:1094 msgid "If you've been maintaining your setup for a while and you haven't been doing [Postgres upgrades](docs/maintenance-postgres.md#upgrading-postgresql), you may be on an old version of Postgres. The easiest way to check is to see the contents of the `/matrix/postgres/data/PG_VERSION` file." msgstr "" -#: ../../../CHANGELOG.md:489 +#: ../../../CHANGELOG.md:1096 msgid "If you're on a Postgres version older than v13, you need to [upgrade your Postgres setup](docs/maintenance-postgres.md#upgrading-postgresql) or Synapse will produce an error on startup." msgstr "" -#: ../../../CHANGELOG.md:491 +#: ../../../CHANGELOG.md:1098 msgid "If you're using an external Postgres server (not installed by this playbook), you'll need to figure out how to upgrade it yourself." msgstr "" -#: ../../../CHANGELOG.md:493 +#: ../../../CHANGELOG.md:1100 msgid "If you're not ready to upgrade your Postgres setup yet, you can temporarily remain on an old Synapse version by adding the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:501 +#: ../../../CHANGELOG.md:1108 msgid "2024-11-26" msgstr "" -#: ../../../CHANGELOG.md:503 +#: ../../../CHANGELOG.md:1110 msgid "(Backward Compatibility Break) Synapse now defaults to enabling authenticated media" msgstr "" -#: ../../../CHANGELOG.md:505 +#: ../../../CHANGELOG.md:1112 msgid "**TLDR**: with this update, your Synapse homeserver will start requiring authentication for newly-uploaded media files. While the majority of the ecosystem (clients, bots, etc.) should support this, certain software may lack support for it (and you may wish to turn it off, if it's causing issues)." msgstr "" -#: ../../../CHANGELOG.md:507 +#: ../../../CHANGELOG.md:1114 msgid "The default configuration for the Synapse homeserver now [enforces Authenticated media by default](https://element-hq.github.io/synapse/v1.120/upgrade.html#authenticated-media-is-now-enforced-by-default)." msgstr "" -#: ../../../CHANGELOG.md:509 +#: ../../../CHANGELOG.md:1116 msgid "Servers like `matrix.org` have already [sunset unauthenticated media](https://matrix.org/blog/2024/06/26/sunsetting-unauthenticated-media/) months ago." msgstr "" -#: ../../../CHANGELOG.md:511 +#: ../../../CHANGELOG.md:1118 msgid "Now that **various clients, bots, bridges and extra services have caught up with authenticated media support**, Synapse developers seem confident that it's time to enable authenticated media by default." msgstr "" -#: ../../../CHANGELOG.md:513 +#: ../../../CHANGELOG.md:1120 msgid "We're changing the playbook configuration for authenticated media to keep up with upstream defaults changing." msgstr "" -#: ../../../CHANGELOG.md:515 +#: ../../../CHANGELOG.md:1122 msgid "Old and unmaintained bridges (like all mx-puppet bridges, etc.) do not support authenticated media. Other software may be similarly affected. If you experience issues with some Matrix-related software, you may wish to disable authenticated media and contact the software maintainers to let them know." msgstr "" -#: ../../../CHANGELOG.md:517 +#: ../../../CHANGELOG.md:1124 msgid "You can disable authenticated media at any time by setting `matrix_synapse_enable_authenticated_media: false` in your `vars.yml` configuration file and re-running the playbook." msgstr "" -#: ../../../CHANGELOG.md:520 +#: ../../../CHANGELOG.md:1127 msgid "2024-11-23" msgstr "" -#: ../../../CHANGELOG.md:522 +#: ../../../CHANGELOG.md:1129 msgid "(Backward Compatibility Break) The playbook now defaults to Valkey, instead of KeyDB" msgstr "" -#: ../../../CHANGELOG.md:524 +#: ../../../CHANGELOG.md:1131 msgid "**TLDR**: if the playbook installed KeyDB (or Redis) as a dependency for you before, it will now replace it with [Valkey](https://valkey.io/) (a drop-in alternative). We [previously switched from Redis to KeyDB](#backward-compatibility-break-the-playbook-now-defaults-to-keydb-instead-of-redis), but Valkey is a better alternative, so we're switching again." msgstr "" -#: ../../../CHANGELOG.md:526 +#: ../../../CHANGELOG.md:1133 msgid "The playbook used to install Redis or KeyDB if services have a need for a Redis-compatible implementation ([enabling worker support for Synapse](docs/configuring-playbook-synapse.md#load-balancing-with-workers), [enabling Hookshot encryption](docs/configuring-playbook-bridge-hookshot.md#end-to-bridge-encryption), etc.)." msgstr "" -#: ../../../CHANGELOG.md:528 +#: ../../../CHANGELOG.md:1135 msgid "Earlier this year, we switched from Redis to KeyDB — see [(Backward Compatibility Break) The playbook now defaults to KeyDB, instead of Redis](#backward-compatibility-break-the-playbook-now-defaults-to-keydb-instead-of-redis)." msgstr "" -#: ../../../CHANGELOG.md:530 +#: ../../../CHANGELOG.md:1137 msgid "Because Valkey seems to be a better successor to Redis (than KeyDB) and likely doesn't suffer from [issues like this one](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3544), we now replace KeyDB with Valkey." msgstr "" -#: ../../../CHANGELOG.md:532 +#: ../../../CHANGELOG.md:1139 msgid "Valkey (like KeyDB and Redis in the past) is an implicitly enabled dependency — you don't need custom configuration in `vars.yml` to enable it." msgstr "" -#: ../../../CHANGELOG.md:534 +#: ../../../CHANGELOG.md:1141 msgid "Next time your run the playbook (via the `setup-all` tag), **KeyDB will be automatically uninstalled and replaced with Valkey**. Some Synapse downtime may occur while the switch happens." msgstr "" -#: ../../../CHANGELOG.md:536 +#: ../../../CHANGELOG.md:1143 msgid "Users on `arm32` should be aware that there's **neither a prebuilt `arm32` container image for Valkey**, nor the Valkey role supports self-building yet. Users on this architecture likely don't run Synapse with workers, etc., so they're likely in no need of Valkey (or Redis/KeyDB). If Redis is necessary in an `arm32` deployment, disabling Valkey and making the playbook fall back to Redis is possible (see below)." msgstr "" -#: ../../../CHANGELOG.md:538 -#: ../../../CHANGELOG.md:878 +#: ../../../CHANGELOG.md:1145 +#: ../../../CHANGELOG.md:1485 msgid "**The playbook still supports Redis** and you can keep using Redis (for now) if you'd like, by adding this additional configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:549 +#: ../../../CHANGELOG.md:1156 msgid "**The playbook still supports KeyDB** and you can keep using KeyDB (for now) if you'd like, by adding this additional configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:559 +#: ../../../CHANGELOG.md:1166 msgid "At some point in time in the future, we'll remove both KeyDB and Redis from the playbook, so we recommend that you migrate to Valkey earlier anyway." msgstr "" -#: ../../../CHANGELOG.md:562 +#: ../../../CHANGELOG.md:1169 msgid "2024-11-14" msgstr "" -#: ../../../CHANGELOG.md:564 +#: ../../../CHANGELOG.md:1171 msgid "HTTP-compression support for Traefik-based setups" msgstr "" -#: ../../../CHANGELOG.md:566 +#: ../../../CHANGELOG.md:1173 msgid "The playbook now **automatically enables HTTP-compression support** for major services powered by the playbook, like [Cinny](./docs/configuring-playbook-client-cinny.md), [Element Web](./docs/configuring-playbook-client-element-web.md), [Hydrogen](./docs/configuring-playbook-client-hydrogen.md), as well as for Matrix Client-Server and Federation APIs (`matrix.example.com`)." msgstr "" -#: ../../../CHANGELOG.md:568 +#: ../../../CHANGELOG.md:1175 msgid "Other services installed by the playbook are currently not compression-enabled, but may become so over time. This change is rolled out on a per-service basis (as opposed to doing it globally, at the Traefik entrypoint level) to allow certain services or route endpoints which do not behave well when compressed (e.g. [issue 3749](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3749)) to be excluded from compression." msgstr "" -#: ../../../CHANGELOG.md:570 +#: ../../../CHANGELOG.md:1177 msgid "A long time ago, various services were operating with `gzip`-compression enabled at the nginx level. Since the switch to Traefik (see [Goodbye, `matrix-nginx-proxy` 🪦](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/57c5271d9d6265a34a9d9cceb93365f685074f96/CHANGELOG.md#goodbye-matrix-nginx-proxy-)), all services (with the exception of Matrix APIs for Synapse worker-enabled setups which are powered by `nginx` via `synapse-reverse-proxy-companion`) have been operating without HTTP-compression support." msgstr "" -#: ../../../CHANGELOG.md:572 +#: ../../../CHANGELOG.md:1179 msgid "HTTP-compression is now done via Traefik's [compress](https://doc.traefik.io/traefik/middlewares/http/compress/) middleware. We use the default configuration for this middleware, which enables `zstd`, `br` and `gzip` support (in this order). This middleware's configuration can be configured via variables in the Traefik role (see `traefik_config_http_middlewares_compression_middleware_options`)." msgstr "" -#: ../../../CHANGELOG.md:574 +#: ../../../CHANGELOG.md:1181 msgid "If you're using your own Traefik reverse-proxy server ([Traefik managed by you](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-you)) instead of the playbook's integrated Traefik service, you can benefit from the same by:" msgstr "" -#: ../../../CHANGELOG.md:576 +#: ../../../CHANGELOG.md:1183 msgid "defining a [compress](https://doc.traefik.io/traefik/middlewares/http/compress/) middleware (via the [file](https://doc.traefik.io/traefik/providers/file/) or [Docker](https://doc.traefik.io/traefik/providers/docker/) providers)" msgstr "" -#: ../../../CHANGELOG.md:577 +#: ../../../CHANGELOG.md:1184 msgid "setting `matrix_playbook_reverse_proxy_traefik_middleware_compression_enabled` to `true`" msgstr "" -#: ../../../CHANGELOG.md:578 +#: ../../../CHANGELOG.md:1185 msgid "specifying the middleware's name in `matrix_playbook_reverse_proxy_traefik_middleware_compression_name` (e.g. `matrix_playbook_reverse_proxy_traefik_middleware_compression_name: my-compression-middleware@file`)" msgstr "" -#: ../../../CHANGELOG.md:580 +#: ../../../CHANGELOG.md:1187 msgid "Timeout adjustments for Traefik-based setups" msgstr "" -#: ../../../CHANGELOG.md:582 +#: ../../../CHANGELOG.md:1189 msgid "The playbook now supports configuring various [transport.respondingTimeouts](https://doc.traefik.io/traefik/routing/entrypoints/#respondingtimeouts) timeout values (`readTimeout`, `writeTimeout`, `idleTimeout`) for the `web`, `web-secure` and `matrix-federation` entrypoints." msgstr "" -#: ../../../CHANGELOG.md:584 +#: ../../../CHANGELOG.md:1191 msgid "If you're using your own Traefik reverse-proxy server ([Traefik managed by you](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-you)) instead of the playbook's integrated Traefik service, you may wish to do similar configuration changes to your setup manually." msgstr "" -#: ../../../CHANGELOG.md:586 +#: ../../../CHANGELOG.md:1193 msgid "The most interesting of these is the `readTimeout` configuration value (the maximum duration for reading the entire request, including the body), which used to default to `60s`. For large and slowly progressing file uploads, `60s` would often not be enough for the transfer to finish and uploads would end up being interrupted. The playbook now raises the `readTimeout` value to 5 minutes (`300s`) to improve this use-case." msgstr "" -#: ../../../CHANGELOG.md:588 +#: ../../../CHANGELOG.md:1195 msgid "The `traefik_config_entrypoint_web_transport_respondingTimeouts_*` variables (for the `web` entrypoint) cascade to affecting the timeout values for the `web-secure` and `matrix-federation` entrypoints, so you can easily adjust all timeout values using them." msgstr "" -#: ../../../CHANGELOG.md:590 +#: ../../../CHANGELOG.md:1197 msgid "Example of the default timeout values used by the playbook:" msgstr "" -#: ../../../CHANGELOG.md:601 +#: ../../../CHANGELOG.md:1208 msgid "Alternatively, you may adjust the timeout values for specific entrypoints (like `web-secure` and `matrix-federation`) using dedicated variables (like `traefik_config_entrypoint_web_secure_transport_respondingTimeouts_readTimeout` and `matrix_playbook_public_matrix_federation_api_traefik_entrypoint_config_transport_respondingTimeouts_readTimeout`)." msgstr "" -#: ../../../CHANGELOG.md:604 +#: ../../../CHANGELOG.md:1211 msgid "2024-11-08" msgstr "" -#: ../../../CHANGELOG.md:606 +#: ../../../CHANGELOG.md:1213 msgid "Support for synapse-admin auto-configuration via /.well-known/matrix/client" msgstr "" -#: ../../../CHANGELOG.md:608 +#: ../../../CHANGELOG.md:1215 msgid "You can administrate your Synapse-powered homeserver using synapse-admin hosted externally (e.g. [admin.etke.cc](https://admin.etke.cc/)) and the synapse-admin instance would still auto-configure itself correctly for your server by [reading its `/.well-known/matrix/client` file](https://github.com/etkecc/synapse-admin/pull/126)." msgstr "" -#: ../../../CHANGELOG.md:610 +#: ../../../CHANGELOG.md:1217 msgid "The playbook now configures the `/.well-known/matrix/client` file for this by default, injecting into it a `cc.etke.synapse-admin` section that contains the full synapse-admin configuration. This is done even if you don't enable the synapse-admin service in your configuration. The reason for always doing it is to allow users to skip the (small) overhead of self-hosting the non-core synapse-admin service, yet still be able to use it from elsewhere when needed." msgstr "" -#: ../../../CHANGELOG.md:612 +#: ../../../CHANGELOG.md:1219 msgid "If you don't ever plan on using synapse-admin from other servers (besides your own due to [self-hosting synapse-admin](./docs/configuring-playbook-synapse-admin.md)), you **can disable this** `/.well-known/matrix/client` configuration via `matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin_enabled: false`" msgstr "" -#: ../../../CHANGELOG.md:615 +#: ../../../CHANGELOG.md:1222 msgid "2024-10-28" msgstr "" -#: ../../../CHANGELOG.md:617 +#: ../../../CHANGELOG.md:1224 msgid "(BC Break) Postmoogle's variable names need adjustments" msgstr "" -#: ../../../CHANGELOG.md:619 +#: ../../../CHANGELOG.md:1226 msgid "Due to the recategorization of [Postmoogle](./docs/configuring-playbook-bridge-postmoogle.md) from the bot to the bridge, its variables were renamed (`matrix_bot_postmoogle_` -> `matrix_postmoogle_`). You need to adjust your `vars.yml` configuration accordingly." msgstr "" -#: ../../../CHANGELOG.md:621 +#: ../../../CHANGELOG.md:1228 msgid "2024-10-19" msgstr "" -#: ../../../CHANGELOG.md:623 +#: ../../../CHANGELOG.md:1230 msgid "Support for Matrix Authentication Service" msgstr "" -#: ../../../CHANGELOG.md:625 +#: ../../../CHANGELOG.md:1232 msgid "The playbook now supports installing and configuring [Matrix Authentication Service](./docs/configuring-playbook-matrix-authentication-service.md) (MAS)." msgstr "" -#: ../../../CHANGELOG.md:627 +#: ../../../CHANGELOG.md:1234 msgid "Huge thanks to [Quentin Gliech](https://github.com/sandhose) from the [Element](https://element.io/) / [Matrix Authentication Service](https://github.com/element-hq/matrix-authentication-service) team for answering our numerous questions about MAS." msgstr "" -#: ../../../CHANGELOG.md:629 +#: ../../../CHANGELOG.md:1236 msgid "This is an **experimental service** and there are **still certain issues with it** (see [Expectations](./docs/configuring-playbook-matrix-authentication-service.md#expectations)). Matrix server administrators should only consider switching if they identify with one or more [reasons to use Matrix Authentication Service](./docs/configuring-playbook-matrix-authentication-service.md#reasons-to-use-matrix-authentication-service). As MAS adoption improves and more services are adjusted to support it, we expect that using MAS will become the norm." msgstr "" -#: ../../../CHANGELOG.md:631 +#: ../../../CHANGELOG.md:1238 msgid "Our [Setting up Matrix Authentication Service](./docs/configuring-playbook-matrix-authentication-service.md) documentation page has more details about this new service, what you might expect from the switch and how you can migrate your existing (Synapse) homeserver setup to MAS." msgstr "" -#: ../../../CHANGELOG.md:634 +#: ../../../CHANGELOG.md:1241 msgid "2024-09-27" msgstr "" -#: ../../../CHANGELOG.md:636 +#: ../../../CHANGELOG.md:1243 msgid "(BC Break) Postgres & Traefik roles have been relocated and variable names need adjustments" msgstr "" -#: ../../../CHANGELOG.md:638 +#: ../../../CHANGELOG.md:1245 msgid "Various roles have been relocated from the [devture](https://github.com/devture) organization to the [mother-of-all-self-hosting](https://github.com/mother-of-all-self-hosting) organization." msgstr "" -#: ../../../CHANGELOG.md:640 +#: ../../../CHANGELOG.md:1247 msgid "Along with the relocation, the `devture_` prefix was dropped from their variable names, so you need to adjust your `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:642 +#: ../../../CHANGELOG.md:1249 msgid "You need to do the following replacements:" msgstr "" -#: ../../../CHANGELOG.md:644 +#: ../../../CHANGELOG.md:1251 msgid "`devture_postgres_` -> `postgres_`" msgstr "" -#: ../../../CHANGELOG.md:645 +#: ../../../CHANGELOG.md:1252 msgid "`devture_traefik_` -> `traefik_`" msgstr "" -#: ../../../CHANGELOG.md:650 +#: ../../../CHANGELOG.md:1257 msgid "2024-09-12" msgstr "" -#: ../../../CHANGELOG.md:652 +#: ../../../CHANGELOG.md:1259 msgid "Support for baibot" msgstr "" -#: ../../../CHANGELOG.md:654 +#: ../../../CHANGELOG.md:1261 msgid "The playbook now supports installing [baibot](./docs/configuring-playbook-bot-baibot.md) (pronounced bye-bot) — a [Matrix](https://matrix.org/) bot developed by [etke.cc](https://etke.cc/) that exposes the power of [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) to you. 🤖" msgstr "" -#: ../../../CHANGELOG.md:656 +#: ../../../CHANGELOG.md:1263 msgid "It supports [OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/) models, as well as many other [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md)." msgstr "" -#: ../../../CHANGELOG.md:658 +#: ../../../CHANGELOG.md:1265 msgid "It's designed as a more private and [✨ featureful](https://github.com/etkecc/baibot/?tab=readme-ov-file#-features) alternative to the now-unmaintained [matrix-chatgpt-bot](./docs/configuring-playbook-bot-chatgpt.md)." msgstr "" -#: ../../../CHANGELOG.md:660 +#: ../../../CHANGELOG.md:1267 msgid "To get started, see the [Setting up baibot](./docs/configuring-playbook-bot-baibot.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:662 +#: ../../../CHANGELOG.md:1269 msgid "Switching synapse-admin to etke.cc's fork" msgstr "" -#: ../../../CHANGELOG.md:664 +#: ../../../CHANGELOG.md:1271 msgid "The playbook now installs [etke.cc](https://etke.cc/)'s [fork](https://github.com/etkecc/synapse-admin) of [synapse-admin](https://github.com/Awesome-Technologies/synapse-admin) (originally developed by [Awesome-Technologies](https://github.com/Awesome-Technologies)). This fork is a drop-in replacement for the original software." msgstr "" -#: ../../../CHANGELOG.md:666 +#: ../../../CHANGELOG.md:1273 msgid "The creation of the fork has been provoked by users frequently encountering issues with the original synapse-admin software, such as unintentionally deleting their one-and-only admin user account (fixed [here](https://github.com/etkecc/synapse-admin/pull/1) and also contributed upstream [here](https://github.com/Awesome-Technologies/synapse-admin/pull/608) — to no avail for now). Since its inception, [a bunch of other quality-of-life improvements](https://github.com/etkecc/synapse-admin?tab=readme-ov-file#changes) have been made to the fork." msgstr "" -#: ../../../CHANGELOG.md:668 +#: ../../../CHANGELOG.md:1275 msgid "If upstream synapse-admin picks up the pace and improves, the etke.cc fork may disappear and the playbook may switch to the original software again. Until that time comes, we believe that etke.cc's fork is the better software to use right now." msgstr "" -#: ../../../CHANGELOG.md:670 +#: ../../../CHANGELOG.md:1277 msgid "If you'd like to switch back to the original synapse-admin software, you can do so by adding the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:683 +#: ../../../CHANGELOG.md:1290 msgid "2024-08-17" msgstr "" -#: ../../../CHANGELOG.md:685 +#: ../../../CHANGELOG.md:1292 msgid "New appservice-double-puppet service for better double-puppeting" msgstr "" -#: ../../../CHANGELOG.md:687 +#: ../../../CHANGELOG.md:1294 msgid "Mautrix bridges are undergoing large changes as announced in the [August 2024 releases & progress](https://mau.fi/blog/2024-08-mautrix-release/) blog post." msgstr "" -#: ../../../CHANGELOG.md:689 +#: ../../../CHANGELOG.md:1296 msgid "The playbook has already upgraded to the rewritten mautrix-slack ([v0.1.0](https://github.com/mautrix/slack/releases/tag/v0.1.0)) and mautrix-signal ([v0.7.0](https://github.com/mautrix/signal/releases/tag/v0.7.0)) bridges." msgstr "" -#: ../../../CHANGELOG.md:691 +#: ../../../CHANGELOG.md:1298 msgid "The newly rewritten bridges do not support double-puppeting via [Shared Secret Auth](./docs/configuring-playbook-shared-secret-auth.md) anymore, which has prompted us to switch to the new & better [appservice method](https://docs.mau.fi/bridges/general/double-puppeting.html#appservice-method-new) for double-puppeting. The playbook automates this double-puppeting setup for you if you enable the new [Appservice Double Puppet](./docs/configuring-playbook-appservice-double-puppet.md) service." msgstr "" -#: ../../../CHANGELOG.md:693 +#: ../../../CHANGELOG.md:1300 msgid "All non-deprecated mautrix bridges in the playbook have been reworked to support double-puppeting via an Appservice. Most bridges still support double-puppeting via [Shared Secret Auth](./docs/configuring-playbook-shared-secret-auth.md), so the playbook supports it too. If only Shared Secret Auth is enabled, double-puppeting will be configured using that method (for the bridges that support it). That said, **Shared Secret Auth double-puppeting is being phased out and we recommend replacing it with the new Appservice method**." msgstr "" -#: ../../../CHANGELOG.md:695 +#: ../../../CHANGELOG.md:1302 msgid "We recommend **enabling double-puppeting via the new Appservice method** by adding the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:701 +#: ../../../CHANGELOG.md:1308 msgid "You can still **keep** [Shared Secret Auth](./docs/configuring-playbook-shared-secret-auth.md) enabled. Non-mautrix bridges and other services (e.g. [matrix-corporal](./docs/configuring-playbook-matrix-corporal.md)) may still require it." msgstr "" -#: ../../../CHANGELOG.md:703 +#: ../../../CHANGELOG.md:1310 msgid "When both double-puppeting methods are enabled, the playbook will automatically choose the new and better Appservice method for bridges that support it." msgstr "" -#: ../../../CHANGELOG.md:706 +#: ../../../CHANGELOG.md:1313 msgid "2024-08-15" msgstr "" -#: ../../../CHANGELOG.md:708 +#: ../../../CHANGELOG.md:1315 msgid "matrix-media-repo now configured for Authenticated Media" msgstr "" -#: ../../../CHANGELOG.md:710 +#: ../../../CHANGELOG.md:1317 msgid "Thanks to [Michael Hollister](https://github.com/Michael-Hollister) from [FUTO](https://www.futo.org/), our matrix-media-repo implementation now automatically [sets up signing keys](https://docs.t2bot.io/matrix-media-repo/v1.3.5/installation/signing-key/) for Authenticated Media (as per [MSC3916](https://github.com/matrix-org/matrix-spec-proposals/pull/3916))." msgstr "" -#: ../../../CHANGELOG.md:712 +#: ../../../CHANGELOG.md:1319 msgid "If you had never heard of Authenticated Media before, the [Sunsetting unauthenticated media](https://matrix.org/blog/2024/06/26/sunsetting-unauthenticated-media/) article on [matrix.org](https://matrix.org/) is a good introduction." msgstr "" -#: ../../../CHANGELOG.md:714 +#: ../../../CHANGELOG.md:1321 msgid "This feature is enabled for matrix-media-repo installations by default and will append an additional (matrix-media-repo-generated signing key) to your homeserver's (Synapse or Dendrite) signing key. See the [Signing keys](./docs/configuring-playbook-matrix-media-repo.md#signing-keys) and [Key backup and revoking](./docs/configuring-playbook-matrix-media-repo.md#key-backup-and-revoking) sections of the matrix-media-repo documentation for more details." msgstr "" -#: ../../../CHANGELOG.md:716 +#: ../../../CHANGELOG.md:1323 msgid "If you'd like to avoid this new feature, you can disable it by setting `matrix_media_repo_generate_signing_key: false` in your `vars.yml` configuration file." msgstr "" -#: ../../../CHANGELOG.md:719 +#: ../../../CHANGELOG.md:1326 msgid "2024-08-08" msgstr "" -#: ../../../CHANGELOG.md:721 +#: ../../../CHANGELOG.md:1328 msgid "(Backward Compatibility Break) matrix-corporal has been upgraded to v3" msgstr "" -#: ../../../CHANGELOG.md:723 +#: ../../../CHANGELOG.md:1330 msgid "The playbook now installs [matrix-corporal](https://github.com/devture/matrix-corporal) v3.0.0, which brings support for **power-level management** (thanks to [this PR](https://github.com/devture/matrix-corporal/pull/32))." msgstr "" -#: ../../../CHANGELOG.md:725 +#: ../../../CHANGELOG.md:1332 msgid "This upgrade necessitates configuration policy changes as described in [matrix-corporal's changelog entry](https://github.com/devture/matrix-corporal/blob/5287cb81c82cd3b951c2a099b4697c3e0b384559/CHANGELOG.md#version-300-2024-08-08)." msgstr "" -#: ../../../CHANGELOG.md:727 +#: ../../../CHANGELOG.md:1334 msgid "If you'd like to remain on the old (v2) version of matrix-corporal, you can do so by adding the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:733 +#: ../../../CHANGELOG.md:1340 msgid "2024-07-25" msgstr "" -#: ../../../CHANGELOG.md:735 +#: ../../../CHANGELOG.md:1342 msgid "synapse-usage-exporter support" msgstr "" -#: ../../../CHANGELOG.md:737 +#: ../../../CHANGELOG.md:1344 msgid "Thanks to [Michael Hollister](https://github.com/Michael-Hollister) from [FUTO](https://www.futo.org/), the creators of the [Circles app](https://circu.li/), the playbook can now set up [synapse-usage-exporter](https://github.com/loelkes/synapse-usage-exporter) — a small [Flask](https://flask.palletsprojects.com)-based webservice which can capture usage statistics from Synapse (via HTTP `PUT`) and then make them available for Prometheus to scrape." msgstr "" -#: ../../../CHANGELOG.md:739 +#: ../../../CHANGELOG.md:1346 msgid "To learn more see our [Enabling synapse-usage-exporter for Synapse usage statistics](docs/configuring-playbook-synapse-usage-exporter.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:742 +#: ../../../CHANGELOG.md:1349 msgid "2024-07-06" msgstr "" -#: ../../../CHANGELOG.md:744 +#: ../../../CHANGELOG.md:1351 msgid "matrix-alertmanager-receiver support" msgstr "" -#: ../../../CHANGELOG.md:746 +#: ../../../CHANGELOG.md:1353 msgid "For those wishing to more easily integrate [Prometheus](https://prometheus.io/)' alerting service ([Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/)) with Matrix, the playbook can now set up [matrix-alertmanager-receiver](https://github.com/metio/matrix-alertmanager-receiver)." msgstr "" -#: ../../../CHANGELOG.md:748 +#: ../../../CHANGELOG.md:1355 msgid "See [Setting up Prometheus Alertmanager integration via matrix-alertmanager-receiver](./docs/configuring-playbook-alertmanager-receiver.md) for more details." msgstr "" -#: ../../../CHANGELOG.md:750 +#: ../../../CHANGELOG.md:1357 msgid "Traefik v3 and HTTP/3 are here now" msgstr "" -#: ../../../CHANGELOG.md:752 +#: ../../../CHANGELOG.md:1359 msgid "**TLDR**: Traefik was migrated from v2 to v3. Minor changes were done to the playbook. Mostly everything else worked out of the box. Most people will not have to do any tweaks to their configuration. In addition, [HTTP/3](https://en.wikipedia.org/wiki/HTTP/3) support is now auto-enabled for the `web-secure` (port 443) and `matrix-federation` (port `8448`) entrypoints. If you have a firewall in front of your server and you wish to benefit from `HTTP3`, you will need to open the `443` and `8448` UDP ports in it." msgstr "" -#: ../../../CHANGELOG.md:754 +#: ../../../CHANGELOG.md:1361 msgid "Traefik v3" msgstr "" -#: ../../../CHANGELOG.md:756 +#: ../../../CHANGELOG.md:1363 msgid "The reverse-proxy that the playbook uses by default (Traefik) has recently been upgraded to v3 (see [this blog post](https://traefik.io/blog/announcing-traefik-proxy-v3-rc/) to learn about its new features). Version 3 includes some small breaking configuration changes requiring a [migration](https://doc.traefik.io/traefik/migration/v2-to-v3/)." msgstr "" -#: ../../../CHANGELOG.md:758 +#: ../../../CHANGELOG.md:1365 msgid "We have **updated the playbook to Traefik v3** (make sure to run `just roles` / `make roles` to get it)." msgstr "" -#: ../../../CHANGELOG.md:760 +#: ../../../CHANGELOG.md:1367 msgid "There were **only minor playbook changes required** to adapt to Traefik v3, and only to the Ansible role for [matrix-media-repo](./docs/configuring-playbook-matrix-media-repo.md) where we changed a few [`PathPrefix` instances to `PathRegexp`](https://doc.traefik.io/traefik/routing/routers/#path-pathprefix-and-pathregexp), because these instances were using a regular expression instead of a fixed path. For fixed-path values, `PathPrefix` is still the preferred matcher function to use." msgstr "" -#: ../../../CHANGELOG.md:762 +#: ../../../CHANGELOG.md:1369 msgid "**Most people using the playbook should not have to do any changes**." msgstr "" -#: ../../../CHANGELOG.md:764 +#: ../../../CHANGELOG.md:1371 msgid "If you're using the playbook's Traefik instance to reverse-proxy to some other services of your own (not managed by the playbook), you may wish to review their Traefik labels and make sure they're in line with the [Traefik v2 to v3 migration guide](https://doc.traefik.io/traefik/migration/v2-to-v3/)." msgstr "" -#: ../../../CHANGELOG.md:766 +#: ../../../CHANGELOG.md:1373 msgid "If you've tweaked any of this playbook's `_path_prefix` variables and made them use a regular expression, you will now need to make additional adjustments. The playbook makes extensive use of `PathPrefix()` matchers in Traefik rules and `PathPrefix` does not support regular expressions anymore. To work around it, you may now need to override a whole `_traefik_rule` variable and switch it from [`PathPrefix` to `PathRegexp`](https://doc.traefik.io/traefik/routing/routers/#path-pathprefix-and-pathregexp)." msgstr "" -#: ../../../CHANGELOG.md:768 +#: ../../../CHANGELOG.md:1375 msgid "If you're not using [matrix-media-repo](./docs/configuring-playbook-matrix-media-repo.md) (the only role we had to tweak to adapt it to Traefik v3), you **may potentially downgrade to Traefik v2** (if necessary) by adding `traefik_verison: v2.11.4` to your configuration. People using `matrix-media-repo` cannot downgrade this way, because `matrix-media-repo` has been adjusted to use `PathRegexp` — a [routing matcher](https://doc.traefik.io/traefik/v2.11/routing/routers/#rule) that Traefik v2 does not understand." msgstr "" -#: ../../../CHANGELOG.md:770 +#: ../../../CHANGELOG.md:1377 msgid "HTTP/3 is enabled by default" msgstr "" -#: ../../../CHANGELOG.md:772 +#: ../../../CHANGELOG.md:1379 msgid "In Traefik v3, [HTTP/3](https://en.wikipedia.org/wiki/HTTP/3) support is no longer considered experimental now. Due to this, **the playbook auto-enables HTTP3** for the `web-secure` (port 443) and `matrix-federation` (port `8448`) entrypoints." msgstr "" -#: ../../../CHANGELOG.md:774 +#: ../../../CHANGELOG.md:1381 msgid "HTTP3 uses the UDP protocol and **the playbook (together with Docker) will make sure that the appropriate ports** (`443` over UDP & `8448` over UDP) **are exposed and whitelisted in your server's firewall**. However, **if you have another firewall in front of your server** (as is the case for many cloud providers), **you will need to manually open these UDP ports**." msgstr "" -#: ../../../CHANGELOG.md:776 +#: ../../../CHANGELOG.md:1383 msgid "If you do not open the UDP ports correctly or there is some other issue, clients (browsers, mostly) will fall-back to [HTTP/2](https://en.wikipedia.org/wiki/HTTP/2) or even [HTTP/1.1](https://en.wikipedia.org/wiki/HTTP)." msgstr "" -#: ../../../CHANGELOG.md:778 +#: ../../../CHANGELOG.md:1385 msgid "Still, if HTTP/3 cannot function correctly in your setup, it's best to disable advertising support for it (and misleading clients into trying to use HTTP/3)." msgstr "" -#: ../../../CHANGELOG.md:780 +#: ../../../CHANGELOG.md:1387 msgid "To **disable HTTP/3**, you can use the following configuration:" msgstr "" -#: ../../../CHANGELOG.md:794 +#: ../../../CHANGELOG.md:1401 msgid "If you are using [your own webserver](./docs/configuring-playbook-own-webserver.md) (in front of Traefik), port binding on UDP port `8448` by default due to HTTP/3 is either unnecessary or [may get in the way](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3402). If it does, you can disable it:" msgstr "" -#: ../../../CHANGELOG.md:807 +#: ../../../CHANGELOG.md:1414 msgid "2024-07-01" msgstr "" -#: ../../../CHANGELOG.md:809 +#: ../../../CHANGELOG.md:1416 msgid "synapse-admin is now restricted to your homeserver's URL by default" msgstr "" -#: ../../../CHANGELOG.md:811 +#: ../../../CHANGELOG.md:1418 msgid "A new feature introduced in synapse-admin [v0.10.0](https://github.com/Awesome-Technologies/synapse-admin/releases/tag/0.10.0) (released and supported by the playbook since a a few months ago) provides the ability to [restrict its usage to a specific homeserver](https://github.com/Awesome-Technologies/synapse-admin/blob/e21e44362c879ac41f47c580b04210842b6ff3d7/README.md#restricting-available-homeserver) (or multiple homeservers)." msgstr "" -#: ../../../CHANGELOG.md:813 +#: ../../../CHANGELOG.md:1420 msgid "The playbook has just started making use of this feature. **From now on, your synapse-admin instance will be restricted to the homeserver you're managing via the playbook**. When configured like this, the *Homeserver URL* field in synapse-admin's web UI changes from a text field to a dropdown having a single value (the URL of your homeserver). This makes usage simpler for most people, as they won't need to manually enter a *Homeserver URL* anymore." msgstr "" -#: ../../../CHANGELOG.md:815 +#: ../../../CHANGELOG.md:1422 msgid "If you'd like **to go back to the old unrestricted behavior**, use the following configuration:" msgstr "" -#: ../../../CHANGELOG.md:823 +#: ../../../CHANGELOG.md:1430 msgid "2024-06-25" msgstr "" -#: ../../../CHANGELOG.md:825 +#: ../../../CHANGELOG.md:1432 msgid "The URL-prefix for Hookshot generic webhooks has changed" msgstr "" -#: ../../../CHANGELOG.md:827 +#: ../../../CHANGELOG.md:1434 msgid "Until now, generic Hookshot webhook URLs looked like this: `https://matrix.example.com/hookshot/webhooks/:hookId`." msgstr "" -#: ../../../CHANGELOG.md:829 +#: ../../../CHANGELOG.md:1436 msgid "The `/hookshot/webhooks` common prefix gets stripped by Traefik automatically, so Hookshot only sees the part that comes after (`/:hookId`)." msgstr "" -#: ../../../CHANGELOG.md:831 +#: ../../../CHANGELOG.md:1438 msgid "[A few years ago](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1681), Hookshot started to prefer to handle webhooks at a `/webhook/:hookId` path (instead of directly at `/:hookId`)." msgstr "" -#: ../../../CHANGELOG.md:833 +#: ../../../CHANGELOG.md:1440 msgid "To avoid future problems, we've [reconfigured](https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/4704a60718946fd469aeee7fc3ae8127c633bb6b) our Hookshot configuration to use webhook URLs that include `/webhook` in the URL suffix (e.g. `/hookshot/webhooks/webhook/:hookId`, instead of `/hookshot/webhooks/:hookId`). This means that when we strip the common prefi (`/hookshot/webhooks`), we'll end up sending `/webhook/:hookId` to Hookshot, just like recommended." msgstr "" -#: ../../../CHANGELOG.md:835 +#: ../../../CHANGELOG.md:1442 msgid "When generating new webhooks, you should start seeing the new URLs being used." msgstr "" -#: ../../../CHANGELOG.md:837 +#: ../../../CHANGELOG.md:1444 msgid "**For now**, **both** old URLs (`/hookshot/webhooks/:hookId`) and new URLs (`/hookshot/webhooks/webhook/:hookId`) **continue to work**, so your webhooks will not break just yet." msgstr "" -#: ../../../CHANGELOG.md:839 +#: ../../../CHANGELOG.md:1446 msgid "However, **we recommend that you update all your old webhook URLs** (configured in other systems) to include the new `/webhook` path component, so that future Hookshot changes (whenever they come) will not break your webhooks. You don't need to do anything on the Hookshot side — you merely need to reconfigure the remote systems that use your webhook URLs." msgstr "" -#: ../../../CHANGELOG.md:842 +#: ../../../CHANGELOG.md:1449 msgid "2024-06-22" msgstr "" -#: ../../../CHANGELOG.md:844 +#: ../../../CHANGELOG.md:1451 msgid "The maubot user is now managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:846 +#: ../../../CHANGELOG.md:1453 msgid "To make things easier and to be consistent with other roles, the [maubot](./docs/configuring-playbook-bot-maubot.md) user (`bot.maubot` by default) is [now](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3376) automatically created be the playbook." msgstr "" -#: ../../../CHANGELOG.md:848 +#: ../../../CHANGELOG.md:1455 msgid "If you have an existing maubot installation, you will need to specify `matrix_bot_maubot_initial_password` in your `vars.yml` file to make the playbook not complain about it being undefined. Since the bot is already registered in your installation, there's nothing for the playbook to do anyway. In case you don't remember the password you've registered your maubot user account with, you can specify any value for this variable." msgstr "" -#: ../../../CHANGELOG.md:850 +#: ../../../CHANGELOG.md:1457 msgid "If you've registered another username for the bot (other than the recommended default of `bot.maubot`), consider adjusting the `matrix_bot_maubot_login` variable (e.g. `matrix_bot_maubot_login: my.maubot.username`)." msgstr "" -#: ../../../CHANGELOG.md:853 +#: ../../../CHANGELOG.md:1460 msgid "2024-06-03" msgstr "" -#: ../../../CHANGELOG.md:855 +#: ../../../CHANGELOG.md:1462 msgid "WeChat bridging support" msgstr "" -#: ../../../CHANGELOG.md:857 +#: ../../../CHANGELOG.md:1464 msgid "Thanks to [Tobias Diez](https://github.com/tobiasdiez)'s [efforts](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3241), the playbook now supports bridging to [WeChat](https://www.wechat.com/) via the [matrix-wechat](https://github.com/duo/matrix-wechat) bridge." msgstr "" -#: ../../../CHANGELOG.md:859 +#: ../../../CHANGELOG.md:1466 msgid "See our [Setting up WeChat bridging](docs/configuring-playbook-bridge-wechat.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:862 +#: ../../../CHANGELOG.md:1469 msgid "2024-03-26" msgstr "" -#: ../../../CHANGELOG.md:864 +#: ../../../CHANGELOG.md:1471 msgid "(Backward Compatibility Break) The playbook now defaults to KeyDB, instead of Redis" msgstr "" -#: ../../../CHANGELOG.md:866 +#: ../../../CHANGELOG.md:1473 msgid "**TLDR**: if the playbook used installed Redis as a dependency for you before, it will now replace it with [KeyDB](https://docs.keydb.dev/) (a drop-in alternative) due to [Redis having changed its license](https://redis.com/blog/redis-adopts-dual-source-available-licensing/)." msgstr "" -#: ../../../CHANGELOG.md:868 +#: ../../../CHANGELOG.md:1475 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook now uses [KeyDB](https://docs.keydb.dev/) (a drop-in alternative for Redis), instead of [Redis](https://redis.io/)." msgstr "" -#: ../../../CHANGELOG.md:870 +#: ../../../CHANGELOG.md:1477 msgid "The playbook used to install Redis (and now installs KeyDB in its place) if services have a need for it ([enabling worker support for Synapse](docs/configuring-playbook-synapse.md#load-balancing-with-workers), [enabling Hookshot encryption](docs/configuring-playbook-bridge-hookshot.md#end-to-bridge-encryption), etc.) or if you explicitly enabled the service (`redis_enabled: true` or `keydb_enabled: true`)." msgstr "" -#: ../../../CHANGELOG.md:872 +#: ../../../CHANGELOG.md:1479 msgid "This change is provoked by the fact that [Redis is now \"source available\"](https://redis.com/blog/redis-adopts-dual-source-available-licensing/). According to the Limitations of [the new license](https://redis.com/legal/rsalv2-agreement/) (as best as we understand them, given that we're not lawyers), using Redis in the playbook (even in a commercial FOSS service like [etke.cc](https://etke.cc/)) does not violate the new Redis license. That said, we'd rather neither risk it, nor endorse shady licenses and products that pretend to be free-software. Another high-quality alternative to Redis seems to be [Dragonfly](https://www.dragonflydb.io/), but the [Dragonfly license](https://github.com/dragonflydb/dragonfly?tab=License-1-ov-file#readme) is no better than Redis's." msgstr "" -#: ../../../CHANGELOG.md:874 +#: ../../../CHANGELOG.md:1481 msgid "Next time your run the playbook (via the `setup-all` tag), **Redis will be automatically uninstalled and replaced with KeyDB**. Some Synapse downtime may occur while the switch happens." msgstr "" -#: ../../../CHANGELOG.md:876 +#: ../../../CHANGELOG.md:1483 msgid "Users on `arm32` should be aware that there's **neither a prebuilt `arm32` container image for KeyDB**, nor the KeyDB role supports self-building yet. Users on this architecture likely don't run Synapse with workers, etc., so they're likely in no need of KeyDB (or Redis). If Redis is necessary in an `arm32` deployment, disabling KeyDB and making the playbook fall back to Redis is possible (see below)." msgstr "" -#: ../../../CHANGELOG.md:887 +#: ../../../CHANGELOG.md:1494 msgid "2024-03-24" msgstr "" -#: ../../../CHANGELOG.md:889 +#: ../../../CHANGELOG.md:1496 msgid "Initial work on IPv6 support" msgstr "" -#: ../../../CHANGELOG.md:891 +#: ../../../CHANGELOG.md:1498 msgid "Thanks to [Tilo Spannagel](https://github.com/tilosp), the playbook can now enable IPv6 for container networks for various components (roles) via [the `devture_systemd_docker_base_ipv6_enabled` variable](https://github.com/devture/com.devture.ansible.role.systemd_docker_base/blob/c11a526bb8e318b42eb52055056377bb31154f13/defaults/main.yml#L14-L31)." msgstr "" -#: ../../../CHANGELOG.md:893 +#: ../../../CHANGELOG.md:1500 msgid "It should be noted that:" msgstr "" -#: ../../../CHANGELOG.md:895 +#: ../../../CHANGELOG.md:1502 msgid "Matrix roles (`roles/custom/matrix-*`) respect this variable, but external roles (those defined in `requirements.yml` and installed via `just roles`) do not respect it yet. Additional work is necessary" msgstr "" -#: ../../../CHANGELOG.md:896 +#: ../../../CHANGELOG.md:1503 msgid "changing the variable subsequently may not change existing container networks. Refer to [these instructions](https://github.com/devture/com.devture.ansible.role.systemd_docker_base/blob/c11a526bb8e318b42eb52055056377bb31154f13/defaults/main.yml#L26-L30)" msgstr "" -#: ../../../CHANGELOG.md:897 +#: ../../../CHANGELOG.md:1504 msgid "this is all very new and untested" msgstr "" -#: ../../../CHANGELOG.md:899 +#: ../../../CHANGELOG.md:1506 msgid "Pantalaimon support" msgstr "" -#: ../../../CHANGELOG.md:901 +#: ../../../CHANGELOG.md:1508 msgid "Thanks to [Julian Foad](https://matrix.to/#/@julian:foad.me.uk), the playbook can now install the [Pantalaimon](https://github.com/matrix-org/pantalaimon) E2EE aware proxy daemon for you. It's already possible to integrate it with [Draupnir](docs/configuring-playbook-bot-draupnir.md) to allow it to work in E2EE rooms — see our Draupnir docs for details." msgstr "" -#: ../../../CHANGELOG.md:903 +#: ../../../CHANGELOG.md:1510 msgid "See our [Setting up Pantalaimon](docs/configuring-playbook-pantalaimon.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:906 +#: ../../../CHANGELOG.md:1513 msgid "2024-03-05" msgstr "" -#: ../../../CHANGELOG.md:908 +#: ../../../CHANGELOG.md:1515 msgid "Support for Draupnir-for-all" msgstr "" -#: ../../../CHANGELOG.md:910 +#: ../../../CHANGELOG.md:1517 msgid "Thanks to [FSG-Cat](https://github.com/FSG-Cat), the playbook can now install [Draupnir for all](./docs/configuring-playbook-appservice-draupnir-for-all.md) (aka multi-instance Draupnir running in appservice mode)." msgstr "" -#: ../../../CHANGELOG.md:912 +#: ../../../CHANGELOG.md:1519 msgid "This is an alternative to [running Draupnir in bot mode](./docs/configuring-playbook-bot-draupnir.md), which is still supported by the playbook." msgstr "" -#: ../../../CHANGELOG.md:914 +#: ../../../CHANGELOG.md:1521 msgid "The documentation page for [Draupnir for all](./docs/configuring-playbook-appservice-draupnir-for-all.md) contains more information on how to install it." msgstr "" -#: ../../../CHANGELOG.md:917 +#: ../../../CHANGELOG.md:1524 msgid "2024-02-19" msgstr "" -#: ../../../CHANGELOG.md:919 +#: ../../../CHANGELOG.md:1526 msgid "Support for bridging to Facebook/Messenger via the new mautrix-meta bridge" msgstr "" -#: ../../../CHANGELOG.md:921 +#: ../../../CHANGELOG.md:1528 msgid "The [mautrix-facebook](./docs/configuring-playbook-bridge-mautrix-facebook.md) and [mautrix-instagram](./docs/configuring-playbook-bridge-mautrix-instagram.md) bridges are being [superseded by a new bridge](https://github.com/mautrix/facebook/issues/332) — the [mautrix-meta](https://github.com/mautrix/meta) bridge." msgstr "" -#: ../../../CHANGELOG.md:923 +#: ../../../CHANGELOG.md:1530 msgid "The playbook now supports the new mautrix-meta bridge — a single bridge, which can run in different modes and bridge to Messenger (via [Facebook](https://facebook.com/), Facebook over [Tor](https://www.torproject.org/) or via [Messenger](https://messenger.com/)) and [Instagram](https://instagram.com/). The playbook makes this bridge available via 2 separate Ansible roles, allowing you to easily run 2 instances of mautrix-meta, for bridging to both services at the same time." msgstr "" -#: ../../../CHANGELOG.md:925 +#: ../../../CHANGELOG.md:1532 msgid "If you're using mautrix-facebook or mautrix-instagram right now, **you can still continue using the old bridges, but may wish to change to the new bridge implementations**. See:" msgstr "" -#: ../../../CHANGELOG.md:927 +#: ../../../CHANGELOG.md:1534 msgid "[Setting up Instagram bridging via Mautrix Meta](docs/configuring-playbook-bridge-mautrix-meta-instagram.md)" msgstr "" -#: ../../../CHANGELOG.md:929 +#: ../../../CHANGELOG.md:1536 msgid "[Setting up Messenger bridging via Mautrix Meta](docs/configuring-playbook-bridge-mautrix-meta-messenger.md)" msgstr "" -#: ../../../CHANGELOG.md:931 +#: ../../../CHANGELOG.md:1538 msgid "The documentation pages contain more information on how to migrate." msgstr "" -#: ../../../CHANGELOG.md:934 +#: ../../../CHANGELOG.md:1541 msgid "2024-02-14" msgstr "" -#: ../../../CHANGELOG.md:936 +#: ../../../CHANGELOG.md:1543 msgid "Much larger Synapse caches and cache auto-tuning enabled by default" msgstr "" -#: ../../../CHANGELOG.md:938 +#: ../../../CHANGELOG.md:1545 msgid "Thanks to [FSG-Cat](https://github.com/FSG-Cat), the playbook now uses much larger caches and enables Synapse's [cache auto-tuning functionality](https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#caches-and-associated-values). This work and the default values used by the playbook are inspired by [Tom Foster](https://github.com/tcpipuk)'s [Synapse homeserver guide](https://tcpipuk.github.io/synapse/deployment/synapse.html)." msgstr "" -#: ../../../CHANGELOG.md:940 +#: ../../../CHANGELOG.md:1547 msgid "The playbook has always used a very conservative cache factor (`matrix_synapse_caches_global_factor`) value of `0.5`, which may be OK for small and underactive deployments, but is not ideal for larger servers. Paradoxically, a small global cache factor value [does not necessarily decrease RAM usage as a whole](https://github.com/matrix-org/synapse/issues/3939)." msgstr "" -#: ../../../CHANGELOG.md:942 +#: ../../../CHANGELOG.md:1549 msgid "The playbook now uses **a 20x larger cache factor** (currently `10`), adjusts a few other cache-related variables, and **enables cache auto-tuning** via the following variables:" msgstr "" -#: ../../../CHANGELOG.md:944 +#: ../../../CHANGELOG.md:1551 msgid "`matrix_synapse_cache_autotuning_max_cache_memory_usage` — defaults to 1/8 of total RAM with a cap of 2GB; values are specified in bytes" msgstr "" -#: ../../../CHANGELOG.md:945 +#: ../../../CHANGELOG.md:1552 msgid "`matrix_synapse_cache_autotuning_target_cache_memory_usage` — defaults to 1/16 of total RAM with a cap of 1GB; values are specified in bytes" msgstr "" -#: ../../../CHANGELOG.md:946 +#: ../../../CHANGELOG.md:1553 msgid "`matrix_synapse_cache_autotuning_min_cache_ttl` — defaults to `30s`" msgstr "" -#: ../../../CHANGELOG.md:948 +#: ../../../CHANGELOG.md:1555 msgid "These values should be good defaults for most servers, but may change over time as we experiment further." msgstr "" -#: ../../../CHANGELOG.md:950 +#: ../../../CHANGELOG.md:1557 msgid "Refer to our new [Tuning caches and cache autotuning](docs/maintenance-synapse.md#tuning-caches-and-cache-autotuning) documentation section for more details." msgstr "" -#: ../../../CHANGELOG.md:953 +#: ../../../CHANGELOG.md:1560 msgid "2024-01-31" msgstr "" -#: ../../../CHANGELOG.md:955 +#: ../../../CHANGELOG.md:1562 msgid "(Backward-compatibility break) Minor changes necessary for some people serving a static website at the base domain" msgstr "" -#: ../../../CHANGELOG.md:957 +#: ../../../CHANGELOG.md:1564 msgid "This only affects people who are [Serving a static website at the base domain](./docs/configuring-playbook-base-domain-serving.md#serving-a-static-website-at-the-base-domain), but not managing its `index.html` through the playbook." msgstr "" -#: ../../../CHANGELOG.md:959 +#: ../../../CHANGELOG.md:1566 msgid "That is, for people who have `matrix_static_files_file_index_html_enabled: false` in their `vars.yml` configuration, the playbook has a new default behavior. Since the playbook is not managing the `index.html` file, it will default to a more sensible way of handling the base domain — redirecting `https://example.com/` to `https://matrix.example.com/`, instead of serving a 404 page." msgstr "" -#: ../../../CHANGELOG.md:961 +#: ../../../CHANGELOG.md:1568 msgid "If you are managing your static website by yourself (by dropping files into `/matrix/static-files/public` somehow), then you probably don't wish for such redirection to happen. You can disable it by adding `matrix_static_files_container_labels_base_domain_root_path_redirection_enabled: false` to your `vars.yml` configuration file." msgstr "" -#: ../../../CHANGELOG.md:964 +#: ../../../CHANGELOG.md:1571 msgid "2024-01-20" msgstr "" -#: ../../../CHANGELOG.md:966 +#: ../../../CHANGELOG.md:1573 msgid "Support for more efficient (specialized) Synapse workers" msgstr "" -#: ../../../CHANGELOG.md:968 +#: ../../../CHANGELOG.md:1575 msgid "Thanks to [Charles Wright](https://github.com/cvwright) from [FUTO](https://www.futo.org/), the creators of the [Circles app](https://circu.li/), the playbook has [received support](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3100) for load-balancing the Synapse workload via [specialized workers](./docs/configuring-playbook-synapse.md#specialized-workers) which are supposed to work better than our old [generic workers](./docs/configuring-playbook-synapse.md#generic-workers) implementation." msgstr "" -#: ../../../CHANGELOG.md:970 +#: ../../../CHANGELOG.md:1577 msgid "For now, playbook defaults remain unchanged and the `one-of-each` [workers preset](./docs/configuring-playbook-synapse.md#worker-presets) continues being the default. However, the default may change in the future. If you'd like to remain on this preset even if/when the defaults change, consider explicitly adding `matrix_synapse_workers_preset: one-of-each` to your `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:972 +#: ../../../CHANGELOG.md:1579 msgid "Our specialized workers setup is based on recommendations found in [Tom Foster](https://github.com/tcpipuk)'s [Synapse homeserver guide](https://tcpipuk.github.io/synapse/index.html). What's special about our new setup is that we try to parse information out of the request (who the user is; which room is being operated on) and try to forward similar requests to the same worker. As an example, this means that once a worker caches some room information, subsequent requests for the same room will be routed to the same worker (which supposedly still has the room's state cached)." msgstr "" -#: ../../../CHANGELOG.md:974 +#: ../../../CHANGELOG.md:1581 msgid "To get started, refer to our [Specialized workers](./docs/configuring-playbook-synapse.md#specialized-workers) documentation section." msgstr "" -#: ../../../CHANGELOG.md:977 +#: ../../../CHANGELOG.md:1584 msgid "2024-01-17" msgstr "" -#: ../../../CHANGELOG.md:979 +#: ../../../CHANGELOG.md:1586 msgid "Switching to Element's AGPLv3-licensed Synapse release" msgstr "" -#: ../../../CHANGELOG.md:981 +#: ../../../CHANGELOG.md:1588 msgid "A few months ago, the [Element](https://element.io/) company has [announced](https://element.io/blog/element-to-adopt-agplv3/) that their work on the Synapse homeserver would no longer be available under the permissive [Apache-2.0 license](https://www.apache.org/licenses/LICENSE-2.0), but only under:" msgstr "" -#: ../../../CHANGELOG.md:983 +#: ../../../CHANGELOG.md:1590 msgid "the [AGPLv3](https://www.gnu.org/licenses/agpl-3.0.en.html) free-software license — the same license that this Ansible playbook has always used" msgstr "" -#: ../../../CHANGELOG.md:984 +#: ../../../CHANGELOG.md:1591 msgid "a proprietary license, for those wishing for Element to [sell them an exception](https://gnu.org/philosophy/selling-exceptions.html) to the AGPLv3 license" msgstr "" -#: ../../../CHANGELOG.md:986 +#: ../../../CHANGELOG.md:1593 msgid "You can also learn more in [this post](https://matrix.org/blog/2023/11/06/future-of-synapse-dendrite/) by the Matrix Foundation." msgstr "" -#: ../../../CHANGELOG.md:988 +#: ../../../CHANGELOG.md:1595 msgid "The change has [already happened](https://element.io/blog/synapse-now-lives-at-github-com-element-hq-synapse/) and the first Synapse release under the new license is here: [v1.99.0](https://github.com/element-hq/synapse/releases/tag/v1.99.0)." msgstr "" -#: ../../../CHANGELOG.md:990 +#: ../../../CHANGELOG.md:1597 msgid "There is no up-to-date alternative Synapse fork right now and this free-software (AGPLv3-licensed) playbook is definitely not against free-software licenses, so we are now switching to the Element-maintained Synapse release." msgstr "" -#: ../../../CHANGELOG.md:992 +#: ../../../CHANGELOG.md:1599 msgid "**What does this mean to you?**" msgstr "" -#: ../../../CHANGELOG.md:994 +#: ../../../CHANGELOG.md:1601 msgid "For most home users, it doesn't mean anything. Your installation will continue working as it should and you don't need to do anything." msgstr "" -#: ../../../CHANGELOG.md:996 +#: ../../../CHANGELOG.md:1603 msgid "For people building commercial products on top of Synapse, they may have to either buy a license exception from Element (from what we hear, the fee depends on the number of monthly-active users on your instance) or they may need to release all related code as free-software (which is what we've been doing at [etke.cc](https://etke.cc/) ([here](https://gitlab.com/etke.cc)) all along)." msgstr "" -#: ../../../CHANGELOG.md:998 +#: ../../../CHANGELOG.md:1605 msgid "We're no lawyers and this changelog entry does not aim to give you the best legal advice, so please research on your own!" msgstr "" -#: ../../../CHANGELOG.md:1000 +#: ../../../CHANGELOG.md:1607 msgid "If you'd like to continue using the old Apache-2.0-licensed Synapse (for a while longer anyway), the playbook makes it possible by introducing a new Ansible variable. You can do it like this:" msgstr "" -#: ../../../CHANGELOG.md:1012 +#: ../../../CHANGELOG.md:1619 msgid "Notes:" msgstr "" -#: ../../../CHANGELOG.md:1014 +#: ../../../CHANGELOG.md:1621 msgid "if you had already upgraded Synapse to `v1.99.0` by running this playbook, you will still be able to downgrade to `v1.98.0`, because both releases use the same database schema version (`SCHEMA_COMPAT_VERSION = 83` — see [here for v1.98.0](https://github.com/element-hq/synapse/blob/v1.98.0/synapse/storage/schema/__init__.py#L131-L134) and [here for v1.99.0](https://github.com/element-hq/synapse/blob/v1.99.0/synapse/storage/schema/__init__.py#L137-L140)). More details on Synapse's database schema are available [here](https://element-hq.github.io/synapse/develop/development/database_schema.html). It appears that there are no new database migrations introduced in `v1.99.0`, so going back to the older release is possible. This is not guaranteed to hold true for future Synapse releases, so if you're seeing this early-enough, consider pinning the version and organization before re-running the playbook and getting upgraded to the latest version" msgstr "" -#: ../../../CHANGELOG.md:1016 +#: ../../../CHANGELOG.md:1623 msgid "running an outdated homeserver exposes you to security issues and incompatibilities. Only consider doing this as a short-term solution." msgstr "" -#: ../../../CHANGELOG.md:1018 +#: ../../../CHANGELOG.md:1625 msgid "2024-01-16" msgstr "" -#: ../../../CHANGELOG.md:1020 +#: ../../../CHANGELOG.md:1627 msgid "`Draupnir` has been relicensed to AFL-3.0" msgstr "" -#: ../../../CHANGELOG.md:1022 +#: ../../../CHANGELOG.md:1629 msgid "As of [#204](https://github.com/the-draupnir-project/Draupnir/pull/204) Draupnir changed its licence to AFL-3.0 from the CSL licence. This change affects playbook users who could not run Draupnir under the old license restrictions. The new license is considerably less restrictive and is OSI approved. Draupnir version v1.86.0 and later are covered by this license change." msgstr "" -#: ../../../CHANGELOG.md:1024 +#: ../../../CHANGELOG.md:1631 msgid "2024-01-15" msgstr "" -#: ../../../CHANGELOG.md:1026 +#: ../../../CHANGELOG.md:1633 msgid "Goodbye, `matrix-nginx-proxy` 🪦" msgstr "" -#: ../../../CHANGELOG.md:1028 +#: ../../../CHANGELOG.md:1635 msgid "**TLDR**: All traces of the `matrix-nginx-proxy` reverse-proxy component are now gone. This brought about many other internal changes (and security improvements), so setups may need minor adjustments or suffer some (temporary) breakage. People who have been on the Traefik-native setup may upgrade without much issues. Those running their own Traefik instance may need minor changes. People who have been postponing the migration away from `matrix-nginx-proxy` (for more than a year already!) will now finally need to do something about it." msgstr "" -#: ../../../CHANGELOG.md:1030 +#: ../../../CHANGELOG.md:1637 msgid "Backstory on `matrix-nginx-proxy`" msgstr "" -#: ../../../CHANGELOG.md:1032 +#: ../../../CHANGELOG.md:1639 msgid "We gather here today to celebrate the loss of a once-beloved component in our stack — `matrix-nginx-proxy`. It's been our [nginx](https://nginx.org/)-based reverse-proxy of choice since the [first commit](https://github.com/spantaleev/matrix-docker-ansible-deploy/tree/87f5883f2455fb115457b65f267f17de305c053c) of this playbook, 7 years ago." msgstr "" -#: ../../../CHANGELOG.md:1034 +#: ../../../CHANGELOG.md:1641 msgid "For 6 years, `matrix-nginx-proxy` has been the front-most reverse-proxy in our setup (doing SSL termination, etc.). After [transitioning to Traefik last year](#traefik-is-the-default-reverse-proxy-now), `matrix-nginx-proxy` took a step back. Nevertheless, since it was so ingrained into the playbook, it still remained in use — even if only internally. Despite our warnings of its imminent death, many of you have indubitably continued to use it instead of Traefik. Its suffering continued for too long, because it served many different purposes and massive effort was required to transition them to others." msgstr "" -#: ../../../CHANGELOG.md:1036 +#: ../../../CHANGELOG.md:1643 msgid "To us, `matrix-nginx-proxy` was:" msgstr "" -#: ../../../CHANGELOG.md:1038 +#: ../../../CHANGELOG.md:1645 msgid "an [nginx](https://nginx.org/)-based reverse-proxy" msgstr "" -#: ../../../CHANGELOG.md:1039 +#: ../../../CHANGELOG.md:1646 msgid "an Ansible role organizing the work of [certbot](https://certbot.eff.org/) — retrieving free [Let's Encrypt](https://letsencrypt.org/) SSL certificates for `matrix-nginx-proxy` and for the [coturn TURN server](./docs/configuring-playbook-turn.md)" msgstr "" -#: ../../../CHANGELOG.md:1040 +#: ../../../CHANGELOG.md:1647 msgid "a central component for reverse-proxying to the [long list of services](./docs/configuring-playbook.md) supported by the playbook. As such, it became a dependency that all these services had to inject themselves into during runtime" msgstr "" -#: ../../../CHANGELOG.md:1041 +#: ../../../CHANGELOG.md:1648 msgid "an intermediary through which addons (bridges, bots) communicated with the homeserver. Going through an intermediary (instead of directly talking to the homeserver) is useful when certain components (like [matrix-media-repo](./docs/configuring-playbook-matrix-media-repo.md) or [matrix-corporal](./docs/configuring-playbook-matrix-corporal.md)) are enabled, because it lets these services \"steal routes\" from the homeserver" msgstr "" -#: ../../../CHANGELOG.md:1042 +#: ../../../CHANGELOG.md:1649 msgid "a webserver for serving the `/.well-known/matrix` static files (generated by the `matrix-base` role until now)" msgstr "" -#: ../../../CHANGELOG.md:1043 +#: ../../../CHANGELOG.md:1650 msgid "a webserver [serving your base domain](./docs/configuring-playbook-base-domain-serving.md) (and also generating the `index.html` page for it)" msgstr "" -#: ../../../CHANGELOG.md:1044 +#: ../../../CHANGELOG.md:1651 msgid "a central component providing global [HTTP Basic Auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) password-protection for all `/metrics` endpoints when metrics were exposed publicly for consumption from a remote Prometheus server" msgstr "" -#: ../../../CHANGELOG.md:1046 +#: ../../../CHANGELOG.md:1653 msgid "Talk about a jack of all trades! The [UNIX philosophy](https://en.wikipedia.org/wiki/Unix_philosophy) (and Docker container philosophy) of \"do one thing and do it well\" had been severely violated for too long." msgstr "" -#: ../../../CHANGELOG.md:1048 +#: ../../../CHANGELOG.md:1655 msgid "On a related note, we also had a large chain of reverse-proxies in the mix. In the worst case, it was something like this: (Traefik -> `matrix-nginx-proxy:8080` -> `matrix-nginx-proxy:12080` -> `matrix-synapse-reverse-proxy-companion:8008` -> `matrix-synapse:8008`)." msgstr "" -#: ../../../CHANGELOG.md:1050 +#: ../../../CHANGELOG.md:1657 msgid "Due to complexity and the playbook's flexibility (trying to accommodate a mix of tens of components), many layers of indirection were necessary. We do like reverse-proxies, but… not quite enough to enjoy going through a chain of ~4 of them before reaching the target service." msgstr "" -#: ../../../CHANGELOG.md:1052 +#: ../../../CHANGELOG.md:1659 msgid "After **a ton of work** in the last weeks (200+ commits, which changed 467 files - 8684 insertions and 8913 deletions), **we're finally saying goodbye** to `matrix-nginx-proxy`." msgstr "" -#: ../../../CHANGELOG.md:1054 +#: ../../../CHANGELOG.md:1661 msgid "Going Traefik-native and cutting out all middlemen" msgstr "" -#: ../../../CHANGELOG.md:1056 +#: ../../../CHANGELOG.md:1663 msgid "In our new setup, you'll see the bare minimum number of reverse-proxies." msgstr "" -#: ../../../CHANGELOG.md:1058 +#: ../../../CHANGELOG.md:1665 msgid "In most cases, there's only Traefik and all services being registered directly with it. When [Synapse workers](./docs/configuring-playbook-synapse.md#load-balancing-with-workers) are enabled, `matrix-synapse-reverse-proxy-companion` remains as an extra reverse-proxy that requests go through (for load-balancing to the correct Synapse worker), but in all other cases services are exposed directly." msgstr "" -#: ../../../CHANGELOG.md:1060 +#: ../../../CHANGELOG.md:1667 msgid "This reduces \"network\" hops (improving performance) and also decreases the number of components (containers). Each Ansible role in our setup is now independent and doesn't need to interact with other roles during runtime." msgstr "" -#: ../../../CHANGELOG.md:1062 +#: ../../../CHANGELOG.md:1669 msgid "Traefik now has an extra job" msgstr "" -#: ../../../CHANGELOG.md:1064 +#: ../../../CHANGELOG.md:1671 msgid "Previously, **Traefik had a single purpose** — being the main reverse-proxy. It was either front-most (terminating SSL, etc.) or you were [fronting Traefik with your own other reverse-proxy](./docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy). In any case — it had this central (yet decentralized) job." msgstr "" -#: ../../../CHANGELOG.md:1066 +#: ../../../CHANGELOG.md:1673 msgid "Now, **Traefik has one more role** — it serves as an intermediary which allows addon services (bridges, bots, etc.) to communicate with the homeserver. As mentioned above, such an intermediary service is not strictly necessary in all kinds of setups, but more complex setups (including [matrix-media-repo](./docs/configuring-playbook-matrix-media-repo.md) or [matrix-corporal](./docs/configuring-playbook-matrix-corporal.md)) benefit from it." msgstr "" -#: ../../../CHANGELOG.md:1068 +#: ../../../CHANGELOG.md:1675 msgid "To perform this new role, Traefik now has a new internal [entrypoint](https://doc.traefik.io/traefik/routing/entrypoints/) called `matrix-internal-matrix-client-api`. All homeservers (Conduit, Dendrite, Synapse and even `matrix-synapse-reverse-proxy-companion`) and homeserver-related core services ([matrix-media-repo](./docs/configuring-playbook-matrix-media-repo.md), [matrix-corporal](./docs/configuring-playbook-matrix-corporal.md) and potentially others) register their routes (using [container labels](https://docs.docker.com/config/labels-custom-metadata/)) not only on the public entrypoints (`web-secure`, `matrix-federation`), but also on this new internal entrypoint." msgstr "" -#: ../../../CHANGELOG.md:1070 +#: ../../../CHANGELOG.md:1677 msgid "Doing so, services can contact Traefik on this entrypoint's dedicated port (the URL defaults to `http://matrix-traefik:8008`) and reach the homeserver Client-Server API as they expect. Internally, Traefik takes care of the routing to the correct service." msgstr "" -#: ../../../CHANGELOG.md:1072 +#: ../../../CHANGELOG.md:1679 msgid "We've also considered keeping it simple and having services talk to the homeserver over the public internet (e.g. `https://matrix.example.com`) thus reusing all existing Traefik routing labels. In this scenario, performance was incredibly poor (e.g. 70 rps, instead of 1400 rps) due to TLS and networking overhead. The need for fast internal communication (via the new internal non-TLS-enabled Traefik entrypoint) is definitely there. In our benchmarks, Traefik even proved more efficient than nginx at doing this: ~1200 rps for Traefik compared to ~900 rps for nginx (out of ~1400 rps when talking to the Synapse homeserver directly)." msgstr "" -#: ../../../CHANGELOG.md:1074 +#: ../../../CHANGELOG.md:1681 msgid "Traefik serving this second purpose has a few downsides:" msgstr "" -#: ../../../CHANGELOG.md:1076 +#: ../../../CHANGELOG.md:1683 msgid "Traefik becomes a runtime dependency for all homeserver-dependant container services" msgstr "" -#: ../../../CHANGELOG.md:1077 +#: ../../../CHANGELOG.md:1684 msgid "all homeserver-dependant services now need to be connected to the `traefik` container network, even if they don't need public internet exposure" msgstr "" -#: ../../../CHANGELOG.md:1079 +#: ../../../CHANGELOG.md:1686 msgid "Despite these downsides (which the playbook manages automatically), we believe it's still a good compromise given the amount of complexity it eliminates and the performance benefits it yields. One alternative we've [considered](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3045#issuecomment-1867327001) was adding a new intermediary service (e.g. `matrix-homeserver-proxy` powered by nginx), but this both had much higher complexity (one more component in the mix; duplication of effort to produce nginx-compatible route definitions for it) and slightly worse performance (see above)." msgstr "" -#: ../../../CHANGELOG.md:1081 +#: ../../../CHANGELOG.md:1688 msgid "People running the default Traefik setup do not need to do anything to make Traefik take on this extra job. Your Traefik configuration will be updated automatically." msgstr "" -#: ../../../CHANGELOG.md:1083 +#: ../../../CHANGELOG.md:1690 msgid "**People running their own Traefik reverse-proxy need to do [minor adjustments](#people-managing-their-own-traefik-instance-need-to-do-minor-changes)**, as described in the section below." msgstr "" -#: ../../../CHANGELOG.md:1085 +#: ../../../CHANGELOG.md:1692 msgid "You may disable Traefik acting as an intermediary by explicitly setting `matrix_playbook_public_matrix_federation_api_traefik_entrypoint_enabled` to `false`. Services would then be configured to talk to the homeserver directly, giving you a slight performance boost and a \"simpler\" Traefik setup. However, such a configuration is less tested and will cause troubles, especially if you enable more services (like `matrix-media-repo`, etc.) in the future. As such, it's not recommended." msgstr "" -#: ../../../CHANGELOG.md:1087 +#: ../../../CHANGELOG.md:1694 msgid "People managing their own Traefik instance need to do minor changes" msgstr "" -#: ../../../CHANGELOG.md:1089 +#: ../../../CHANGELOG.md:1696 msgid "This section is for people [managing their own Traefik instance on the Matrix server](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-you). Those [using Traefik managed by the playbook](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-the-playbook) don't need to do any changes." msgstr "" -#: ../../../CHANGELOG.md:1091 +#: ../../../CHANGELOG.md:1698 msgid "Because [Traefik has an extra job now](#traefik-now-has-an-extra-job), you need to adapt your configuration to add the additional `matrix-internal-matrix-client-api` entrypoint and potentially configure the `matrix_playbook_reverse_proxy_container_network` variable. See the [Traefik managed by you](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-you) documentation section for more details." msgstr "" -#: ../../../CHANGELOG.md:1093 +#: ../../../CHANGELOG.md:1700 msgid "People fronting Traefik with another reverse proxy need to do minor changes" msgstr "" -#: ../../../CHANGELOG.md:1095 +#: ../../../CHANGELOG.md:1702 msgid "We've already previously mentioned that you need to do some minor [configuration changes related to `traefik_additional_entrypoints_auto`](#backward-compatibility-configuration-changes-required-for-people-fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy)." msgstr "" -#: ../../../CHANGELOG.md:1097 +#: ../../../CHANGELOG.md:1704 msgid "If you don't do these changes (switching from `traefik_additional_entrypoints_auto` to multiple other variables), your Traefik setup will not automatically receive the new `matrix-internal-matrix-client-api` Traefik entrypoint and Traefik would not be able to perform [its new duty of connecting addons with the homeserver](#traefik-now-has-an-extra-job)." msgstr "" -#: ../../../CHANGELOG.md:1099 +#: ../../../CHANGELOG.md:1706 msgid "Supported reverse proxy types are now fewer" msgstr "" -#: ../../../CHANGELOG.md:1101 +#: ../../../CHANGELOG.md:1708 msgid "This section is for people using a more custom reverse-proxy setup — those having `matrix_playbook_reverse_proxy_type` set to a value different than the default (`playbook-managed-traefik`)." msgstr "" -#: ../../../CHANGELOG.md:1103 +#: ../../../CHANGELOG.md:1710 msgid "Previously, we allowed you to set `matrix_playbook_reverse_proxy_type` to 7 different values to accommodate various reverse-proxy setups." msgstr "" -#: ../../../CHANGELOG.md:1105 +#: ../../../CHANGELOG.md:1712 msgid "The complexity of this is too high, so we only support 3 values right now:" msgstr "" -#: ../../../CHANGELOG.md:1107 +#: ../../../CHANGELOG.md:1714 msgid "(the default) `playbook-managed-traefik`, when you're [using Traefik managed by the playbook](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-the-playbook)" msgstr "" -#: ../../../CHANGELOG.md:1108 +#: ../../../CHANGELOG.md:1715 msgid "`other-traefik-container`, when you're [managing your own Traefik instance on the Matrix server](./docs/configuring-playbook-own-webserver.md#traefik-managed-by-you)" msgstr "" -#: ../../../CHANGELOG.md:1109 +#: ../../../CHANGELOG.md:1716 msgid "`none`, when you wish for [no reverse-proxy integration to be done at all](./docs/configuring-playbook-own-webserver.md#using-no-reverse-proxy-on-the-matrix-side-at-all)" msgstr "" -#: ../../../CHANGELOG.md:1111 +#: ../../../CHANGELOG.md:1718 msgid "The `none` value is not recommended and may not work adequately, due to lack of testing and [Traefik's new responsibilities](#traefik-now-has-an-extra-job) in our setup." msgstr "" -#: ../../../CHANGELOG.md:1113 +#: ../../../CHANGELOG.md:1720 msgid "**Previous values that are now gone** (and the playbook would report them as such) are: `playbook-managed-nginx`, `other-nginx-non-container`, `other-on-same-host` and `other-on-another-host`." msgstr "" -#: ../../../CHANGELOG.md:1115 +#: ../../../CHANGELOG.md:1722 msgid "If you were using these values as a way to stay away from Traefik, you now have 2 options:" msgstr "" -#: ../../../CHANGELOG.md:1117 +#: ../../../CHANGELOG.md:1724 msgid "(recommended) [Fronting Traefik with another reverse-proxy](./docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy)" msgstr "" -#: ../../../CHANGELOG.md:1118 +#: ../../../CHANGELOG.md:1725 msgid "(not recommended) [Using no reverse-proxy on the Matrix side at all](./docs/configuring-playbook-own-webserver.md#using-no-reverse-proxy-on-the-matrix-side-at-all) and reverse-proxying to each and every service manually" msgstr "" -#: ../../../CHANGELOG.md:1120 +#: ../../../CHANGELOG.md:1727 msgid "Container networking changes" msgstr "" -#: ../../../CHANGELOG.md:1122 +#: ../../../CHANGELOG.md:1729 msgid "Now that `matrix-nginx-proxy` is not in the mix, it became easier to clear out some other long-overdue technical debt." msgstr "" -#: ../../../CHANGELOG.md:1124 +#: ../../../CHANGELOG.md:1731 msgid "Since the very beginning of this playbook, all playbook services were connected to a single (shared) `matrix` container network. Later on, some additional container networks appeared, but most services (database, etc.) still remained in the `matrix` container network. This meant that any random container in this network could try to talk (or attack) the Postgres database operating in the same `matrix` network." msgstr "" -#: ../../../CHANGELOG.md:1126 +#: ../../../CHANGELOG.md:1733 msgid "Moving components (especially the database) into other container networks was difficult — it required changes to many other components to ensure correct connectivity." msgstr "" -#: ../../../CHANGELOG.md:1128 +#: ../../../CHANGELOG.md:1735 msgid "All the hard work has been done now. We've added much more isolation between services by splitting them up into separate networks (`matrix-homeserver`, `matrix-addons`, `matrix-monitoring`, `matrix-exim-relay`, etc). Components are only joined to the networks they need and should (for the most part) not be able to access unrelated things." msgstr "" -#: ../../../CHANGELOG.md:1130 +#: ../../../CHANGELOG.md:1737 msgid "Carrying out these container networking changes necessitated modifying many components, so **we're hoping not too many bugs were introduced in the process**." msgstr "" -#: ../../../CHANGELOG.md:1132 +#: ../../../CHANGELOG.md:1739 msgid "We've refrained from creating too many container networks (e.g. one for each component), to avoid exhausting Docker's default network pool and contaminating the container networks list too much." msgstr "" -#: ../../../CHANGELOG.md:1134 +#: ../../../CHANGELOG.md:1741 msgid "Metrics exposure changes" msgstr "" -#: ../../../CHANGELOG.md:1136 +#: ../../../CHANGELOG.md:1743 msgid "This section is for people who are exposing monitoring metrics publicly, to be consumed by an external Prometheus server." msgstr "" -#: ../../../CHANGELOG.md:1138 +#: ../../../CHANGELOG.md:1745 msgid "Previously, `matrix-nginx-proxy` was potentially password-protecting all `/metrics/*` endpoints with the same username and password (specified as plain-text in your `vars.yml` configuration file)." msgstr "" -#: ../../../CHANGELOG.md:1140 +#: ../../../CHANGELOG.md:1747 msgid "From now on, there are new variables for doing roughly the same — `matrix_metrics_exposure_enabled`, `matrix_metrics_exposure_http_basic_auth_enabled` and `matrix_metrics_exposure_http_basic_auth_users`. See the [Prometheus & Grafana](./docs/configuring-playbook-prometheus-grafana.md) docs page for details." msgstr "" -#: ../../../CHANGELOG.md:1142 +#: ../../../CHANGELOG.md:1749 msgid "`matrix-nginx-proxy` is not acting as a \"global guardian\" anymore. Now, each role provides its own metrics exposure and protection by registering with Traefik. Nevertheless, all roles are wired (via playbook configuration in `group_vars/matrix_servers`) to obey these new `matrix_metrics_exposure_*` variables. We've eliminated the centralization, but have kept the ease of use. Now, you can also do per-service password-protection (with different credentials), should you need to do that for some reason." msgstr "" -#: ../../../CHANGELOG.md:1144 +#: ../../../CHANGELOG.md:1751 msgid "The playbook will tell you about all variables that you need to migrate during runtime, so rest assured — you shouldn't be able to miss anything!" msgstr "" -#: ../../../CHANGELOG.md:1146 +#: ../../../CHANGELOG.md:1753 msgid "Matrix static files" msgstr "" -#: ../../../CHANGELOG.md:1148 +#: ../../../CHANGELOG.md:1755 msgid "As mentioned above, static files like `/.well-known/matrix/*` or your base domain's `index.html` file (when [serving the base domain via the Matrix server](./docs/configuring-playbook-base-domain-serving.md) was enabled) were generated by the `matrix-base` or `matrix-nginx-proxy` roles and put into a `/matrix/static-files` directory on the server. Then `matrix-nginx-proxy` was serving all these static files." msgstr "" -#: ../../../CHANGELOG.md:1150 +#: ../../../CHANGELOG.md:1757 msgid "All of this has been extracted into a new `matrix-static-files` Ansible role that's part of the playbook. The static files generated by this new role still live at roughly the same place (`/matrix/static-files/public` directory, instead of `/matrix/static-files`)." msgstr "" -#: ../../../CHANGELOG.md:1152 +#: ../../../CHANGELOG.md:1759 msgid "The playbook will migrate and update the `/.well-known/matrix/*` files automatically but not your own files in `nginx-proxy/data/matrix-domain/` you will need to back these up yourself otherwise they will be lost. It will also warn you about usage of old variable names, so you can adapt to the new names." msgstr "" -#: ../../../CHANGELOG.md:1154 +#: ../../../CHANGELOG.md:1761 msgid "A note on performance" msgstr "" -#: ../../../CHANGELOG.md:1156 +#: ../../../CHANGELOG.md:1763 msgid "Some of you have been voicing their concerns (for a long time) about Traefik being too slow and nginx being better." msgstr "" -#: ../../../CHANGELOG.md:1158 +#: ../../../CHANGELOG.md:1765 msgid "Some online benchmarks support this by demonstrating slightly higher SSL-termination performance in favor of nginx. The upcoming Traefik v3 release is [said to](https://medium.com/beyn-technology/is-nginx-dead-is-traefik-v3-20-faster-than-traefik-v2-f28ffb7eed3e) improve Traefik's SSL performance by some 20%, but that still ends up being somewhat slower than nginx." msgstr "" -#: ../../../CHANGELOG.md:1160 +#: ../../../CHANGELOG.md:1767 msgid "We believe that using Traefik provides way too many benefits to worry about this minor performance impairment." msgstr "" -#: ../../../CHANGELOG.md:1162 +#: ../../../CHANGELOG.md:1769 msgid "The heaviest part of running a Matrix homeserver is all the slow and potentially inefficient things the homeserver (e.g. Synapse) is doing. These things affect performance much more than whatever reverse-proxy is in front. Your server will die the same way by joining the famously large **Matrix HQ** room, no matter which reverse-proxy you put in front." msgstr "" -#: ../../../CHANGELOG.md:1164 +#: ../../../CHANGELOG.md:1771 msgid "Even our previously mentioned benchmarks (yielding ~1300 rps) are synthetic — hitting a useless `/_matrix/client/versions` endpoint. Real-use does much more than this." msgstr "" -#: ../../../CHANGELOG.md:1166 +#: ../../../CHANGELOG.md:1773 msgid "If this is still not convincing enough for you and you want the best possible performance, consider [Fronting Traefik with another reverse-proxy](./docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy) (thus having the slowest part — SSL termination — happen elsewhere) or [Using no reverse-proxy on the Matrix side at all](./docs/configuring-playbook-own-webserver.md#using-no-reverse-proxy-on-the-matrix-side-at-all). The playbook will not get in your way of doing that, but these options may make your life much harder. Performance comes at a cost, after all." msgstr "" -#: ../../../CHANGELOG.md:1168 +#: ../../../CHANGELOG.md:1775 msgid "Migration procedure" msgstr "" -#: ../../../CHANGELOG.md:1170 +#: ../../../CHANGELOG.md:1777 msgid "The updated playbook will automatically perform some migration tasks for you:" msgstr "" -#: ../../../CHANGELOG.md:1172 +#: ../../../CHANGELOG.md:1779 msgid "It will stop and remove the `matrix-nginx-proxy` systemd service and container for you. This behavior cannot be disabled. It's essential that this service gets stopped, because it remaining running (and having container labels) may confuse Traefik as to where to route HTTP requests." msgstr "" -#: ../../../CHANGELOG.md:1174 +#: ../../../CHANGELOG.md:1781 msgid "It will delete the `/matrix/nginx-proxy` directory and all files within it. You can disable this behavior by adding `matrix_playbook_migration_matrix_nginx_proxy_uninstallation_enabled: false` to your `vars.yml` configuration file. Doing so will leave its data around." msgstr "" -#: ../../../CHANGELOG.md:1176 +#: ../../../CHANGELOG.md:1783 msgid "It will delete the `/matrix/ssl` directory and all files within it. You can disable this behavior by adding `matrix_playbook_migration_matrix_ssl_uninstallation_enabled: false` to your `vars.yml` configuration file. If you have some important certificates there for some reason, take them out or temporarily disable removal of these files until you do." msgstr "" -#: ../../../CHANGELOG.md:1178 +#: ../../../CHANGELOG.md:1785 msgid "It will tell you about all variables (`matrix_nginx_proxy_*` and many others — even from other roles) that have changed during this large nginx-elimination upgrade. You can disable this behavior by adding `matrix_playbook_migration_matrix_nginx_proxy_elimination_variable_transition_checks_enabled: false` to your `vars.yml` configuration file." msgstr "" -#: ../../../CHANGELOG.md:1180 +#: ../../../CHANGELOG.md:1787 msgid "It will tell you about any leftover `matrix_nginx_proxy_*` variables in your `vars.yml` file. You can disable this behavior by adding `matrix_playbook_migration_matrix_nginx_proxy_leftover_variable_validation_checks_enabled: false` to your `vars.yml` configuration file." msgstr "" -#: ../../../CHANGELOG.md:1182 +#: ../../../CHANGELOG.md:1789 msgid "It will tell you about any leftover `matrix_ssl_*` variables in your `vars.yml` file. You can disable this behavior by adding `matrix_playbook_migration_matrix_ssl_leftover_variable_checks_enabled: false` to your `vars.yml` configuration file." msgstr "" -#: ../../../CHANGELOG.md:1184 +#: ../../../CHANGELOG.md:1791 msgid "We don't recommend changing these variables and suppressing warnings, unless you know what you're doing." msgstr "" -#: ../../../CHANGELOG.md:1186 +#: ../../../CHANGELOG.md:1793 msgid "**Most people should just upgrade as per-normal**, bearing in mind that a lot has changed and some issues may arise. The playbook would guide you through renamed variables automatically." msgstr "" -#: ../../../CHANGELOG.md:1188 +#: ../../../CHANGELOG.md:1795 msgid "Conclusion" msgstr "" -#: ../../../CHANGELOG.md:1190 +#: ../../../CHANGELOG.md:1797 msgid "Thousands of lines of code were changed across hundreds of files. All addons (bridges, bots) were rewired in terms of container networking and in terms of how they reach the homeserver." msgstr "" -#: ../../../CHANGELOG.md:1192 +#: ../../../CHANGELOG.md:1799 msgid "I don't actively use all the ~100 components offered by the playbook (no one does), nor do I operate servers exercising all edge-cases. As such, issues may arise. Please have patience and report (or try to fix) these issues!" msgstr "" -#: ../../../CHANGELOG.md:1195 +#: ../../../CHANGELOG.md:1802 msgid "2024-01-14" msgstr "" -#: ../../../CHANGELOG.md:1197 +#: ../../../CHANGELOG.md:1804 msgid "(Backward Compatibility) Configuration changes required for people fronting the integrated reverse-proxy webserver with another reverse-proxy" msgstr "" -#: ../../../CHANGELOG.md:1199 +#: ../../../CHANGELOG.md:1806 msgid "If you're on the default setup (using the Traefik reverse-proxy as installed by the playbook), you don't need to do anything." msgstr "" -#: ../../../CHANGELOG.md:1201 +#: ../../../CHANGELOG.md:1808 msgid "People who are [Fronting the integrated Traefik reverse-proxy webserver with another reverse-proxy](./docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy), as per our previous instructions are redefining `traefik_additional_entrypoints_auto` in their `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:1203 +#: ../../../CHANGELOG.md:1810 msgid "Such a full variable redefinion is intrustive, because it prevents the playbook from injecting additional entrypoints into the Traefik webserver. In the future, the playbook may have a need to do so." msgstr "" -#: ../../../CHANGELOG.md:1205 +#: ../../../CHANGELOG.md:1812 msgid "For this reason, we no longer recommend completely redefining `traefik_additional_entrypoints_auto`. The playbook now defines [various `matrix_playbook_public_matrix_federation_api_traefik_entrypoint_*` variables in the `defaults/main.yml` file](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/roles/custom/matrix-base/defaults/main.yml) of the `matrix-base` role which can be used as a safer alternative to `traefik_additional_entrypoints_auto`." msgstr "" -#: ../../../CHANGELOG.md:1207 +#: ../../../CHANGELOG.md:1814 msgid "Adapt your configuration as seen below:" msgstr "" -#: ../../../CHANGELOG.md:1240 +#: ../../../CHANGELOG.md:1847 msgid "Also, feel free to read the [Fronting the integrated Traefik reverse-proxy webserver with another reverse-proxy](./docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy) documentation section again for additional details." msgstr "" -#: ../../../CHANGELOG.md:1243 +#: ../../../CHANGELOG.md:1850 msgid "2024-01-13" msgstr "" -#: ../../../CHANGELOG.md:1245 +#: ../../../CHANGELOG.md:1852 msgid "matrix-reminder-bot update with more secure (backward-incompatible) default settings" msgstr "" -#: ../../../CHANGELOG.md:1247 +#: ../../../CHANGELOG.md:1854 msgid "**TLDR**: your updated (to [v0.3.0](https://github.com/anoadragon453/matrix-reminder-bot/releases/tag/v0.3.0)) [matrix-reminder-bot](./docs/configuring-playbook-bot-matrix-reminder-bot.md) is now more secure. By default, like other bridges/bots managed by the playbook, it will only provide its services to users of your own server (not to anyone, even across the Matrix Federation). If that's fine, there's nothing you need to do." msgstr "" -#: ../../../CHANGELOG.md:1249 +#: ../../../CHANGELOG.md:1856 msgid "Maintenance of [matrix-reminder-bot](./docs/configuring-playbook-bot-matrix-reminder-bot.md) has been picked up by [Kim Brose](https://github.com/HarHarLinks) and [@svierne](https://github.com/svierne)." msgstr "" -#: ../../../CHANGELOG.md:1251 +#: ../../../CHANGELOG.md:1858 msgid "Thanks to them, a new [v0.3.0](https://github.com/anoadragon453/matrix-reminder-bot/releases/tag/v0.3.0) release is out. The new version is now available for the ARM64 architecture, so playbook users on this architecture will no longer need to wait for [self-building](./docs/self-building.md) to happen." msgstr "" -#: ../../../CHANGELOG.md:1253 +#: ../../../CHANGELOG.md:1860 msgid "The new version also comes with new `allowlist` and `blocklist` settings, which make it possible to restrict who can use the bot. Previously anyone, even across the Matrix Federation could talk to it and schedule reminders." msgstr "" -#: ../../../CHANGELOG.md:1255 +#: ../../../CHANGELOG.md:1862 msgid "The playbook defaults all bridges and bots (where possible) to only be exposed to users of the current homeserver, not users across federation. Thanks to the new version of this bot making such a restriction possible, we're now making use of it. The playbook (via its `group_vars/matrix_servers` file) automatically enables the `allowlist` (`matrix_bot_matrix_reminder_bot_allowlist_enabled: true`) and configures it in such a way (`matrix_bot_matrix_reminder_bot_allowlist_regexes_auto`) so as to restrict the bot to your homeserver's users." msgstr "" -#: ../../../CHANGELOG.md:1257 +#: ../../../CHANGELOG.md:1864 msgid "If you need **to undo or tweak these security improvements**, you can change your `vars.yml` file to:" msgstr "" -#: ../../../CHANGELOG.md:1259 +#: ../../../CHANGELOG.md:1866 msgid "disable the allowlist (`matrix_bot_matrix_reminder_bot_allowlist_enabled: false`), making the bot allow usage by anyone, anywhere" msgstr "" -#: ../../../CHANGELOG.md:1261 +#: ../../../CHANGELOG.md:1868 msgid "inject additional allowed servers or users by adding **additional** (on top of the default allowlist in `matrix_bot_matrix_reminder_bot_allowlist_regexes_auto`) custom regexes in the `matrix_bot_matrix_reminder_bot_allowlist_regexes_custom` list variable (see the [syntax reference](https://github.com/anoadragon453/matrix-reminder-bot/blob/1e910c0aa3469d280d93ee7e6c6d577227a3460c/sample.config.yaml#L43-L49))" msgstr "" -#: ../../../CHANGELOG.md:1263 +#: ../../../CHANGELOG.md:1870 msgid "override the default allowlist (in the `group_vars/matrix_servers` file) by redefining `matrix_bot_matrix_reminder_bot_allowlist_regexes_auto`" msgstr "" -#: ../../../CHANGELOG.md:1266 +#: ../../../CHANGELOG.md:1873 msgid "2024-01-05" msgstr "" -#: ../../../CHANGELOG.md:1268 +#: ../../../CHANGELOG.md:1875 msgid "matrix-mailer has been replaced by the exim-relay external role" msgstr "" -#: ../../../CHANGELOG.md:1270 -#: ../../../CHANGELOG.md:1908 +#: ../../../CHANGELOG.md:1877 +#: ../../../CHANGELOG.md:2515 msgid "We're continuing our effort to make [the playbook use external roles for some things](#the-playbook-now-uses-external-roles-for-some-things), so as to avoid doing everything ourselves and to facilitate code re-use." msgstr "" -#: ../../../CHANGELOG.md:1272 +#: ../../../CHANGELOG.md:1879 msgid "The `matrix-mailer` role has been moved to its own repository ([ansible-role-exim-relay](https://github.com/mother-of-all-self-hosting/ansible-role-exim-relay)) that this playbook now includes." msgstr "" -#: ../../../CHANGELOG.md:1274 +#: ../../../CHANGELOG.md:1881 msgid "To migrate:" msgstr "" -#: ../../../CHANGELOG.md:1276 +#: ../../../CHANGELOG.md:1883 msgid "pull the playbook changes, as usual" msgstr "" -#: ../../../CHANGELOG.md:1277 +#: ../../../CHANGELOG.md:1884 msgid "update your roles (run `just roles` or `make roles`)" msgstr "" -#: ../../../CHANGELOG.md:1278 +#: ../../../CHANGELOG.md:1885 msgid "update your `vars.yml`, renaming `matrix_mailer`-prefixed variables to `exim_relay`-prefixed ones (e.g. `matrix_mailer_sender_address` -> `exim_relay_sender_address`). If you find none, it means you're using the default configuration and your migraiton job is even simpler." msgstr "" -#: ../../../CHANGELOG.md:1279 +#: ../../../CHANGELOG.md:1886 msgid "re-run the playbook (`install-all` or `setup-all`)" msgstr "" -#: ../../../CHANGELOG.md:1281 +#: ../../../CHANGELOG.md:1888 msgid "The playbook will take care of stopping the old `matrix-mailer` systemd service, relocating its directory and restarting it under the new name (`matrix-exim-relay.service`)." msgstr "" -#: ../../../CHANGELOG.md:1284 +#: ../../../CHANGELOG.md:1891 msgid "2024-01-02" msgstr "" -#: ../../../CHANGELOG.md:1286 +#: ../../../CHANGELOG.md:1893 msgid "mautrix-signal now powered by the new Go-based bridge" msgstr "" -#: ../../../CHANGELOG.md:1288 +#: ../../../CHANGELOG.md:1895 msgid "The old Python-based [mautrix-signal](https://github.com/mautrix/signal) bridge is no longer maintained upstream. It's also known to have issues linking new devices." msgstr "" -#: ../../../CHANGELOG.md:1290 +#: ../../../CHANGELOG.md:1897 msgid "It seems like the path forward is to switch to the new mautrix-signal bridge written in Golang, which we did thanks to [PR #3031](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/3041) by [Pierre 'McFly' Marty](https://github.com/pm-McFly)." msgstr "" -#: ../../../CHANGELOG.md:1292 +#: ../../../CHANGELOG.md:1899 msgid "The playbook should **automatically migrate your mautrix-signal installation to the new bridge code**. You will **need to relink all your devices** to continue your bridged conversations." msgstr "" -#: ../../../CHANGELOG.md:1295 +#: ../../../CHANGELOG.md:1902 msgid "2023-10-23" msgstr "" -#: ../../../CHANGELOG.md:1297 +#: ../../../CHANGELOG.md:1904 msgid "Enabling `allow_public_rooms_over_federation` by default for Synapse" msgstr "" -#: ../../../CHANGELOG.md:1299 +#: ../../../CHANGELOG.md:1906 msgid "**TDLR**: if your Matrix server is federating (which it mostly likely is, unless you've [disabled federation](docs/configuring-playbook-federation.md#disabling-federation)), your public rooms will not only be joinable across federation (as they've always been), but from now on will be discoverable (made available as a list across federation). We're changing this by flipping the value for Synapse's `allow_public_rooms_over_federation` setting to `true`, going against the upstream default. Servers that disable federation are not affected. Servers that have public rooms which are not published to the room directory are also not affected." msgstr "" -#: ../../../CHANGELOG.md:1301 +#: ../../../CHANGELOG.md:1908 msgid "We generally try to stick to the default configuration for Synapse (and all other components), unless these defaults seem wrong or harmful. One such previous case from a few months ago was us [Enabling `forget_rooms_on_leave` by default for Synapse](#enabling-forget_rooms_on_leave-by-default-for-synapse) — the default value was making Synapse more wasteful of resources by default." msgstr "" -#: ../../../CHANGELOG.md:1303 +#: ../../../CHANGELOG.md:1910 msgid "Today, we're going against upstream defaults again and flipping the `allow_public_rooms_over_federation` configuration option to `true`. This way, public rooms on your server will be made discoverable by others via federation, using the [`GET /_matrix/federation/v1/publicRooms` of the Server-Server API](https://spec.matrix.org/v1.8/server-server-api/#get_matrixfederationv1publicrooms)." msgstr "" -#: ../../../CHANGELOG.md:1305 +#: ../../../CHANGELOG.md:1912 msgid "The upstream Synapse default is `false` (disabled), so that public rooms are not exposed for other servers to discover (learn about their existence). Nevertheless, even if these rooms are not exposed (listed) for discovery, they are **still joinable** by anyone who knows their address or is invited to the room by an existing member." msgstr "" -#: ../../../CHANGELOG.md:1307 +#: ../../../CHANGELOG.md:1914 msgid "**We go against the upstream default** in an effort to make Matrix federation more useful — a public room should be globally public — not only joinable, but also discoverable across federation." msgstr "" -#: ../../../CHANGELOG.md:1309 +#: ../../../CHANGELOG.md:1916 msgid "The **historical reasoning** behind this change is as follows:" msgstr "" -#: ../../../CHANGELOG.md:1311 +#: ../../../CHANGELOG.md:1918 msgid "`allow_public_rooms_over_federation` seems to have been enabled by default for Synapse until v1.7.0 (~2019), just like we believe it should be for a globally-federating network — rooms should be joinable and discoverable across federation." msgstr "" -#: ../../../CHANGELOG.md:1313 +#: ../../../CHANGELOG.md:1920 msgid "In Synapse v1.7.0 (~2019), `allow_public_rooms_over_federation` [got disabled](https://github.com/element-hq/synapse/blob/e9069c9f919685606506f04527332e83fbfa44d9/docs/upgrade.md?plain=1#L1877-L1891) by default in a [security-by-obscurity](https://en.wikipedia.org/wiki/Security_through_obscurity) workaround for misconfigured servers. See the [Avoiding unwelcome visitors on private Matrix servers](https://matrix.org/blog/2019/11/09/avoiding-unwelcome-visitors-on-private-matrix-servers/) `matrix.org` blog article. We believe that people wishing for a truly private server, should [disable federation](docs/configuring-playbook-federation.md#disabling-federation), instead of having a fully-federating server and trying to hide its public rooms. We also provide other workarounds below. We (and the Synapse team, obviously) believe that Matrix should federate by default, so federating the public room list seems to make sense." msgstr "" -#: ../../../CHANGELOG.md:1315 +#: ../../../CHANGELOG.md:1922 msgid "[etke.cc](https://etke.cc/) has been developing the free-software [Matrix Rooms Search](https://github.com/etkecc/mrs) project for a while now. One public (demo) instance of it is hosted at [matrixrooms.info](https://matrixrooms.info/). This search engine tries to go through the Matrix federation and discover & index public rooms to allow people to find them. We believe it's vital for Matrix (and any chat or social network for that matter) to be more discoverable, so that people can find communities and others to talk to. Today (on 23rd of October 2023), `matrixrooms.info` is indexing `23066` Matrix servers. Of these, only `1567` servers (7%) are making their public rooms discoverable. Who knows what wonderful communities and rooms are available on these 93% other Matrix servers that are supposedly federating, but are still gate-keeping their public room list. Indubitably, many of these servers are hosted via matrix-docker-ansible-deploy, so we feel partially responsible for making Matrix federation less useful." msgstr "" -#: ../../../CHANGELOG.md:1317 +#: ../../../CHANGELOG.md:1924 msgid "Here are **actions you may wish to take** as a result of this change:" msgstr "" -#: ../../../CHANGELOG.md:1319 +#: ../../../CHANGELOG.md:1926 msgid "(recommended) embrace the new default. If your Matrix server is federating, your public rooms have always been joinable across federation anyway. Exposing the list of public rooms does no harm and more-so does good by contributing to the usefulness of the Matrix network by facilitating room discovery." msgstr "" -#: ../../../CHANGELOG.md:1321 +#: ../../../CHANGELOG.md:1928 msgid "(switch to a better way of doings things on your semi-private server) The problem that the Synapse team appears to have solved by flipping the `allow_public_rooms_over_federation` default in Synapse v1.7.0 seems to for \"mostly private\" servers, which federate and have a bunch of rooms made public (and published in their room directory) in an effort to allow people on the same homeserver to easily find and join them (self-onboarding). With the introduction of Matrix Spaces, you can reorganize your flow around spaces — you can auto-join your users to a Matrix Space (via Synapse's `auto_join_rooms` setting — controlled by our `matrix_synapse_auto_join_rooms` variable), then add a bunch of rooms to the space and make them joinable by people belonging to the space. That is to say, do not make rooms public and do not publish them to the room directory unless they are really public. Instead, use other mechanisms for semi-public rooms or private rooms. One alternative is to stick to what you're doing (public rooms published to your rooms directory) but having a `m.federate: true` flag set during creation (clients like Element Web have a nice UI checkbox for this) to explicitly disable federation for them." msgstr "" -#: ../../../CHANGELOG.md:1323 +#: ../../../CHANGELOG.md:1930 msgid "(keeping the old behavior) if you wish to keep doing what you're doing (keeping your Matrix server federating, but hiding its public rooms list), add `matrix_synapse_allow_public_rooms_over_federation: false` to your `vars.yml` configuration. This restores the old behavior. You may also consider [disabling federation](docs/configuring-playbook-federation.md#disabling-federation) completely instead of relying on security-by-obscurity measures." msgstr "" -#: ../../../CHANGELOG.md:1326 +#: ../../../CHANGELOG.md:1933 msgid "2023-10-18" msgstr "" -#: ../../../CHANGELOG.md:1328 +#: ../../../CHANGELOG.md:1935 msgid "Postgres parameters are automatically tuned now" msgstr "" -#: ../../../CHANGELOG.md:1330 +#: ../../../CHANGELOG.md:1937 msgid "The playbook has provided some hints about [Tuning PostgreSQL](docs/maintenance-postgres.md#tuning-postgresql) for quite a while now." msgstr "" -#: ../../../CHANGELOG.md:1332 +#: ../../../CHANGELOG.md:1939 msgid "From now on, the [Postgres Ansible role](https://github.com/mother-of-all-self-hosting/ansible-role-postgres) automatically tunes your Postgres configuration with the same [calculation logic](https://github.com/le0pard/pgtune/blob/master/src/features/configuration/configurationSlice.js) that powers https://pgtune.leopard.in.ua/." msgstr "" -#: ../../../CHANGELOG.md:1334 +#: ../../../CHANGELOG.md:1941 msgid "Our [Tuning PostgreSQL](docs/maintenance-postgres.md#tuning-postgresql) documentation page has details about how you can turn auto-tuning off or adjust the automatically-determined Postgres configuration parameters manually." msgstr "" -#: ../../../CHANGELOG.md:1336 +#: ../../../CHANGELOG.md:1943 msgid "People who [enable load-balancing with Synapse workers](docs/configuring-playbook-synapse.md#load-balancing-with-workers) no longer need to increase the maximum number of Postgres connections manually (previously done via `postgres_process_extra_arguments`). There's a new variable (`postgres_max_connections`) for controlling this number and the playbook automatically raises its value from `200` to `500` for setups which enable workers." msgstr "" -#: ../../../CHANGELOG.md:1339 +#: ../../../CHANGELOG.md:1946 msgid "2023-08-31" msgstr "" -#: ../../../CHANGELOG.md:1341 +#: ../../../CHANGELOG.md:1948 msgid "SchildiChat Web support" msgstr "" -#: ../../../CHANGELOG.md:1343 +#: ../../../CHANGELOG.md:1950 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up the [SchildiChat Web](https://github.com/SchildiChat/schildichat-desktop) client." msgstr "" -#: ../../../CHANGELOG.md:1345 +#: ../../../CHANGELOG.md:1952 msgid "See our [Configuring SchildiChat Web](docs/configuring-playbook-client-schildichat-web.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1348 +#: ../../../CHANGELOG.md:1955 msgid "2023-08-23" msgstr "" -#: ../../../CHANGELOG.md:1350 +#: ../../../CHANGELOG.md:1957 msgid "mautrix-wsproxy support" msgstr "" -#: ../../../CHANGELOG.md:1352 +#: ../../../CHANGELOG.md:1959 msgid "Thanks to [Johan Swetzén](https://github.com/jswetzen)'s efforts (who finished what was started by [James Reilly](https://github.com/hanthor) and [Shreyas Ajjarapu](https://github.com/shreyasajj)), the playbook now supports bridging to Android SMS and Apple iMessage via the [mautrix-wsproxy](https://github.com/mautrix/wsproxy) service (in combination with a [mautrix-imessage](https://github.com/mautrix/imessage) bridge running on your Mac or Android phone)." msgstr "" -#: ../../../CHANGELOG.md:1354 +#: ../../../CHANGELOG.md:1961 msgid "See our [Setting up Mautrix wsproxy for bridging Android SMS or Apple iMessage](docs/configuring-playbook-bridge-mautrix-wsproxy.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:1357 +#: ../../../CHANGELOG.md:1964 msgid "2023-07-24" msgstr "" -#: ../../../CHANGELOG.md:1359 +#: ../../../CHANGELOG.md:1966 msgid "matrix-registration-bot usage changed" msgstr "" -#: ../../../CHANGELOG.md:1361 +#: ../../../CHANGELOG.md:1968 msgid "[matrix-registration-bot](docs/configuring-playbook-bot-matrix-registration-bot.md) got some updates and now supports password-only-based login. Therefore the bot now doesn't need any manual configuration except setting a password in your `vars.yml`. The bot will be registered as admin and access tokens will be obtained automatically by the bot." msgstr "" -#: ../../../CHANGELOG.md:1363 +#: ../../../CHANGELOG.md:1970 msgid "**For existing users** You need to set `matrix_bot_matrix_registration_bot_bot_password` if you previously only used `matrix_bot_matrix_registration_bot_bot_access_token`. Please also remove the following deprecated settings" msgstr "" -#: ../../../CHANGELOG.md:1365 +#: ../../../CHANGELOG.md:1972 msgid "`matrix_bot_matrix_registration_bot_bot_access_token`" msgstr "" -#: ../../../CHANGELOG.md:1366 +#: ../../../CHANGELOG.md:1973 msgid "`matrix_bot_matrix_registration_bot_api_token`" msgstr "" -#: ../../../CHANGELOG.md:1369 +#: ../../../CHANGELOG.md:1976 msgid "2023-07-21" msgstr "" -#: ../../../CHANGELOG.md:1371 +#: ../../../CHANGELOG.md:1978 msgid "mautrix-gmessages support" msgstr "" -#: ../../../CHANGELOG.md:1373 +#: ../../../CHANGELOG.md:1980 msgid "Thanks to [Shreyas Ajjarapu](https://github.com/shreyasajj)'s efforts, the playbook now supports bridging to [Google Messages](https://messages.google.com/) via the [mautrix-gmessages](https://github.com/mautrix/gmessages) bridge. See our [Setting up Mautrix Google Messages bridging](docs/configuring-playbook-bridge-mautrix-gmessages.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:1376 +#: ../../../CHANGELOG.md:1983 msgid "2023-07-17" msgstr "" -#: ../../../CHANGELOG.md:1378 +#: ../../../CHANGELOG.md:1985 msgid "matrix-media-repo support" msgstr "" -#: ../../../CHANGELOG.md:1380 +#: ../../../CHANGELOG.md:1987 msgid "Thanks to [Michael Hollister](https://github.com/Michael-Hollister) from [FUTO](https://www.futo.org/), the creators of the [Circles app](https://circu.li/), the playbook can now set up [matrix-media-repo](https://github.com/turt2live/matrix-media-repo) — an alternative way to store homeserver media files, powered by a homeserver-independent implementation which supports S3 storage, IPFS, deduplication and other advanced features." msgstr "" -#: ../../../CHANGELOG.md:1382 +#: ../../../CHANGELOG.md:1989 msgid "To learn more see our [Storing Matrix media files using matrix-media-repo](docs/configuring-playbook-matrix-media-repo.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:1385 +#: ../../../CHANGELOG.md:1992 msgid "2023-05-25" msgstr "" -#: ../../../CHANGELOG.md:1387 +#: ../../../CHANGELOG.md:1994 msgid "Enabling `forget_rooms_on_leave` by default for Synapse" msgstr "" -#: ../../../CHANGELOG.md:1389 +#: ../../../CHANGELOG.md:1996 msgid "With the [Synapse v1.84.0 update](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2698), we've also **changed the default value** of the `forget_rooms_on_leave` setting of Synapse to a value of `true`. This way, **when you leave a room, Synapse will now forget it automatically**." msgstr "" -#: ../../../CHANGELOG.md:1391 +#: ../../../CHANGELOG.md:1998 msgid "The upstream Synapse default is `false` (disabled), so that you must forget rooms manually after leaving." msgstr "" -#: ../../../CHANGELOG.md:1393 +#: ../../../CHANGELOG.md:2000 msgid "**We go against the upstream default** ([somewhat controversially](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2700)) in an effort to make Synapse leaner and potentially do what we believe most users would expect their homeserver to be doing." msgstr "" -#: ../../../CHANGELOG.md:1395 +#: ../../../CHANGELOG.md:2002 msgid "If you'd like to go back to the old behavior, add the following to your configuration: `matrix_synapse_forget_rooms_on_leave: false`" msgstr "" -#: ../../../CHANGELOG.md:1398 +#: ../../../CHANGELOG.md:2005 msgid "2023-04-03" msgstr "" -#: ../../../CHANGELOG.md:1400 +#: ../../../CHANGELOG.md:2007 msgid "The matrix-jitsi role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1402 +#: ../../../CHANGELOG.md:2009 msgid "**TLDR**: the `matrix-jitsi` role is now included from the [ansible-role-jitsi](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi) repository, part of the [MASH playbook](https://github.com/mother-of-all-self-hosting/mash-playbook). Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1404 +#: ../../../CHANGELOG.md:2011 msgid "The `matrix-jitsi` role has been relocated in its own repository, part of the [MASH playbook](https://github.com/mother-of-all-self-hosting/mash-playbook) project — an Ansible playbook for self-hosting [a growing list of FOSS software](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md). If hosting a Jitsi stack on the Matrix server itself did not stand right with you or you always wanted to host most stuff, you can now use this new playbook to do so." msgstr "" -#: ../../../CHANGELOG.md:1406 +#: ../../../CHANGELOG.md:2013 msgid "As part of the extraction process of this role out of the Matrix playbook, a few other things improved:" msgstr "" -#: ../../../CHANGELOG.md:1408 +#: ../../../CHANGELOG.md:2015 msgid "**native Traefik support** has been added" msgstr "" -#: ../../../CHANGELOG.md:1409 +#: ../../../CHANGELOG.md:2016 msgid "**support for hosting under a subpath** has been added, although it suffers from a few minor issues listed [here](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/jitsi.md#url)" msgstr "" -#: ../../../CHANGELOG.md:1411 +#: ../../../CHANGELOG.md:2018 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're using Jitsi or not." msgstr "" -#: ../../../CHANGELOG.md:1413 +#: ../../../CHANGELOG.md:2020 msgid "If you're making use of Jitsi via this playbook, you will need to update variable references in your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:1415 +#: ../../../CHANGELOG.md:2022 msgid "`matrix_jitsi_*_docker_image_` -> `matrix_jitsi_*_container_image_`" msgstr "" -#: ../../../CHANGELOG.md:1416 +#: ../../../CHANGELOG.md:2023 msgid "`matrix_jitsi_` -> `jitsi_`" msgstr "" -#: ../../../CHANGELOG.md:1417 -#: ../../../CHANGELOG.md:1444 +#: ../../../CHANGELOG.md:2024 +#: ../../../CHANGELOG.md:2051 msgid "some other internal variables have changed, but the playbook will tell you about them" msgstr "" -#: ../../../CHANGELOG.md:1419 +#: ../../../CHANGELOG.md:2026 msgid "2023-03-22" msgstr "" -#: ../../../CHANGELOG.md:1421 +#: ../../../CHANGELOG.md:2028 msgid "ntfy Web App is disabled by default" msgstr "" -#: ../../../CHANGELOG.md:1423 +#: ../../../CHANGELOG.md:2030 msgid "ntfy provides a web app, which is now disabled by default, because it may be unknown to and unused by most users of this playbook. You can enable it by setting `ntfy_web_root: \"app\"` (see [ntfy documentation](docs/configuring-playbook-ntfy.md))." msgstr "" -#: ../../../CHANGELOG.md:1425 +#: ../../../CHANGELOG.md:2032 msgid "This change was already applied a while before this entry, but as some users were reporting the missing web app, this entry was added (see [#2529](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2529))." msgstr "" -#: ../../../CHANGELOG.md:1428 +#: ../../../CHANGELOG.md:2035 msgid "2023-03-21" msgstr "" -#: ../../../CHANGELOG.md:1430 +#: ../../../CHANGELOG.md:2037 msgid "The matrix-prometheus role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1432 +#: ../../../CHANGELOG.md:2039 msgid "**TLDR**: the `matrix-prometheus` role is now included from the [ansible-role-prometheus](https://github.com/mother-of-all-self-hosting/ansible-role-prometheus) repository, part of the [MASH playbook](https://github.com/mother-of-all-self-hosting/mash-playbook). Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1434 +#: ../../../CHANGELOG.md:2041 msgid "The `matrix-prometheus` role has been relocated in its own repository, part of the [MASH playbook](https://github.com/mother-of-all-self-hosting/mash-playbook) project — an Ansible playbook for self-hosting [a growing list of FOSS software](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md). If hosting a Prometheus stack on the Matrix server itself did not stand right with you or you always wanted to host most stuff, you can now use this new playbook to do so." msgstr "" -#: ../../../CHANGELOG.md:1436 +#: ../../../CHANGELOG.md:2043 msgid "Extracting the Prometheus role out of this Matrix playbook required huge internal refactoring to the way the Prometheus configuration (scraping jobs) is generated. If you notice any breakage after upgrading, let us know." msgstr "" -#: ../../../CHANGELOG.md:1438 +#: ../../../CHANGELOG.md:2045 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're using Prometheus or not." msgstr "" -#: ../../../CHANGELOG.md:1440 +#: ../../../CHANGELOG.md:2047 msgid "If you're making use of Prometheus via this playbook, you will need to update variable references in your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:1442 +#: ../../../CHANGELOG.md:2049 msgid "`matrix_prometheus_docker_image_` -> `matrix_prometheus_container_image_`" msgstr "" -#: ../../../CHANGELOG.md:1443 +#: ../../../CHANGELOG.md:2050 msgid "`matrix_prometheus_` -> `prometheus_`" msgstr "" -#: ../../../CHANGELOG.md:1447 +#: ../../../CHANGELOG.md:2054 msgid "2023-03-12" msgstr "" -#: ../../../CHANGELOG.md:1449 +#: ../../../CHANGELOG.md:2056 msgid "synapse-auto-compressor support" msgstr "" -#: ../../../CHANGELOG.md:1451 +#: ../../../CHANGELOG.md:2058 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up [rust-synapse-compress-state](https://github.com/matrix-org/rust-synapse-compress-state)'s `synapse_auto_compressor` tool to run periodically." msgstr "" -#: ../../../CHANGELOG.md:1453 +#: ../../../CHANGELOG.md:2060 msgid "If enabled, `synapse_auto_compressor` runs on a schedule and compresses your Synapse database's `state_groups` table. It was possible to run `rust-synapse-compress-state` manually via the playbook even before — see [Compressing state with rust-synapse-compress-state](docs/maintenance-synapse.md#compressing-state-with-rust-synapse-compress-state). However, using `synapse_auto_compressor` is better, because:" msgstr "" -#: ../../../CHANGELOG.md:1455 +#: ../../../CHANGELOG.md:2062 msgid "it runs on a more up-to-date version of `rust-synapse-compress-state`" msgstr "" -#: ../../../CHANGELOG.md:1456 +#: ../../../CHANGELOG.md:2063 msgid "it's a set-it-and-forget-it tool that you can enable and never have to deal with manual compression anymore" msgstr "" -#: ../../../CHANGELOG.md:1458 +#: ../../../CHANGELOG.md:2065 msgid "This tool needs to be enabled manually, for now. In the future, we're considering enabling it by default for all Synapse installations." msgstr "" -#: ../../../CHANGELOG.md:1460 +#: ../../../CHANGELOG.md:2067 msgid "See our [Setting up synapse-auto-compressor](docs/configuring-playbook-synapse-auto-compressor.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1463 +#: ../../../CHANGELOG.md:2070 msgid "2023-03-07" msgstr "" -#: ../../../CHANGELOG.md:1465 +#: ../../../CHANGELOG.md:2072 msgid "Sliding Sync proxy (Element X) support" msgstr "" -#: ../../../CHANGELOG.md:1467 +#: ../../../CHANGELOG.md:2074 msgid "Thanks to [Benjamin Kampmann](https://github.com/gnunicorn) for [getting it started](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2515), [FSG-Cat](https://github.com/FSG-Cat) for fixing it up and me ([Slavi](https://github.com/spantaleev)) for polishing it up, the playbook can now install and configure the [sliding-sync proxy](https://github.com/matrix-org/sliding-sync)." msgstr "" -#: ../../../CHANGELOG.md:1469 +#: ../../../CHANGELOG.md:2076 msgid "The upcoming Element X clients ([Element X iOS](https://github.com/vector-im/element-x-ios) and [Element X Android](https://github.com/vector-im/element-x-android)) require the `sliding-sync` proxy to do their job. **These clients are still in beta** (especially Element X Android, which requires manual compilation to get it working with a non-`matrix.org` homeseserver). Playbook users can now easily give these clients a try and help test them thanks to us having `sliding-sync` support." msgstr "" -#: ../../../CHANGELOG.md:1471 +#: ../../../CHANGELOG.md:2078 msgid "To get started, see our [Setting up the Sliding Sync proxy](docs/configuring-playbook-sliding-sync-proxy.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:1474 +#: ../../../CHANGELOG.md:2081 msgid "2023-03-02" msgstr "" -#: ../../../CHANGELOG.md:1476 +#: ../../../CHANGELOG.md:2083 msgid "The matrix-etherpad role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1478 +#: ../../../CHANGELOG.md:2085 msgid "**TLDR**: the `matrix-etherpad` role is now included from [another repository](https://github.com/mother-of-all-self-hosting/ansible-role-etherpad). Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1480 +#: ../../../CHANGELOG.md:2087 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're using Etherpad or not." msgstr "" -#: ../../../CHANGELOG.md:1482 +#: ../../../CHANGELOG.md:2089 msgid "If you're making use of Etherpad via this playbook, you will need to update variable references in your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:1484 +#: ../../../CHANGELOG.md:2091 msgid "Rename `matrix_etherpad_public_endpoint` to `etherpad_path_prefix`" msgstr "" -#: ../../../CHANGELOG.md:1486 +#: ../../../CHANGELOG.md:2093 msgid "Replace `matrix_etherpad_mode: dimension` with:" msgstr "" -#: ../../../CHANGELOG.md:1487 +#: ../../../CHANGELOG.md:2094 msgid "for `matrix-nginx-proxy` users:" msgstr "" -#: ../../../CHANGELOG.md:1488 +#: ../../../CHANGELOG.md:2095 msgid "`etherpad_nginx_proxy_dimension_integration_enabled: true`" msgstr "" -#: ../../../CHANGELOG.md:1489 +#: ../../../CHANGELOG.md:2096 msgid "`etherpad_hostname: \"{{ matrix_server_fqn_dimension }}\"`" msgstr "" -#: ../../../CHANGELOG.md:1490 +#: ../../../CHANGELOG.md:2097 msgid "for Traefik users:" msgstr "" -#: ../../../CHANGELOG.md:1491 +#: ../../../CHANGELOG.md:2098 msgid "define your own `etherpad_hostname` and `etherpad_path_prefix` as you see fit" msgstr "" -#: ../../../CHANGELOG.md:1493 +#: ../../../CHANGELOG.md:2100 msgid "Rename all other variables:" msgstr "" -#: ../../../CHANGELOG.md:1494 +#: ../../../CHANGELOG.md:2101 msgid "`matrix_etherpad_docker_image_` -> `matrix_etherpad_container_image_`" msgstr "" -#: ../../../CHANGELOG.md:1495 +#: ../../../CHANGELOG.md:2102 msgid "`matrix_etherpad_` -> `etherpad_`" msgstr "" -#: ../../../CHANGELOG.md:1497 +#: ../../../CHANGELOG.md:2104 msgid "Along with this relocation, the new role also:" msgstr "" -#: ../../../CHANGELOG.md:1499 +#: ../../../CHANGELOG.md:2106 msgid "supports [self-building](docs/self-building.md), so it should work on `arm32` and `arm64` architectures" msgstr "" -#: ../../../CHANGELOG.md:1500 +#: ../../../CHANGELOG.md:2107 msgid "has native Traefik reverse-proxy support (Etherpad requests no longer go through `matrix-nginx-proxy` when using Traefik)" msgstr "" -#: ../../../CHANGELOG.md:1503 +#: ../../../CHANGELOG.md:2110 msgid "2023-02-26" msgstr "" -#: ../../../CHANGELOG.md:1505 +#: ../../../CHANGELOG.md:2112 msgid "Traefik is the default reverse-proxy now" msgstr "" -#: ../../../CHANGELOG.md:1507 +#: ../../../CHANGELOG.md:2114 msgid "**TLDR**: new installations will now default to Traefik as their reverse-proxy. Existing users need to explicitly choose their reverse-proxy type. [Switching to Traefik](#how-do-i-switch-my-existing-setup-to-traefik) is strongly encouraged. `matrix-nginx-proxy` may break over time and will ultimately be removed." msgstr "" -#: ../../../CHANGELOG.md:1509 +#: ../../../CHANGELOG.md:2116 msgid "As mentioned 2 weeks ago in [(Backward Compatibility) Reverse-proxy configuration changes and initial Traefik support](#backward-compatibility-reverse-proxy-configuration-changes-and-initial-traefik-support), the playbook is moving to Traefik as its default SSL-terminating reverse-proxy." msgstr "" -#: ../../../CHANGELOG.md:1511 +#: ../../../CHANGELOG.md:2118 msgid "Until now, we've been doing the migration gradually and keeping full backward compatibility. New installations were defaulting to `matrix-nginx-proxy` (just like before), while existing installations were allowed to remain on `matrix-nginx-proxy` as well. This makes things very difficult for us, because we need to maintain and think about lots of different setups:" msgstr "" -#: ../../../CHANGELOG.md:1513 +#: ../../../CHANGELOG.md:2120 msgid "Traefik managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:1514 +#: ../../../CHANGELOG.md:2121 msgid "Traefik managed by the user in another way" msgstr "" -#: ../../../CHANGELOG.md:1515 +#: ../../../CHANGELOG.md:2122 msgid "another reverse-proxy on the same host (`127.0.0.1` port exposure)" msgstr "" -#: ../../../CHANGELOG.md:1516 +#: ../../../CHANGELOG.md:2123 msgid "another reverse-proxy on another host (`0.0.0.0` port exposure)" msgstr "" -#: ../../../CHANGELOG.md:1517 +#: ../../../CHANGELOG.md:2124 msgid "`matrix-nginx-proxy` — an `nginx` container managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:1518 +#: ../../../CHANGELOG.md:2125 msgid "`nginx` webserver operated by the user, running without a container on the same server" msgstr "" -#: ../../../CHANGELOG.md:1520 +#: ../../../CHANGELOG.md:2127 msgid "Each change we do and each new feature that comes in needs to support all these different ways of reverse-proxying. Because `matrix-nginx-proxy` was the default and pretty much everyone was (and still is) using it, means that new PRs also come with `matrix-nginx-proxy` as their main focus and Traefik as an afterthought, which means we need to spend hours fixing up Traefik support." msgstr "" -#: ../../../CHANGELOG.md:1522 +#: ../../../CHANGELOG.md:2129 msgid "We can't spend all this time maintaining so many different configurations anymore. Traefik support has been an option for 2 weeks and lots of people have already migrated their server and have tested things out. Traefik is what we use and preferentially test for." msgstr "" -#: ../../../CHANGELOG.md:1524 +#: ../../../CHANGELOG.md:2131 msgid "It's time for the **next step in our migration process** to Traefik and elimination of `matrix-nginx-proxy`:" msgstr "" -#: ../../../CHANGELOG.md:1526 +#: ../../../CHANGELOG.md:2133 msgid "Traefik is now the default reverse-proxy for new installations" msgstr "" -#: ../../../CHANGELOG.md:1527 +#: ../../../CHANGELOG.md:2134 msgid "All existing users need to explicitly choose their reverse-proxy type by defining the `matrix_playbook_reverse_proxy_type` variable in their `vars.yml` configuration file. We strongly encourage existing users to [switch the Traefik](#how-to-switch-an-existing-setup-to-traefik), as the nginx setup is bound to become more and more broken over time until it's ultimately removed" msgstr "" -#: ../../../CHANGELOG.md:1529 +#: ../../../CHANGELOG.md:2136 msgid "How do I switch my existing setup to Traefik?" msgstr "" -#: ../../../CHANGELOG.md:1531 +#: ../../../CHANGELOG.md:2138 msgid "**For users who are on `matrix-nginx-proxy`** (the default reverse-proxy provided by the playbook), switching to Traefik can happen with a simple configuration change. Follow this section from 2 weeks ago: [How do I explicitly switch to Traefik right now?](#how-do-i-explicitly-switch-to-traefik-right-now)." msgstr "" -#: ../../../CHANGELOG.md:1533 +#: ../../../CHANGELOG.md:2140 msgid "If you experience trouble:" msgstr "" -#: ../../../CHANGELOG.md:1535 +#: ../../../CHANGELOG.md:2142 msgid "Follow [How do I remain on matrix-nginx-proxy?](#how-do-i-remain-on-matrix-nginx-proxy) to bring your server back online using the old reverse-proxy" msgstr "" -#: ../../../CHANGELOG.md:1536 +#: ../../../CHANGELOG.md:2143 msgid "Ask for help in our [support channels](README.md#support)" msgstr "" -#: ../../../CHANGELOG.md:1537 +#: ../../../CHANGELOG.md:2144 msgid "Try switching to Traefik again later" msgstr "" -#: ../../../CHANGELOG.md:1539 +#: ../../../CHANGELOG.md:2146 msgid "**For users with a more special reverse-proxying setup** (another nginx server, Apache, Caddy, etc.), the migration may not be so smooth. Follow the [Using your own webserver](docs/configuring-playbook-own-webserver.md) guide. Ideally, your custom reverse-proxy will be configured in such a way that it **fronts the Traefik reverse-proxy** provided by the playbook. Other means of reverse-proxying are more fragile and may be deprecated in the future." msgstr "" -#: ../../../CHANGELOG.md:1541 +#: ../../../CHANGELOG.md:2148 msgid "I already use my own Traefik server. How do I plug that in?" msgstr "" -#: ../../../CHANGELOG.md:1543 +#: ../../../CHANGELOG.md:2150 msgid "See the [Traefik managed by the playbook](docs/configuring-playbook-own-webserver.md#traefik-managed-by-the-playbook) section." msgstr "" -#: ../../../CHANGELOG.md:1545 +#: ../../../CHANGELOG.md:2152 msgid "Why is matrix-nginx-proxy used even after switching to Traefik?" msgstr "" -#: ../../../CHANGELOG.md:1547 +#: ../../../CHANGELOG.md:2154 msgid "This playbook manages many different services. All these services were initially integrated with `matrix-nginx-proxy`." msgstr "" -#: ../../../CHANGELOG.md:1549 +#: ../../../CHANGELOG.md:2156 msgid "While we migrate all these components to have native Traefik support, some still go through nginx internally (Traefik -> local `matrix-nginx-proxy` -> component). As time goes on, internal reliance on `matrix-nginx-proxy` will gradually decrease until it's completely removed." msgstr "" -#: ../../../CHANGELOG.md:1551 +#: ../../../CHANGELOG.md:2158 msgid "How do I remain on matrix-nginx-proxy?" msgstr "" -#: ../../../CHANGELOG.md:1553 +#: ../../../CHANGELOG.md:2160 msgid "Most new work and testing targets Traefik, so remaining on nginx is **not** \"the good old stable\" option, but rather the \"still available, but largely untested and likely to be broken very soon\" option." msgstr "" -#: ../../../CHANGELOG.md:1555 +#: ../../../CHANGELOG.md:2162 msgid "To proceed regardless of this warning, add `matrix_playbook_reverse_proxy_type: playbook-managed-nginx` to your configuration." msgstr "" -#: ../../../CHANGELOG.md:1557 +#: ../../../CHANGELOG.md:2164 msgid "At some point in the **near** future (days, or even weeks at most), we hope to completely get rid of `matrix-nginx-proxy` (or break it enough to make it unusable), so you **will soon be forced to migrate** anyway. Plan your migration accordingly." msgstr "" -#: ../../../CHANGELOG.md:1559 +#: ../../../CHANGELOG.md:2166 msgid "How do I keep using my own other reverse-proxy?" msgstr "" -#: ../../../CHANGELOG.md:1561 +#: ../../../CHANGELOG.md:2168 msgid "We recommend that you follow the guide for [Fronting the integrated reverse-proxy webserver with another reverse-proxy](docs/configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy)." msgstr "" -#: ../../../CHANGELOG.md:1564 +#: ../../../CHANGELOG.md:2171 msgid "2023-02-25" msgstr "" -#: ../../../CHANGELOG.md:1566 +#: ../../../CHANGELOG.md:2173 msgid "rageshake support" msgstr "" -#: ../../../CHANGELOG.md:1568 +#: ../../../CHANGELOG.md:2175 msgid "Thanks to [Benjamin Kampmann](https://github.com/gnunicorn), the playbook can now install and configure the [rageshake](https://github.com/matrix-org/rageshake) bug report server." msgstr "" -#: ../../../CHANGELOG.md:1570 +#: ../../../CHANGELOG.md:2177 msgid "Additional details are available in [Setting up rageshake](docs/configuring-playbook-rageshake.md)." msgstr "" -#: ../../../CHANGELOG.md:1573 +#: ../../../CHANGELOG.md:2180 msgid "2023-02-17" msgstr "" -#: ../../../CHANGELOG.md:1575 +#: ../../../CHANGELOG.md:2182 msgid "Synapse templates customization support" msgstr "" -#: ../../../CHANGELOG.md:1577 +#: ../../../CHANGELOG.md:2184 msgid "The playbook can now help you customize Synapse's templates." msgstr "" -#: ../../../CHANGELOG.md:1579 +#: ../../../CHANGELOG.md:2186 msgid "Additional details are available in the [Customizing templates](docs/configuring-playbook-synapse.md#customizing-templates) section of our Synapse documentation." msgstr "" -#: ../../../CHANGELOG.md:1581 +#: ../../../CHANGELOG.md:2188 msgid "The matrix-redis role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1583 +#: ../../../CHANGELOG.md:2190 msgid "**TLDR**: the `matrix-redis` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1585 +#: ../../../CHANGELOG.md:2192 msgid "The `matrix-redis` role (which configures [Redis](https://redis.io/)) has been extracted from the playbook and now lives in its [own repository](https://github.com/mother-of-all-self-hosting/ansible-role-redis). This makes it possible to easily use it in other Ansible playbooks." msgstr "" -#: ../../../CHANGELOG.md:1587 +#: ../../../CHANGELOG.md:2194 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're enabling Ntfy or not. If you're making use of Ntfy via this playbook, you will need to update variable references in your `vars.yml` file (`matrix_redis_` -> `redis_`)." msgstr "" -#: ../../../CHANGELOG.md:1589 +#: ../../../CHANGELOG.md:2196 msgid "The matrix-ntfy role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1591 +#: ../../../CHANGELOG.md:2198 msgid "**TLDR**: the `matrix-ntfy` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1593 +#: ../../../CHANGELOG.md:2200 msgid "The `matrix-ntfy` role (which configures [Ntfy](https://ntfy.sh/)) has been extracted from the playbook and now lives in its [own repository](https://github.com/mother-of-all-self-hosting/ansible-role-ntfy). This makes it possible to easily use it in other Ansible playbooks." msgstr "" -#: ../../../CHANGELOG.md:1595 +#: ../../../CHANGELOG.md:2202 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're enabling Ntfy or not. If you're making use of Ntfy via this playbook, you will need to update variable references in your `vars.yml` file (`matrix_ntfy_` -> `ntfy_`)." msgstr "" -#: ../../../CHANGELOG.md:1598 +#: ../../../CHANGELOG.md:2205 msgid "2023-02-15" msgstr "" -#: ../../../CHANGELOG.md:1600 +#: ../../../CHANGELOG.md:2207 msgid "The matrix-grafana role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1602 +#: ../../../CHANGELOG.md:2209 msgid "**TLDR**: the `matrix-grafana` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1604 +#: ../../../CHANGELOG.md:2211 msgid "The `matrix-grafana` role (which configures [Grafana](docs/configuring-playbook-prometheus-grafana.md)) has been extracted from the playbook and now lives in its [own repository](https://github.com/mother-of-all-self-hosting/ansible-role-grafana). This makes it possible to easily use it in other Ansible playbooks." msgstr "" -#: ../../../CHANGELOG.md:1606 +#: ../../../CHANGELOG.md:2213 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're enabling Grafana or not. If you're making use of Grafana via this playbook, you will need to update variable references in your `vars.yml` file (`matrix_grafana_` -> `grafana_`)." msgstr "" -#: ../../../CHANGELOG.md:1609 +#: ../../../CHANGELOG.md:2216 msgid "2023-02-13" msgstr "" -#: ../../../CHANGELOG.md:1611 +#: ../../../CHANGELOG.md:2218 msgid "The matrix-backup-borg role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1613 +#: ../../../CHANGELOG.md:2220 msgid "**TLDR**: the `matrix-backup-borg` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1615 +#: ../../../CHANGELOG.md:2222 msgid "Thanks to [moan0s](https://github.com/moan0s), the `matrix-backup-borg` role (which configures [BorgBackup](docs/configuring-playbook-backup-borg.md)) has been extracted from the playbook and now lives in its [own repository](https://github.com/mother-of-all-self-hosting/ansible-role-backup_borg). This makes it possible to easily use it in other Ansible playbooks and will become part of [nextcloud-docker-ansible-deploy](https://github.com/spantaleev/nextcloud-docker-ansible-deploy) soon." msgstr "" -#: ../../../CHANGELOG.md:1617 +#: ../../../CHANGELOG.md:2224 msgid "You need to **update your roles** (`just roles` or `make roles`) regardless of whether you're enabling Borg's backup functionality or not. If you're making use of BorgBackup via this playbook, you will need to update variable references in your `vars.yml` file (`matrix_backup_borg_` -> `backup_borg_`)." msgstr "" -#: ../../../CHANGELOG.md:1620 +#: ../../../CHANGELOG.md:2227 msgid "2023-02-12" msgstr "" -#: ../../../CHANGELOG.md:1622 +#: ../../../CHANGELOG.md:2229 msgid "(Backward Compatibility) Reverse-proxy configuration changes and initial Traefik support" msgstr "" -#: ../../../CHANGELOG.md:1624 +#: ../../../CHANGELOG.md:2231 msgid "**TLDR**:" msgstr "" -#: ../../../CHANGELOG.md:1626 +#: ../../../CHANGELOG.md:2233 msgid "there's a new `matrix_playbook_reverse_proxy_type` variable (see [roles/custom/matrix-base/defaults/main.yml](roles/custom/matrix-base/defaults/main.yml)), which lets you tell the playbook what reverse-proxy setup you'd like to have. This makes it easier for people who want to do reverse-proxying in other ways." msgstr "" -#: ../../../CHANGELOG.md:1627 +#: ../../../CHANGELOG.md:2234 msgid "the default reverse-proxy (`matrix_playbook_reverse_proxy_type`) is still `playbook-managed-nginx` (via `matrix-nginx-proxy`), for now. **Existing `matrix-nginx-proxy` users should not observe any changes** and can stay on this for now." msgstr "" -#: ../../../CHANGELOG.md:1628 +#: ../../../CHANGELOG.md:2235 msgid "**Users who use their [own other webserver](docs/configuring-playbook-own-webserver.md) (e.g. Apache, etc.) need to change** `matrix_playbook_reverse_proxy_type` to something like `other-on-same-host`, `other-on-another-host` or `other-nginx-non-container`" msgstr "" -#: ../../../CHANGELOG.md:1629 +#: ../../../CHANGELOG.md:2236 msgid "we now have **optional [Traefik](https://traefik.io/) support**, so you could easily host Matrix and other Traefik-native services in containers on the same server. Traefik support is still experimental (albeit, good enough) and will improve over time. It does work, but certain esoteric features may not be there yet." msgstr "" -#: ../../../CHANGELOG.md:1630 +#: ../../../CHANGELOG.md:2237 msgid "**Traefik will become the default reverse-proxy in the near future**. `matrix-nginx-proxy` will either remain as an option, or be completely removed to simplify the playbook" msgstr "" -#: ../../../CHANGELOG.md:1632 +#: ../../../CHANGELOG.md:2239 msgid "Motivation for redoing our reverse-proxy setup" msgstr "" -#: ../../../CHANGELOG.md:1634 +#: ../../../CHANGELOG.md:2241 msgid "The playbook has supported various reverse-proxy setups for a long time. We have various configuration variables (`matrix_nginx_proxy_enabled`, various `_host_bind_port` variables, etc.) which allow the playbook to adapt to these different setups. The whole situation was messy though — hard to figure out and with lots of variables to toggle to make things work as you'd expect — huge **operational complexity**." msgstr "" -#: ../../../CHANGELOG.md:1636 +#: ../../../CHANGELOG.md:2243 msgid "We love containers, proven by the fact that **everything** that this playbook manages runs in a container. Yet, we weren't allowing people to easily host other web-exposed containers alongside Matrix services on the same server. We were using `matrix-nginx-proxy` (our integrated [nginx](https://nginx.org/) server), which was handling web-exposure and SSL termination for our own services, but we **weren't helping you with all your other containers**." msgstr "" -#: ../../../CHANGELOG.md:1638 +#: ../../../CHANGELOG.md:2245 msgid "People who were **using `matrix-nginx-proxy`** were on the happy path on which everything worked well by default (Matrix-wise), **but** could not easily run other web-exposed services on their Matrix server because `matrix-nginx-proxy` was occupying ports `80` and `443`. Other services which wanted to get web exposure either had to be plugged into `matrix-nginx-proxy` (somewhat difficult) or people had to forgo using `matrix-nginx-proxy` in favor of something else." msgstr "" -#: ../../../CHANGELOG.md:1640 +#: ../../../CHANGELOG.md:2247 msgid "Of those that decided to forgo `matrix-nginx-proxy`, many were **using nginx** on the same server without a container. This was likely some ancient nginx version, depending on your choice of distro. The Matrix playbook was trying to be helpful and even with `matrix_nginx_proxy_enabled: false` was still generating nginx configuration in `/matrix/nginx-proxy/conf.d`. Those configuration files were adapted for inclusion into an nginx server running locally. Disabling the `matrix-nginx-proxy` role like this, yet still having it produce files is a bit disgusting, but it's what we've had since the early beginnings of this playbook." msgstr "" -#: ../../../CHANGELOG.md:1642 +#: ../../../CHANGELOG.md:2249 msgid "Others still, wanted to run Matrix locally (no SSL certificates), regardless of which web server technology this relied on, and then **reverse-proxy from another machine on the network** which was doing SSL termination. These people were:" msgstr "" -#: ../../../CHANGELOG.md:1644 +#: ../../../CHANGELOG.md:2251 msgid "*either* relying on `matrix_nginx_proxy_enabled: false` as well, combined with exposing services manually (setting `_bind_port` variables)" msgstr "" -#: ../../../CHANGELOG.md:1645 +#: ../../../CHANGELOG.md:2252 msgid "*or* better yet, they were keeping `matrix-nginx-proxy` enabled, but in `http`-only mode (no SSL certificate retrieval)." msgstr "" -#: ../../../CHANGELOG.md:1647 +#: ../../../CHANGELOG.md:2254 msgid "Despite this operational complexity, things worked and were reasonably flexible to adapt to all these situations." msgstr "" -#: ../../../CHANGELOG.md:1649 +#: ../../../CHANGELOG.md:2256 msgid "When using `matrix-nginx-proxy` as is, we still had another problem — one of **internal playbook complexity**. Too many services need to be web-exposed (port 80/443, SSL certificates). Because of this, they all had to integrate with the `matrix-nginx-proxy` role. Tens of different roles explicitly integrating with `matrix-nginx-proxy` is not what we call clean. The `matrix-nginx-proxy` role contains variables for many of these roles (yikes). Other roles were more decoupled from it and were injecting configuration into `matrix-nginx-proxy` at runtime — see all the `inject_into_nginx_proxy.yml` task files in this playbook (more decoupled, but still… yikes)." msgstr "" -#: ../../../CHANGELOG.md:1651 +#: ../../../CHANGELOG.md:2258 msgid "The next problem is one of **efficiency, interoperability and cost-saving**. We're working on other playbooks:" msgstr "" -#: ../../../CHANGELOG.md:1653 +#: ../../../CHANGELOG.md:2260 msgid "[vaultwarden-docker-ansible-deploy](https://github.com/spantaleev/vaultwarden-docker-ansible-deploy) for hosting the [Vaultwarden](https://github.com/dani-garcia/vaultwarden) server — an alternative implementation of the [Bitwarden](https://bitwarden.com/) password manager" msgstr "" -#: ../../../CHANGELOG.md:1654 +#: ../../../CHANGELOG.md:2261 msgid "[gitea-docker-ansible-deploy](https://github.com/spantaleev/gitea-docker-ansible-deploy) — for hosting the [Gitea](https://gitea.io/) git source code hosting service" msgstr "" -#: ../../../CHANGELOG.md:1655 +#: ../../../CHANGELOG.md:2262 msgid "[nextcloud-docker-ansible-deploy](https://github.com/spantaleev/nextcloud-docker-ansible-deploy) — for hosting the [Nextcloud](https://nextcloud.com/) groupware platform" msgstr "" -#: ../../../CHANGELOG.md:1657 +#: ../../../CHANGELOG.md:2264 msgid "We'd love for users to be able to **seamlessly use all these playbooks (and others, even) against a single server**. We don't want `matrix-nginx-proxy` to have a monopoly on port `80`/`443` and make it hard for other services to join in on the party. Such a thing forces people into running multiple servers (one for each service), which does provide nice security benefits, but is costly and ineffiecient. We'd like to make self-hosting these services cheap and easy." msgstr "" -#: ../../../CHANGELOG.md:1659 +#: ../../../CHANGELOG.md:2266 msgid "These other playbooks have been using [Traefik](https://traefik.io/) as their default reverse-proxy for a long time. They can all coexist nicely together (as an example, see the [Interoperability](https://github.com/spantaleev/nextcloud-docker-ansible-deploy/blob/master/docs/configuring-playbook-interoperability.md) documentation for the [Nextcloud playbook](https://github.com/spantaleev/nextcloud-docker-ansible-deploy)). Now that this playbook is gaining Traefik support, it will be able to interoperate with them. If you're going this way, make sure to have the Matrix playbook install Traefik and have the others use `*_reverse_proxy_type: other-traefik-container`." msgstr "" -#: ../../../CHANGELOG.md:1661 +#: ../../../CHANGELOG.md:2268 msgid "Finally, at [etke.cc — a managed Matrix server hosting service](https://etke.cc) (built on top of this playbook, and coincidentally [turning 2 years old today](https://etke.cc/news/upsyw4ykbtgmwhz8k7ukldx0zbbfq-fh0iqi3llixi0/) 🎉), we're allowing people to host some additional services besides Matrix components. Exposing these services to the web requires ugly hacks and configuration files being dropped into `/matrix/nginx-proxy/conf.d`. We believe that everything should run in independent containers and be exposed to the web via a Traefik server, without a huge Ansible role like `matrix-nginx-proxy` that everything else needs to integrate with." msgstr "" -#: ../../../CHANGELOG.md:1663 +#: ../../../CHANGELOG.md:2270 msgid "How do these changes fix all these problems?" msgstr "" -#: ../../../CHANGELOG.md:1665 +#: ../../../CHANGELOG.md:2272 msgid "The new `matrix_playbook_reverse_proxy_type` lets you easily specify your preferred reverse-proxy type, including `other-on-same-host`, `other-on-another-host` and `none`, so people who'd like to reverse-proxy with their own web server have more options now." msgstr "" -#: ../../../CHANGELOG.md:1667 +#: ../../../CHANGELOG.md:2274 msgid "Using Traefik greatly simplifies things, so going forward we'll have a simpler and easier to maintain playbook, which is also interoperable with other services." msgstr "" -#: ../../../CHANGELOG.md:1669 +#: ../../../CHANGELOG.md:2276 msgid "Traefik is a web server, which has been specifically **designed for reverse-proxying to services running in containers**. It's ideal for usage in an Ansible playbook which runs everything in containers." msgstr "" -#: ../../../CHANGELOG.md:1671 +#: ../../../CHANGELOG.md:2278 msgid "**Traefik obtains SSL certificates automatically**, so there's no need for plugging additional tools like [Certbot](https://certbot.eff.org/) into your web server (like we were doing in the `matrix-nginx-proxy` role). No more certificate renewal timers, web server reloading timers, etc. It's just simpler." msgstr "" -#: ../../../CHANGELOG.md:1673 +#: ../../../CHANGELOG.md:2280 msgid "Traefik is a **modern web server**. [HTTP/3](https://doc.traefik.io/traefik/routing/entrypoints/#http3) is supported already (experimentally) and will move to stable soon, in the upcoming Traefik v3 release." msgstr "" -#: ../../../CHANGELOG.md:1675 +#: ../../../CHANGELOG.md:2282 msgid "Traefik does not lock important functionality we'd like to use into [plus packages like nginx does](https://www.nginx.com/products/nginx/), leading us to resolve to configuration workarounds. The default Traefik package is good enough as it is." msgstr "" -#: ../../../CHANGELOG.md:1677 +#: ../../../CHANGELOG.md:2284 msgid "Where we're at right now?" msgstr "" -#: ../../../CHANGELOG.md:1679 +#: ../../../CHANGELOG.md:2286 msgid "`matrix_playbook_reverse_proxy_type` still defaults to a value of `playbook-managed-nginx`." msgstr "" -#: ../../../CHANGELOG.md:1681 +#: ../../../CHANGELOG.md:2288 msgid "Unless we have some regression, **existing `matrix-nginx-proxy` users should be able to update their Matrix server and not observe any changes**. Their setup should still remain on nginx and everything should still work as expected." msgstr "" -#: ../../../CHANGELOG.md:1683 +#: ../../../CHANGELOG.md:2290 msgid "**Users using [their own webservers](docs/configuring-playbook-own-webserver.md) will need to change `matrix_playbook_reverse_proxy_type`** to something like `other-on-same-host`, `other-on-another-host` or `other-nginx-non-container`. Previously, they could toggle `matrix_nginx_proxy_enabled` to `false`, and that made the playbook automatically expose services locally. Currently, we only do this if you change the reverse-proxy type to `other-on-same-host`, `other-on-another-host` or `other-nginx-non-container`." msgstr "" -#: ../../../CHANGELOG.md:1685 +#: ../../../CHANGELOG.md:2292 msgid "How do I explicitly switch to Traefik right now?" msgstr "" -#: ../../../CHANGELOG.md:1687 +#: ../../../CHANGELOG.md:2294 msgid "**Users who wish to migrate to Traefik** today, can do so by **adding** this to their configuration:" msgstr "" -#: ../../../CHANGELOG.md:1693 +#: ../../../CHANGELOG.md:2300 msgid "You may still need to keep certain old `matrix_nginx_proxy_*` variables (like `matrix_nginx_proxy_base_domain_serving_enabled`), even when using Traefik. For now, we recommend keeping all `matrix_nginx_proxy_*` variables just in case. In the future, reliance on `matrix-nginx-proxy` will be removed." msgstr "" -#: ../../../CHANGELOG.md:1695 +#: ../../../CHANGELOG.md:2302 msgid "Switching to Traefik will obtain new SSL certificates from Let's Encrypt (stored in `/matrix/traefik/ssl/acme.json`). **The switch is reversible**. You can always go back to `playbook-managed-nginx` if Traefik is causing you trouble." msgstr "" -#: ../../../CHANGELOG.md:1697 +#: ../../../CHANGELOG.md:2304 msgid "**Note**: toggling `matrix_playbook_reverse_proxy_type` between Traefik and nginx will uninstall the Traefik role and all of its data (under `/matrix/traefik`), so you may run into a Let's Encrypt rate limit if you do it often." msgstr "" -#: ../../../CHANGELOG.md:1699 +#: ../../../CHANGELOG.md:2306 msgid "Treafik directly reverse-proxies to **some** services right now, but for most other services it goes through `matrix-nginx-proxy` (e.g. Traefik -> `matrix-nginx-proxy` -> [Ntfy](docs/configuring-playbook-ntfy.md)). So, even if you opt into Traefik, you'll still see `matrix-nginx-proxy` being installed in local-only mode. This will improve with time." msgstr "" -#: ../../../CHANGELOG.md:1701 +#: ../../../CHANGELOG.md:2308 msgid "Some services (like [coturn](docs/configuring-playbook-turn.md) and [Postmoogle](docs/configuring-playbook-bridge-postmoogle.md)) cannot be reverse-proxied to directly from Traefik, so they require direct access to SSL certificate files extracted out of Traefik. The playbook does this automatically thanks to a new [com.devture.ansible.role.traefik_certs_dumper](https://github.com/devture/com.devture.ansible.role.traefik_certs_dumper) role utilizing the [traefik-certs-dumper](https://github.com/ldez/traefik-certs-dumper) tool." msgstr "" -#: ../../../CHANGELOG.md:1703 +#: ../../../CHANGELOG.md:2310 msgid "Our Traefik setup mostly works, but certain esoteric features may not work. If you have a default setup, we expect you to have a good experience." msgstr "" -#: ../../../CHANGELOG.md:1705 +#: ../../../CHANGELOG.md:2312 msgid "Where we're going in the near future?" msgstr "" -#: ../../../CHANGELOG.md:1707 +#: ../../../CHANGELOG.md:2314 msgid "The `matrix-nginx-proxy` role is quite messy. It manages both nginx and Certbot and its certificate renewal scripts and timers. It generates configuration even when the role is disabled (weird). Although it doesn't directly reach into variables from other roles, it has explicit awareness of various other services that it reverse-proxies to (`roles/custom/matrix-nginx-proxy/templates/nginx/conf.d/matrix-ntfy.conf.j2`, etc.). We'd like to clean this up. The only way is probably to just get rid of the whole thing at some point." msgstr "" -#: ../../../CHANGELOG.md:1709 +#: ../../../CHANGELOG.md:2316 msgid "For now, `matrix-nginx-proxy` will stay around." msgstr "" -#: ../../../CHANGELOG.md:1711 +#: ../../../CHANGELOG.md:2318 msgid "As mentioned above, Traefik still reverse-proxies to some (most) services by going through a local-only `matrix-nginx-proxy` server. This has allowed us to add Traefik support to the playbook early on (without having to rework all services), but is not the final goal. We'll **work on making each service support Traefik natively**, so that traffic will not need to go through `matrix-nginx-proxy` anymore. In the end, choosing Traefik should only give you a pure Traefik installation with no `matrix-nginx-proxy` in sight." msgstr "" -#: ../../../CHANGELOG.md:1713 +#: ../../../CHANGELOG.md:2320 msgid "As Traefik support becomes complete and proves to be stable for a while, especially as a playbook default, we will **most likely remove `matrix-nginx-proxy` completely**. It will likely be some months before this happens though. Keeping support for both Traefik and nginx in the playbook will be a burden, especially with most of us running Traefik in the future. The Traefik role should do everything nginx does in a better and cleaner way. Users who use their own `nginx` server on the Matrix server will be inconvenienced, as nothing will generate ready-to-include nginx configuration for them. Still, we hope it won't be too hard to migrate their setup to another way of doing things, like:" msgstr "" -#: ../../../CHANGELOG.md:1715 +#: ../../../CHANGELOG.md:2322 msgid "not using nginx anymore. A common reason for using nginx until now was that you were running other containers and you need your own nginx to reverse-proxy to all of them. Just switch them to Traefik as well." msgstr "" -#: ../../../CHANGELOG.md:1716 +#: ../../../CHANGELOG.md:2323 msgid "running Traefik in local-only mode (`traefik_config_entrypoint_web_secure_enabled: false`) and using some nginx configuration which reverse-proxies to Traefik (we should introduce examples for this in `examples/nginx`)." msgstr "" -#: ../../../CHANGELOG.md:1718 +#: ../../../CHANGELOG.md:2325 msgid "How do I help?" msgstr "" -#: ../../../CHANGELOG.md:1720 +#: ../../../CHANGELOG.md:2327 msgid "You can help by:" msgstr "" -#: ../../../CHANGELOG.md:1722 +#: ../../../CHANGELOG.md:2329 msgid "**explicitly switching your server to Traefik** right now (see example configuration in [How do I explicitly switch to Traefik right now?](#how-do-i-explicitly-switch-to-traefik-right-now) above), testing, reporting troubles" msgstr "" -#: ../../../CHANGELOG.md:1724 +#: ../../../CHANGELOG.md:2331 msgid "**adding native Traefik support to a role** (requires adding Traefik labels, etc.) — for inspiration, see these roles ([prometheus_node_exporter](https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-node-exporter), [prometheus_postgres_exporter](https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-postgres-exporter)) and how they're hooked into the playbook via [group_vars/matrix_servers](group_vars/matrix_servers)." msgstr "" -#: ../../../CHANGELOG.md:1726 +#: ../../../CHANGELOG.md:2333 msgid "**adding reverse-proxying examples for nginx users** in `examples/nginx`. People who insist on using their own `nginx` server on the same Matrix host, can run Traefik in local-only mode (`traefik_config_entrypoint_web_secure_enabled: false`) and reverse-proxy to the Traefik server" msgstr "" -#: ../../../CHANGELOG.md:1729 +#: ../../../CHANGELOG.md:2336 msgid "2023-02-10" msgstr "" -#: ../../../CHANGELOG.md:1731 +#: ../../../CHANGELOG.md:2338 msgid "Matrix Authentication Support for Jitsi" msgstr "" -#: ../../../CHANGELOG.md:1733 +#: ../../../CHANGELOG.md:2340 msgid "Thanks to [Jakob S.](https://github.com/jakicoll) ([zakk gGmbH](https://github.com/zakk-it)), Jitsi can now use Matrix for authentication (via [Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service))." msgstr "" -#: ../../../CHANGELOG.md:1735 +#: ../../../CHANGELOG.md:2342 msgid "Additional details are available in the [Authenticate using Matrix OpenID (Auth-Type 'matrix')](docs/configuring-playbook-jitsi.md#authenticate-using-matrix-openid-auth-type-matrix)." msgstr "" -#: ../../../CHANGELOG.md:1737 +#: ../../../CHANGELOG.md:2344 msgid "Draupnir moderation tool (bot) support" msgstr "" -#: ../../../CHANGELOG.md:1739 +#: ../../../CHANGELOG.md:2346 msgid "Thanks to [FSG-Cat](https://github.com/FSG-Cat), the playbook can now install and configure the [Draupnir](https://github.com/the-draupnir-project/Draupnir) moderation tool (bot). Draupnir is a fork of [Mjolnir](docs/configuring-playbook-bot-mjolnir.md) (which the playbook has supported for a long time) maintained by Mjolnir's former lead developer." msgstr "" -#: ../../../CHANGELOG.md:1741 +#: ../../../CHANGELOG.md:2348 msgid "Additional details are available in [Setting up Draupnir](docs/configuring-playbook-bot-draupnir.md)." msgstr "" -#: ../../../CHANGELOG.md:1744 +#: ../../../CHANGELOG.md:2351 msgid "2023-02-05" msgstr "" -#: ../../../CHANGELOG.md:1746 +#: ../../../CHANGELOG.md:2353 msgid "The matrix-prometheus-postgres-exporter role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1748 +#: ../../../CHANGELOG.md:2355 msgid "**TLDR**: the `matrix-prometheus-postgres-exporter` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1750 +#: ../../../CHANGELOG.md:2357 msgid "The `matrix-prometheus-postgres-exporter` role (which configures [Prometheus Postgres Exporter](https://github.com/prometheus-community/postgres_exporter)) has been extracted from the playbook and now lives in its own repository at https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-postgres-exporter" msgstr "" -#: ../../../CHANGELOG.md:1752 +#: ../../../CHANGELOG.md:2359 msgid "It's still part of the playbook, but is now installed via `ansible-galaxy` (by running `just roles` / `make roles`). Some variables have been renamed (`matrix_prometheus_postgres_exporter_` -> `prometheus_postgres_exporter_`, etc.). The playbook will report all variables that you need to rename to get upgraded. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1754 +#: ../../../CHANGELOG.md:2361 msgid "The `matrix-prometheus-services-proxy-connect` role has bee adjusted to help integrate the new `prometheus_postgres_exporter` role with our own services (`matrix-nginx-proxy`)" msgstr "" -#: ../../../CHANGELOG.md:1756 -#: ../../../CHANGELOG.md:1798 +#: ../../../CHANGELOG.md:2363 +#: ../../../CHANGELOG.md:2405 msgid "Other roles which aren't strictly related to Matrix are likely to follow this fate of moving to their own repositories. Extracting them out allows other Ansible playbooks to make use of these roles easily." msgstr "" -#: ../../../CHANGELOG.md:1759 +#: ../../../CHANGELOG.md:2366 msgid "2023-01-26" msgstr "" -#: ../../../CHANGELOG.md:1761 +#: ../../../CHANGELOG.md:2368 msgid "coturn can now use host-networking" msgstr "" -#: ../../../CHANGELOG.md:1763 +#: ../../../CHANGELOG.md:2370 msgid "Large coturn deployments (with a huge range of ports specified via `coturn_turn_udp_min_port` and `coturn_turn_udp_max_port`) experience a huge slowdown with how Docker publishes all these ports (setting up firewall forwarding rules), which leads to a very slow coturn service startup and shutdown." msgstr "" -#: ../../../CHANGELOG.md:1765 +#: ../../../CHANGELOG.md:2372 msgid "Such deployments don't need to run coturn within a private container network anymore. coturn can now run with host-networking by using configuration like this:" msgstr "" -#: ../../../CHANGELOG.md:1771 +#: ../../../CHANGELOG.md:2378 msgid "With such a configuration, **Docker no longer needs to configure thousands of firewall forwarding rules** each time coturn starts and stops. This, however, means that **you will need to ensure these ports are open** in your firewall yourself." msgstr "" -#: ../../../CHANGELOG.md:1773 +#: ../../../CHANGELOG.md:2380 msgid "Thanks to us [tightening coturn security](#backward-compatibility-tightening-coturn-security-can-lead-to-connectivity-issues), running coturn with host-networking should be safe and not expose neither other services running on the host, nor other services running on the local network." msgstr "" -#: ../../../CHANGELOG.md:1775 +#: ../../../CHANGELOG.md:2382 msgid "(Backward Compatibility) Tightening coturn security can lead to connectivity issues" msgstr "" -#: ../../../CHANGELOG.md:1777 +#: ../../../CHANGELOG.md:2384 msgid "**TLDR**: users who run and access their Matrix server on a private network (likely a small minority of users) may experience connectivity issues with our new default coturn blocklists. They may need to override `coturn_denied_peer_ips` and remove some IP ranges from it." msgstr "" -#: ../../../CHANGELOG.md:1779 +#: ../../../CHANGELOG.md:2386 msgid "Inspired by [this security article](https://www.rtcsec.com/article/cve-2020-26262-bypass-of-coturns-access-control-protection/), we've decided to make use of coturn's `denied-peer-ip` functionality to prevent relaying network traffic to certain private IP subnets. This ensures that your coturn server won't accidentally try to forward traffic to certain services running on your local networks. We run coturn in a container and in a private container network by default, which should prevent such access anyway, but having additional block layers in place is better." msgstr "" -#: ../../../CHANGELOG.md:1781 +#: ../../../CHANGELOG.md:2388 msgid "If you access your Matrix server from a local network and need coturn to relay to private IP addresses, you may observe that relaying is now blocked due to our new default `denied-peer-ip` lists (specified in `coturn_denied_peer_ips`). If you experience such connectivity problems, consider overriding this setting in your `vars.yml` file and removing certain networks from it." msgstr "" -#: ../../../CHANGELOG.md:1783 +#: ../../../CHANGELOG.md:2390 msgid "We've also added `no-multicast-peers` to the default coturn configuration, but we don't expect this to cause trouble for most people." msgstr "" -#: ../../../CHANGELOG.md:1786 +#: ../../../CHANGELOG.md:2393 msgid "2023-01-21" msgstr "" -#: ../../../CHANGELOG.md:1788 +#: ../../../CHANGELOG.md:2395 msgid "The matrix-prometheus-node-exporter role lives independently now" msgstr "" -#: ../../../CHANGELOG.md:1790 +#: ../../../CHANGELOG.md:2397 msgid "**TLDR**: the `matrix-prometheus-node-exporter` role is now included from another repository. Some variables have been renamed. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1792 +#: ../../../CHANGELOG.md:2399 msgid "The `matrix-prometheus-node-exporter` role (which configures [Prometheus node exporter](https://github.com/prometheus/node_exporter)) has been extracted from the playbook and now lives in its own repository at https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-node-exporter" msgstr "" -#: ../../../CHANGELOG.md:1794 +#: ../../../CHANGELOG.md:2401 msgid "It's still part of the playbook, but is now installed via `ansible-galaxy` (by running `just roles` / `make roles`). Some variables have been renamed (`matrix_prometheus_node_exporter_` -> `prometheus_node_exporter_`, etc.). The playbook will report all variables that you need to rename to get upgraded. All functionality remains intact." msgstr "" -#: ../../../CHANGELOG.md:1796 +#: ../../../CHANGELOG.md:2403 msgid "A new `matrix-prometheus-services-proxy-connect` role was added to the playbook to help integrate the new `prometheus_node_exporter` role with our own services (`matrix-nginx-proxy`)" msgstr "" -#: ../../../CHANGELOG.md:1801 +#: ../../../CHANGELOG.md:2408 msgid "2023-01-13" msgstr "" -#: ../../../CHANGELOG.md:1803 +#: ../../../CHANGELOG.md:2410 msgid "Support for running commands via just" msgstr "" -#: ../../../CHANGELOG.md:1805 +#: ../../../CHANGELOG.md:2412 msgid "We've previously used [make](https://www.gnu.org/software/make/) for easily running some playbook commands (e.g. `make roles` which triggers `ansible-galaxy`, see [Makefile](Makefile)). Our `Makefile` is still around and you can still run these commands." msgstr "" -#: ../../../CHANGELOG.md:1807 +#: ../../../CHANGELOG.md:2414 msgid "In addition, we've added support for running commands via [just](https://github.com/casey/just) — a more modern command-runner alternative to `make`. Instead of `make roles`, you can now run `just roles` to accomplish the same." msgstr "" -#: ../../../CHANGELOG.md:1809 +#: ../../../CHANGELOG.md:2416 msgid "Our [justfile](justfile) already defines some additional helpful **shortcut** commands that weren't part of our `Makefile`. Here are some examples:" msgstr "" -#: ../../../CHANGELOG.md:1811 +#: ../../../CHANGELOG.md:2418 msgid "`just install-all` to trigger the much longer `ansible-playbook -i inventory/hosts setup.yml --tags=install-all,ensure-matrix-users-created,start` command" msgstr "" -#: ../../../CHANGELOG.md:1812 +#: ../../../CHANGELOG.md:2419 msgid "`just install-all --ask-vault-pass` — commands also support additional arguments (`--ask-vault-pass` will be appended to the above installation command)" msgstr "" -#: ../../../CHANGELOG.md:1813 +#: ../../../CHANGELOG.md:2420 msgid "`just run-tags install-mautrix-slack,start` — to run specific playbook tags" msgstr "" -#: ../../../CHANGELOG.md:1814 +#: ../../../CHANGELOG.md:2421 msgid "`just start-all` — (re-)starts all services" msgstr "" -#: ../../../CHANGELOG.md:1815 +#: ../../../CHANGELOG.md:2422 msgid "`just stop-group postgres` — to stop only the Postgres service" msgstr "" -#: ../../../CHANGELOG.md:1816 +#: ../../../CHANGELOG.md:2423 msgid "`just register-user alice secret-password yes` — registers an `alice` user with the `secret-password` password and admin access (admin = `yes`)" msgstr "" -#: ../../../CHANGELOG.md:1818 +#: ../../../CHANGELOG.md:2425 msgid "Additional helpful commands and shortcuts may be defined in the future." msgstr "" -#: ../../../CHANGELOG.md:1820 +#: ../../../CHANGELOG.md:2427 msgid "This is all completely optional. If you find it difficult to [install `just`](https://github.com/casey/just#installation) or don't find any of this convenient, feel free to run all commands manually." msgstr "" -#: ../../../CHANGELOG.md:1823 +#: ../../../CHANGELOG.md:2430 msgid "2023-01-11" msgstr "" -#: ../../../CHANGELOG.md:1825 +#: ../../../CHANGELOG.md:2432 msgid "mautrix-slack support" msgstr "" -#: ../../../CHANGELOG.md:1827 +#: ../../../CHANGELOG.md:2434 msgid "Thanks to [Cody Neiman](https://github.com/xangelix)'s efforts, the playbook now supports bridging to [Slack](https://slack.com/) via the [mautrix-slack](https://mau.dev/mautrix/slack) bridge. See our [Setting up Mautrix Slack bridging](docs/configuring-playbook-bridge-mautrix-slack.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:1829 +#: ../../../CHANGELOG.md:2436 msgid "**Note**: this is a new Slack bridge. The playbook still retains Slack bridging via [matrix-appservice-slack](docs/configuring-playbook-bridge-appservice-slack.md) and [mx-puppet-slack](docs/configuring-playbook-bridge-mx-puppet-slack.md). You're free to use the bridge that serves you better, or even all three of them (for different users and use-cases)." msgstr "" -#: ../../../CHANGELOG.md:1832 +#: ../../../CHANGELOG.md:2439 msgid "2023-01-10" msgstr "" -#: ../../../CHANGELOG.md:1834 +#: ../../../CHANGELOG.md:2441 msgid "ChatGPT support" msgstr "" -#: ../../../CHANGELOG.md:1836 +#: ../../../CHANGELOG.md:2443 msgid "Thanks to [@bertybuttface](https://github.com/bertybuttface), the playbook can now help you set up [matrix-chatgpt-bot](https://github.com/matrixgpt/matrix-chatgpt-bot) — a bot through which you can talk to the [ChatGPT](https://openai.com/blog/chatgpt/) model." msgstr "" -#: ../../../CHANGELOG.md:1838 +#: ../../../CHANGELOG.md:2445 msgid "See our [Setting up matrix-bot-chatgpt](docs/configuring-playbook-bot-chatgpt.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:1841 +#: ../../../CHANGELOG.md:2448 msgid "2022-11-30" msgstr "" -#: ../../../CHANGELOG.md:1843 +#: ../../../CHANGELOG.md:2450 msgid "matrix-postgres-backup has been replaced by the ansible-role-postgres-backup external role" msgstr "" -#: ../../../CHANGELOG.md:1845 +#: ../../../CHANGELOG.md:2452 msgid "Just like we've [replaced Postgres with an external role](#matrix-postgres-has-been-replaced-by-the-comdevtureansiblerolepostgres-external-role) on 2022-11-28, we're now replacing `matrix-postgres-backup` with an external role — [com.devture.ansible.role.postgres_backup](https://github.com/mother-of-all-self-hosting/ansible-role-postgres_backup)." msgstr "" -#: ../../../CHANGELOG.md:1847 +#: ../../../CHANGELOG.md:2454 msgid "You'll need to rename your `matrix_postgres_backup`-prefixed variables such that they use a `postgres_backup` prefix." msgstr "" -#: ../../../CHANGELOG.md:1850 +#: ../../../CHANGELOG.md:2457 msgid "2022-11-28" msgstr "" -#: ../../../CHANGELOG.md:1852 +#: ../../../CHANGELOG.md:2459 msgid "matrix-postgres has been replaced by the ansible-role-postgres external role" msgstr "" -#: ../../../CHANGELOG.md:1854 +#: ../../../CHANGELOG.md:2461 msgid "**TLDR**: the tasks that install the integrated Postgres server now live in an external role — [ansible-role-postgres](https://github.com/mother-of-all-self-hosting/ansible-role-postgres). You'll need to run `make roles` to install it, and to also rename your `matrix_postgres`-prefixed variables to use a `devture_postgres` prefix (e.g. `matrix_postgres_connection_password` -> `postgres_connection_password`). All your data will still be there! Some scripts have moved (`/usr/local/bin/matrix-postgres-cli` -> `/matrix/postgres/bin/cli`)." msgstr "" -#: ../../../CHANGELOG.md:1856 +#: ../../../CHANGELOG.md:2463 msgid "The `matrix-postgres` role that has been part of the playbook for a long time has been replaced with the [ansible-role-postgres](https://github.com/mother-of-all-self-hosting/ansible-role-postgres) role. This was done as part of our work to [use external roles for some things](#the-playbook-now-uses-external-roles-for-some-things) for better code re-use and maintainability." msgstr "" -#: ../../../CHANGELOG.md:1858 +#: ../../../CHANGELOG.md:2465 msgid "The new role is an upgraded version of the old `matrix-postgres` role with these notable differences:" msgstr "" -#: ../../../CHANGELOG.md:1860 +#: ../../../CHANGELOG.md:2467 msgid "it uses different names for its variables (`matrix_postgres` -> `devture_postgres`)" msgstr "" -#: ../../../CHANGELOG.md:1861 +#: ../../../CHANGELOG.md:2468 msgid "when [Vacuuming PostgreSQL](docs/maintenance-postgres.md#vacuuming-postgresql), it will vacuum all your databases, not just the Synapse one" msgstr "" -#: ../../../CHANGELOG.md:1863 +#: ../../../CHANGELOG.md:2470 msgid "You'll need to run `make roles` to install the new role. You would also need to rename your `matrix_postgres`-prefixed variables to use a `devture_postgres` prefix." msgstr "" -#: ../../../CHANGELOG.md:1865 +#: ../../../CHANGELOG.md:2472 msgid "Note: the systemd service still remains the same — `matrix-postgres.service`. Your data will still be in `/matrix/postgres`, etc. Postgres-related scripts will be moved to `/matrix/postgres/bin` (`/usr/local/bin/matrix-postgres-cli` -> `/matrix/postgres/bin/cli`, etc). Also see [The playbook no longer installs scripts in /usr/local/bin](#the-playbook-no-longer-installs-scripts-in-usrlocalbin)." msgstr "" -#: ../../../CHANGELOG.md:1867 +#: ../../../CHANGELOG.md:2474 msgid "The playbook no longer installs scripts to /usr/local/bin" msgstr "" -#: ../../../CHANGELOG.md:1869 +#: ../../../CHANGELOG.md:2476 msgid "The locations of various scripts installed by the playbook have changed." msgstr "" -#: ../../../CHANGELOG.md:1871 +#: ../../../CHANGELOG.md:2478 msgid "The playbook no longer contaminates your `/usr/local/bin` directory. All scripts installed by the playbook now live in `bin/` directories under `/matrix`. Some examples are below:" msgstr "" -#: ../../../CHANGELOG.md:1873 +#: ../../../CHANGELOG.md:2480 msgid "`/usr/local/bin/matrix-remove-all` -> `/matrix/bin/remove-all`" msgstr "" -#: ../../../CHANGELOG.md:1874 +#: ../../../CHANGELOG.md:2481 msgid "`/usr/local/bin/matrix-postgres-cli` -> `/matrix/postgres/bin/cli`" msgstr "" -#: ../../../CHANGELOG.md:1875 +#: ../../../CHANGELOG.md:2482 msgid "`/usr/local/bin/matrix-ssl-lets-encrypt-certificates-renew` -> `/matrix/ssl/bin/lets-encrypt-certificates-renew`" msgstr "" -#: ../../../CHANGELOG.md:1876 +#: ../../../CHANGELOG.md:2483 msgid "`/usr/local/bin/matrix-synapse-register-user` -> `/matrix/synapse/bin/register-user`" msgstr "" -#: ../../../CHANGELOG.md:1879 +#: ../../../CHANGELOG.md:2486 msgid "2022-11-25" msgstr "" -#: ../../../CHANGELOG.md:1881 +#: ../../../CHANGELOG.md:2488 msgid "2x-5x performance improvements in playbook runtime" msgstr "" -#: ../../../CHANGELOG.md:1883 +#: ../../../CHANGELOG.md:2490 msgid "**TLDR**: the playbook is 2x faster for running `--tags=setup-all` (and various other tags). It also has new `--tags=install-*` tags (like `--tags=install-all`), which skip uninstallation tasks and bring an additional 2.5x speedup. In total, the playbook can maintain your server 5 times faster." msgstr "" -#: ../../../CHANGELOG.md:1885 +#: ../../../CHANGELOG.md:2492 msgid "Our [etke.cc managed Matrix hosting service](https://etke.cc) runs maintenance against hundreds of servers, so the playbook being fast means a lot. The [etke.cc Ansible playbook](https://github.com/etkecc/ansible) (which is an extension of this one) is growing to support more and more services (besides just Matrix), so the Matrix playbook being leaner prevents runtimes from becoming too slow and improves the customer experience." msgstr "" -#: ../../../CHANGELOG.md:1887 +#: ../../../CHANGELOG.md:2494 msgid "Even when running `ansible-playbook` manually (as most of us here do), it's beneficial not to waste time and CPU resources." msgstr "" -#: ../../../CHANGELOG.md:1889 +#: ../../../CHANGELOG.md:2496 msgid "Recently, a few large optimizations have been done to this playbook and its external roles (see [The playbook now uses external roles for some things](#the-playbook-now-uses-external-roles-for-some-things) and don't forget to run `make roles`):" msgstr "" -#: ../../../CHANGELOG.md:1891 +#: ../../../CHANGELOG.md:2498 msgid "Replacing Ansible `import_tasks` calls with `include_tasks`, which decreased runtime in half. Using `import_tasks` is slower and causes Ansible to go through and skip way too many tasks (tasks which could have been skipped altogether by not having Ansible include them in the first place). On an experimental VM, **deployment time was decreased from ~530 seconds to ~250 seconds**." msgstr "" -#: ../../../CHANGELOG.md:1893 +#: ../../../CHANGELOG.md:2500 msgid "Introducing new `install-*` tags (`install-all` and `install-COMPONENT`, e.g. `install-synapse`, `install-bot-mjolnir`), which only run Ansible tasks pertaining to installation, while skipping uninstallation tasks. In most cases, people are maintaining the same setup or they're *adding* new components. Removing components is rare. Running thousands of uninstallation tasks each time is wasteful. On an experimental VM, **deployment time was decreased from ~250 seconds (`--tags=setup-all`) to ~100 seconds (`--tags=install-all`)**." msgstr "" -#: ../../../CHANGELOG.md:1895 +#: ../../../CHANGELOG.md:2502 msgid "You can still use `--tags=setup-all`. In fact, that's the best way to ensure your server is reconciled with the `vars.yml` configuration." msgstr "" -#: ../../../CHANGELOG.md:1897 +#: ../../../CHANGELOG.md:2504 msgid "If you know you haven't uninstalled any services since the last time you ran the playbook, you could run `--tags=install-all` instead and benefit from quicker runtimes. It should be noted that a service may become \"eligible for uninstallation\" even if your `vars.yml` file remains the same. In rare cases, we toggle services from being auto-installed to being optional, like we did on the 17th of March 2022 when we made [ma1sd not get installed by default](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md#compatibility-break-ma1sd-identity-server-no-longer-installed-by-default). In such rare cases, you'd also need to run `--tags=setup-all`." msgstr "" -#: ../../../CHANGELOG.md:1900 +#: ../../../CHANGELOG.md:2507 msgid "2022-11-22" msgstr "" -#: ../../../CHANGELOG.md:1902 +#: ../../../CHANGELOG.md:2509 msgid "Automatic `matrix_architecture` determination" msgstr "" -#: ../../../CHANGELOG.md:1904 +#: ../../../CHANGELOG.md:2511 msgid "From now on, the playbook automatically determines your server's architecture and sets the `matrix_architecture` variable accordingly. You no longer need to set this variable manually in your `vars.yml` file." msgstr "" -#: ../../../CHANGELOG.md:1906 +#: ../../../CHANGELOG.md:2513 msgid "Docker and the Docker SDK for Python are now installed via external roles" msgstr "" -#: ../../../CHANGELOG.md:1910 +#: ../../../CHANGELOG.md:2517 msgid "Docker will now be installed on the server via the [geerlingguy.docker](https://github.com/geerlingguy/ansible-role-docker) Ansible role. If you'd like to manage the Docker installation yourself, you can disable the playbook's installation of Docker by setting `matrix_playbook_docker_installation_enabled: false`." msgstr "" -#: ../../../CHANGELOG.md:1912 +#: ../../../CHANGELOG.md:2519 msgid "The Docker SDK for Python (named `docker-python`, `python-docker`, etc. on the different platforms) is now also installed by another role ([com.devture.ansible.role.docker_sdk_for_python](https://github.com/devture/com.devture.ansible.role.docker_sdk_for_python)). To disable this role and install the necessary tools yourself, use `devture_docker_sdk_for_python_installation_enabled: false`." msgstr "" -#: ../../../CHANGELOG.md:1914 +#: ../../../CHANGELOG.md:2521 msgid "If you're hitting issues with Docker installation or Docker SDK for Python installation, consider reporting bugs or contributing to these other projects." msgstr "" -#: ../../../CHANGELOG.md:1916 +#: ../../../CHANGELOG.md:2523 msgid "These additional roles are downloaded into the playbook directory (to `roles/galaxy`) via an `ansible-galaxy …` command. `make roles` is an easy shortcut for invoking the `ansible-galaxy` command to download these roles." msgstr "" -#: ../../../CHANGELOG.md:1919 +#: ../../../CHANGELOG.md:2526 msgid "2022-11-20" msgstr "" -#: ../../../CHANGELOG.md:1921 +#: ../../../CHANGELOG.md:2528 msgid "(Backward Compatibility Break) Changing how reverse-proxying to Synapse works — now via a `matrix-synapse-reverse-proxy-companion` service" msgstr "" -#: ../../../CHANGELOG.md:1923 +#: ../../../CHANGELOG.md:2530 msgid "**TLDR**: There's now a `matrix-synapse-reverse-proxy-companion` nginx service, which helps with reverse-proxying to Synapse and its various worker processes (if workers are enabled), so that `matrix-nginx-proxy` can be relieved of this role. `matrix-nginx-proxy` still remains as the public SSL-terminating reverse-proxy in the playbook. `matrix-synapse-reverse-proxy-companion` is just one more reverse-proxy thrown into the mix for convenience. People with a more custom reverse-proxying configuration may be affected — see [Webserver configuration](#webserver-configuration) below." msgstr "" -#: ../../../CHANGELOG.md:1925 +#: ../../../CHANGELOG.md:2532 msgid "Background" msgstr "" -#: ../../../CHANGELOG.md:1927 +#: ../../../CHANGELOG.md:2534 msgid "Previously, `matrix-nginx-proxy` forwarded requests to Synapse directly. When Synapse is running in worker mode, the reverse-proxying configuration is more complicated (different requests need to go to different Synapse worker processes). `matrix-nginx-proxy` had configuration for sending each URL endpoint to the correct Synapse worker responsible for handling it. However, sometimes people like to disable `matrix-nginx-proxy` (for whatever reason) as detailed in [Using your own webserver, instead of this playbook's nginx proxy](docs/configuring-playbook-own-webserver.md)." msgstr "" -#: ../../../CHANGELOG.md:1929 +#: ../../../CHANGELOG.md:2536 msgid "Because `matrix-nginx-proxy` was so central to request forwarding, when it was disabled and Synapse was running with workers enabled, there was nothing which could forward requests to the correct place anymore… which caused [problems such as this one affecting Dimension](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2090)." msgstr "" -#: ../../../CHANGELOG.md:1931 +#: ../../../CHANGELOG.md:2538 msgid "Solution" msgstr "" -#: ../../../CHANGELOG.md:1933 +#: ../../../CHANGELOG.md:2540 msgid "From now on, `matrix-nginx-proxy` is relieved of its function of reverse-proxying to Synapse and its various worker processes. This role is now handled by the new `matrix-synapse-reverse-proxy-companion` nginx service and works even if `matrix-nginx-proxy` is disabled. The purpose of the new `matrix-synapse-reverse-proxy-companion` service is to:" msgstr "" -#: ../../../CHANGELOG.md:1935 +#: ../../../CHANGELOG.md:2542 msgid "serve as a companion to Synapse and know how to reverse-proxy to Synapse correctly (no matter if workers are enabled or not)" msgstr "" -#: ../../../CHANGELOG.md:1937 +#: ../../../CHANGELOG.md:2544 msgid "provide a unified container address for reaching Synapse (no matter if workers are enabled or not)" msgstr "" -#: ../../../CHANGELOG.md:1938 +#: ../../../CHANGELOG.md:2545 msgid "`matrix-synapse-reverse-proxy-companion:8008` for Synapse Client-Server API traffic" msgstr "" -#: ../../../CHANGELOG.md:1939 +#: ../../../CHANGELOG.md:2546 msgid "`matrix-synapse-reverse-proxy-companion:8048` for Synapse Server-Server (Federation) API traffic" msgstr "" -#: ../../../CHANGELOG.md:1941 +#: ../../../CHANGELOG.md:2548 msgid "simplify `matrix-nginx-proxy` configuration — it now only needs to send requests to `matrix-synapse-reverse-proxy-companion` or `matrix-dendrite`, etc., without having to worry about workers" msgstr "" -#: ../../../CHANGELOG.md:1943 +#: ../../../CHANGELOG.md:2550 msgid "allow reverse-proxying to Synapse, even if `matrix-nginx-proxy` is disabled" msgstr "" -#: ../../../CHANGELOG.md:1945 +#: ../../../CHANGELOG.md:2552 msgid "`matrix-nginx-proxy` still remains as the public SSL-terminating reverse-proxy in the playbook. All traffic goes through it before reaching any of the services. It's just that now the Synapse traffic is routed through `matrix-synapse-reverse-proxy-companion` like this:" msgstr "" -#: ../../../CHANGELOG.md:1947 +#: ../../../CHANGELOG.md:2554 msgid "(`matrix-nginx-proxy` -> `matrix-synapse-reverse-proxy-companion` -> (`matrix-synapse` or some Synapse worker))." msgstr "" -#: ../../../CHANGELOG.md:1949 +#: ../../../CHANGELOG.md:2556 msgid "Various services (like Dimension, etc.) still talk to Synapse via `matrix-nginx-proxy` (e.g. `http://matrix-nginx-proxy:12080`) preferentially. They only talk to Synapse via the reverse-proxy companion (e.g. `http://matrix-synapse-reverse-proxy-companion:8008`) if `matrix-nginx-proxy` is disabled. Services should not be talking to Synapse (e.g. `https://matrix-synapse:8008` directly anymore), because when workers are enabled, that's the Synapse `master` process and may not be serving all URL endpoints needed by the service." msgstr "" -#: ../../../CHANGELOG.md:1951 +#: ../../../CHANGELOG.md:2558 msgid "Webserver configuration" msgstr "" -#: ../../../CHANGELOG.md:1953 +#: ../../../CHANGELOG.md:2560 msgid "if you're using `matrix-nginx-proxy` (`matrix_nginx_proxy_enabled: true`, which is the default for the playbook), you don't need to do anything" msgstr "" -#: ../../../CHANGELOG.md:1955 +#: ../../../CHANGELOG.md:2562 msgid "if you're using your own `nginx` webserver running on the server, you shouldn't be affected. The `/matrix/nginx/conf.d` configuration and exposed ports that you're relying on will automatically be updated in a way that should work" msgstr "" -#: ../../../CHANGELOG.md:1957 +#: ../../../CHANGELOG.md:2564 msgid "if you're using another local webserver (e.g. Apache, etc.) and haven't changed any ports (`matrix_*_host_bind_port` definitions), you shouldn't be affected. You're likely sending Matrix traffic to `127.0.0.1:8008` and `127.0.0.1:8048`. These ports (`8008` and `8048`) will still be exposed on `127.0.0.1` by default — just not by the `matrix-synapse` container from now on, but by the `matrix-synapse-reverse-proxy-companion` container instead" msgstr "" -#: ../../../CHANGELOG.md:1959 +#: ../../../CHANGELOG.md:2566 msgid "if you've been exposing `matrix-synapse` ports (`matrix_synapse_container_client_api_host_bind_port`, etc.) manually, you should consider exposing `matrix-synapse-reverse-proxy-companion` ports instead" msgstr "" -#: ../../../CHANGELOG.md:1961 +#: ../../../CHANGELOG.md:2568 msgid "if you're running Traefik and reverse-proxying directly to the `matrix-synapse` container, you should start reverse-proxying to the `matrix-synapse-reverse-proxy-companion` container instead. See [our updated Traefik example configuration](docs/configuring-playbook-own-webserver.md#sample-configuration-for-running-behind-traefik-20). Note: we now recommend calling the federation entry point `federation` (instead of `synapse`) and reverse-proxying the federation traffic via `matrix-nginx-proxy`, instead of sending it directly to Synapse (or `matrix-synapse-reverse-proxy-companion`). This makes the configuration simpler." msgstr "" -#: ../../../CHANGELOG.md:1964 +#: ../../../CHANGELOG.md:2571 msgid "2022-11-05" msgstr "" -#: ../../../CHANGELOG.md:1966 +#: ../../../CHANGELOG.md:2573 msgid "(Backward Compatibility Break) A new default standalone mode for Etherpad" msgstr "" -#: ../../../CHANGELOG.md:1968 +#: ../../../CHANGELOG.md:2575 msgid "Until now, [Etherpad](https://etherpad.org/) (which [the playbook could install for you](docs/configuring-playbook-etherpad.md)) required the [Dimension integration manager](docs/configuring-playbook-dimension.md) to also be installed, because Etherpad was hosted on the Dimension domain (at `dimension.example.com/etherpad`)." msgstr "" -#: ../../../CHANGELOG.md:1970 +#: ../../../CHANGELOG.md:2577 msgid "From now on, Etherpad can be installed in `standalone` mode on `etherpad.example.com` and used even without Dimension. This is much more versatile, so the playbook now defaults to this new mode (`etherpad_mode: standalone`)." msgstr "" -#: ../../../CHANGELOG.md:1972 +#: ../../../CHANGELOG.md:2579 msgid "If you've already got both Etherpad and Dimension in use you could:" msgstr "" -#: ../../../CHANGELOG.md:1974 +#: ../../../CHANGELOG.md:2581 msgid "**either** keep hosting Etherpad under the Dimension domain by adding `etherpad_mode: dimension` to your `vars.yml` file. All your existing room widgets will continue working at the same URLs and no other changes will be necessary." msgstr "" -#: ../../../CHANGELOG.md:1976 +#: ../../../CHANGELOG.md:2583 msgid "**or**, you could change to hosting Etherpad separately on `etherpad.example.com`. You will need to [configure a DNS record](docs/configuring-dns.md) for this new domain. You will also need to reconfigure Dimension to use the new pad URLs (`https://etherpad.example.com/…`) going forward (refer to our [configuring Etherpad documentation](docs/configuring-playbook-etherpad.md)). All your existing room widgets (which still use `https://dimension.example.com/etherpad/…`) will break as Etherpad is not hosted there anymore. You will need to re-add them or to consider not using `standalone` mode" msgstr "" -#: ../../../CHANGELOG.md:1979 +#: ../../../CHANGELOG.md:2586 msgid "2022-11-04" msgstr "" -#: ../../../CHANGELOG.md:1981 +#: ../../../CHANGELOG.md:2588 msgid "The playbook now uses external roles for some things" msgstr "" -#: ../../../CHANGELOG.md:1983 +#: ../../../CHANGELOG.md:2590 msgid "**TLDR**: when updating the playbook and before running it, you'll need to run `make roles` to make [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) download dependency roles (see the [`requirements.yml` file](requirements.yml)) to the `roles/galaxy` directory. Without this, the playbook won't work." msgstr "" -#: ../../../CHANGELOG.md:1985 +#: ../../../CHANGELOG.md:2592 msgid "We're in the process of trimming the playbook and making it reuse Ansible roles." msgstr "" -#: ../../../CHANGELOG.md:1987 +#: ../../../CHANGELOG.md:2594 msgid "Starting now, the playbook is composed of 2 types of Ansible roles:" msgstr "" -#: ../../../CHANGELOG.md:1989 +#: ../../../CHANGELOG.md:2596 msgid "those that live within the playbook itself (`roles/custom/*`)" msgstr "" -#: ../../../CHANGELOG.md:1991 +#: ../../../CHANGELOG.md:2598 msgid "those downloaded from other sources (using [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) to `roles/galaxy`, based on the [`requirements.yml` file](requirements.yml)). These roles are maintained by us or by other people from the Ansible community." msgstr "" -#: ../../../CHANGELOG.md:1993 +#: ../../../CHANGELOG.md:2600 msgid "We're doing this for greater code-reuse (across Ansible playbooks, including our own related playbooks [gitea-docker-ansible-deploy](https://github.com/spantaleev/gitea-docker-ansible-deploy) and [nextcloud-docker-ansible-deploy](https://github.com/spantaleev/nextcloud-docker-ansible-deploy)) and decreased maintenance burden. Until now, certain features were copy-pasted across playbooks or were maintained separately in each one, with improvements often falling behind. We've also tended to do too much by ourselves — installing Docker on the server from our `matrix-base` role, etc. — something that we'd rather not do anymore by switching to the [geerlingguy.docker](https://galaxy.ansible.com/geerlingguy/docker) role." msgstr "" -#: ../../../CHANGELOG.md:1995 +#: ../../../CHANGELOG.md:2602 msgid "Some variable names will change during the transition to having more and more external (galaxy) roles. There's a new `custom/matrix_playbook_migration` role added to the playbook which will tell you about these changes each time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:1997 +#: ../../../CHANGELOG.md:2604 msgid "**From now on**, every time you update the playbook (well, every time the `requirements.yml` file changes), it's best to run `make roles` to update the roles downloaded from other sources. `make roles` is a shortcut (a `roles` target defined in [`Makefile`](Makefile) and executed by the [`make`](https://www.gnu.org/software/make/) utility) which ultimately runs [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) to download Ansible roles. If you don't have `make`, you can also manually run the commands seen in the `Makefile`." msgstr "" -#: ../../../CHANGELOG.md:2000 +#: ../../../CHANGELOG.md:2607 msgid "2022-10-14" msgstr "" -#: ../../../CHANGELOG.md:2002 +#: ../../../CHANGELOG.md:2609 msgid "synapse-s3-storage-provider support" msgstr "" -#: ../../../CHANGELOG.md:2004 +#: ../../../CHANGELOG.md:2611 msgid "**`synapse-s3-storage-provider` support is very new and still relatively untested. Using it may cause data loss.**" msgstr "" -#: ../../../CHANGELOG.md:2006 +#: ../../../CHANGELOG.md:2613 msgid "You can now store your Synapse media repository files on Amazon S3 (or another S3-compatible object store) using [synapse-s3-storage-provider](https://github.com/matrix-org/synapse-s3-storage-provider) — a media provider for Synapse (Python module), which should work faster and more reliably than our previous [Goofys](docs/configuring-playbook-s3-goofys.md) implementation (Goofys will continue to work)." msgstr "" -#: ../../../CHANGELOG.md:2008 +#: ../../../CHANGELOG.md:2615 msgid "This is not just for initial installations. Users with existing files (stored in the local filesystem) can also migrate their files to `synapse-s3-storage-provider`." msgstr "" -#: ../../../CHANGELOG.md:2010 +#: ../../../CHANGELOG.md:2617 msgid "To get started, see our [Storing Synapse media files on Amazon S3 with synapse-s3-storage-provider](docs/configuring-playbook-synapse-s3-storage-provider.md) documentation." msgstr "" -#: ../../../CHANGELOG.md:2012 +#: ../../../CHANGELOG.md:2619 msgid "Synapse container image customization support" msgstr "" -#: ../../../CHANGELOG.md:2014 +#: ../../../CHANGELOG.md:2621 msgid "We now support customizing the Synapse container image by adding additional build steps to its [`Dockerfile`](https://docs.docker.com/engine/reference/builder/)." msgstr "" -#: ../../../CHANGELOG.md:2016 +#: ../../../CHANGELOG.md:2623 msgid "Our [synapse-s3-storage-provider support](#synapse-s3-storage-provider-support) is actually built on this. When `s3-storage-provider` is enabled, we automatically add additional build steps to install its Python module into the Synapse image." msgstr "" -#: ../../../CHANGELOG.md:2018 +#: ../../../CHANGELOG.md:2625 msgid "Besides this kind of auto-added build steps (for components supported by the playbook), we also let you inject your own custom build steps using configuration like this:" msgstr "" -#: ../../../CHANGELOG.md:2029 +#: ../../../CHANGELOG.md:2636 msgid "People who have needed to customize Synapse previously had to fork the git repository, make their changes to the `Dockerfile` there, point the playbook to the new repository (`matrix_synapse_container_image_self_build_repo`) and enable self-building from scratch (`matrix_synapse_container_image_self_build: true`). This is harder and slower." msgstr "" -#: ../../../CHANGELOG.md:2031 +#: ../../../CHANGELOG.md:2638 msgid "With the new Synapse-customization feature in the playbook, we use the original upstream (pre-built, if available) Synapse image and only build on top of it, right on the Matrix server. This is much faster than building all of Synapse from scratch." msgstr "" -#: ../../../CHANGELOG.md:2034 +#: ../../../CHANGELOG.md:2641 msgid "2022-10-02" msgstr "" -#: ../../../CHANGELOG.md:2036 +#: ../../../CHANGELOG.md:2643 msgid "matrix-ldap-registration-proxy support" msgstr "" -#: ../../../CHANGELOG.md:2038 +#: ../../../CHANGELOG.md:2645 msgid "Thanks to [@TheOneWithTheBraid](https://github.com/TheOneWithTheBraid), we now support installing [matrix-ldap-registration-proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy) — a proxy which handles Matrix registration requests and forwards them to LDAP." msgstr "" -#: ../../../CHANGELOG.md:2040 +#: ../../../CHANGELOG.md:2647 msgid "See our [Setting up matrix-ldap-registration-proxy](docs/configuring-playbook-matrix-ldap-registration-proxy.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2043 +#: ../../../CHANGELOG.md:2650 msgid "2022-09-15" msgstr "" -#: ../../../CHANGELOG.md:2045 +#: ../../../CHANGELOG.md:2652 msgid "(Potential Backward Compatibility Break) Major improvements to Synapse workers" msgstr "" -#: ../../../CHANGELOG.md:2047 +#: ../../../CHANGELOG.md:2654 msgid "People who are interested in running a Synapse worker setup should know that **our Synapse worker implementation is much more powerful now**:" msgstr "" -#: ../../../CHANGELOG.md:2049 +#: ../../../CHANGELOG.md:2656 msgid "we've added support for [Stream writers](#stream-writers-support)" msgstr "" -#: ../../../CHANGELOG.md:2050 +#: ../../../CHANGELOG.md:2657 msgid "we've added support for [multiple federation sender workers](#multiple-federation-sender-workers-support)" msgstr "" -#: ../../../CHANGELOG.md:2051 +#: ../../../CHANGELOG.md:2658 msgid "we've added support for [multiple pusher workers](#multiple-pusher-workers-support)" msgstr "" -#: ../../../CHANGELOG.md:2052 +#: ../../../CHANGELOG.md:2659 msgid "we've added support for [running background tasks on a worker](#background-tasks-can-run-on-a-worker)" msgstr "" -#: ../../../CHANGELOG.md:2053 +#: ../../../CHANGELOG.md:2660 msgid "we've restored support for [`appservice` workers](#appservice-worker-support-is-back)" msgstr "" -#: ../../../CHANGELOG.md:2054 +#: ../../../CHANGELOG.md:2661 msgid "we've restored support for [`user_dir` workers](#user-directory-worker-support-is-back)" msgstr "" -#: ../../../CHANGELOG.md:2055 +#: ../../../CHANGELOG.md:2662 msgid "we've made it possible to [reliably use more than 1 `media_repository` worker](#using-more-than-1-media-repository-worker-is-now-more-reliable)" msgstr "" -#: ../../../CHANGELOG.md:2056 +#: ../../../CHANGELOG.md:2663 msgid "see the [Potential Backward Incompatibilities after these Synapse worker changes](#potential-backward-incompatibilities-after-these-synapse-worker-changes)" msgstr "" -#: ../../../CHANGELOG.md:2058 +#: ../../../CHANGELOG.md:2665 msgid "Stream writers support" msgstr "" -#: ../../../CHANGELOG.md:2060 +#: ../../../CHANGELOG.md:2667 msgid "From now on, the playbook lets you easily set up various [stream writer workers](https://matrix-org.github.io/synapse/latest/workers.html#stream-writers) which can handle different streams (`events` stream; `typing` URL endpoints, `to_device` URL endpoints, `account_data` URL endpoints, `receipts` URL endpoints, `presence` URL endpoints). All of this work was previously handled by the main Synapse process, but can now be offloaded to stream writer worker processes." msgstr "" -#: ../../../CHANGELOG.md:2062 +#: ../../../CHANGELOG.md:2669 msgid "If you're using `matrix_synapse_workers_preset: one-of-each`, you'll automatically get 6 additional workers (one for each of the above stream types). Our `little-federation-helper` preset (meant to be quite minimal and focusing in improved federation performance) does not include stream writer workers." msgstr "" -#: ../../../CHANGELOG.md:2064 +#: ../../../CHANGELOG.md:2671 msgid "If you'd like to customize the number of workers we also make that possible using these variables:" msgstr "" -#: ../../../CHANGELOG.md:2077 +#: ../../../CHANGELOG.md:2684 msgid "Multiple federation sender workers support" msgstr "" -#: ../../../CHANGELOG.md:2079 +#: ../../../CHANGELOG.md:2686 msgid "Until now, we only supported a single `federation_sender` worker (`matrix_synapse_workers_federation_sender_workers_count` could either be `0` or `1`). From now on, you can have as many as you want to help with your federation traffic." msgstr "" -#: ../../../CHANGELOG.md:2081 +#: ../../../CHANGELOG.md:2688 msgid "Multiple pusher workers support" msgstr "" -#: ../../../CHANGELOG.md:2083 +#: ../../../CHANGELOG.md:2690 msgid "Until now, we only supported a single `pusher` worker (`matrix_synapse_workers_pusher_workers_count` could either be `0` or `1`). From now on, you can have as many as you want to help with pushing notifications out." msgstr "" -#: ../../../CHANGELOG.md:2085 +#: ../../../CHANGELOG.md:2692 msgid "Background tasks can run on a worker" msgstr "" -#: ../../../CHANGELOG.md:2087 +#: ../../../CHANGELOG.md:2694 msgid "From now on, you can put [background task processing on a worker](https://matrix-org.github.io/synapse/latest/workers.html#background-tasks)." msgstr "" -#: ../../../CHANGELOG.md:2089 +#: ../../../CHANGELOG.md:2696 msgid "With `matrix_synapse_workers_preset: one-of-each`, you'll get one `background` worker automatically. You can also control the `background` workers count with `matrix_synapse_workers_background_workers_count`. Only `0` or `1` workers of this type are supported by Synapse." msgstr "" -#: ../../../CHANGELOG.md:2091 +#: ../../../CHANGELOG.md:2698 msgid "Appservice worker support is back" msgstr "" -#: ../../../CHANGELOG.md:2093 +#: ../../../CHANGELOG.md:2700 msgid "We previously had an `appservice` worker type, which [Synapse deprecated in v1.59.0](https://github.com/element-hq/synapse/blob/v1.59.0/docs/upgrade.md#deprecation-of-the-synapseappappservice-and-synapseappuser_dir-worker-application-types). So did we, at the time." msgstr "" -#: ../../../CHANGELOG.md:2095 +#: ../../../CHANGELOG.md:2702 msgid "The new way to implement such workers is by using a `generic_worker` and dedicating it to the task of talking to Application Services. From now on, we have support for this." msgstr "" -#: ../../../CHANGELOG.md:2097 +#: ../../../CHANGELOG.md:2704 msgid "With `matrix_synapse_workers_preset: one-of-each`, you'll get one `appservice` worker automatically. You can also control the `appservice` workers count with `matrix_synapse_workers_appservice_workers_count`. Only `0` or `1` workers of this type are supported by Synapse." msgstr "" -#: ../../../CHANGELOG.md:2099 +#: ../../../CHANGELOG.md:2706 msgid "User Directory worker support is back" msgstr "" -#: ../../../CHANGELOG.md:2101 +#: ../../../CHANGELOG.md:2708 msgid "We previously had a `user_dir` worker type, which [Synapse deprecated in v1.59.0](https://github.com/element-hq/synapse/blob/v1.59.0/docs/upgrade.md#deprecation-of-the-synapseappappservice-and-synapseappuser_dir-worker-application-types). So did we, at the time." msgstr "" -#: ../../../CHANGELOG.md:2103 +#: ../../../CHANGELOG.md:2710 msgid "The new way to implement such workers is by using a `generic_worker` and dedicating it to the task of serving the user directory. From now on, we have support for this." msgstr "" -#: ../../../CHANGELOG.md:2105 +#: ../../../CHANGELOG.md:2712 msgid "With `matrix_synapse_workers_preset: one-of-each`, you'll get one `user_dir` worker automatically. You can also control the `user_dir` workers count with `matrix_synapse_workers_user_dir_workers_count`. Only `0` or `1` workers of this type are supported by Synapse." msgstr "" -#: ../../../CHANGELOG.md:2107 +#: ../../../CHANGELOG.md:2714 msgid "Using more than 1 media repository worker is now more reliable" msgstr "" -#: ../../../CHANGELOG.md:2109 +#: ../../../CHANGELOG.md:2716 msgid "With `matrix_synapse_workers_preset: one-of-each`, we only launch one `media_repository` worker." msgstr "" -#: ../../../CHANGELOG.md:2111 +#: ../../../CHANGELOG.md:2718 msgid "If you've been configuring `matrix_synapse_workers_media_repository_workers_count` manually, you may have increased that to more workers. When multiple media repository workers are in use, background tasks related to the media repository must always be configured to run on a single `media_repository` worker via `media_instance_running_background_jobs`. Until now, we weren't doing this correctly, but we now are." msgstr "" -#: ../../../CHANGELOG.md:2113 +#: ../../../CHANGELOG.md:2720 msgid "Potential Backward Incompatibilities after these Synapse worker changes" msgstr "" -#: ../../../CHANGELOG.md:2115 +#: ../../../CHANGELOG.md:2722 msgid "Below we'll discuss **potential backward incompatibilities**." msgstr "" -#: ../../../CHANGELOG.md:2117 +#: ../../../CHANGELOG.md:2724 msgid "**Worker names** (container names, systemd services, worker configuration files) **have changed**. Workers are now labeled sequentially (e.g. `matrix-synapse-worker_generic_worker-18111` -> `matrix-synapse-worker-generic-0`). The playbook will handle these changes automatically." msgstr "" -#: ../../../CHANGELOG.md:2119 +#: ../../../CHANGELOG.md:2726 msgid "Due to increased worker types support above, people who use `matrix_synapse_workers_preset: one-of-each` should be aware that with these changes, **the playbook will deploy 9 additional workers** (6 stream writers, 1 `appservice` worker, 1 `user_dir` worker, 1 background task worker). This **may increase RAM/CPU usage**, etc. If you find your server struggling, consider disabling some workers with the appropriate `matrix_synapse_workers_*_workers_count` variables." msgstr "" -#: ../../../CHANGELOG.md:2121 +#: ../../../CHANGELOG.md:2728 msgid "**Metric endpoints have also changed** (`/metrics/synapse/worker/generic_worker-18111` -> `/metrics/synapse/worker/generic-worker-0`). If you're [collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server), consider revisiting our [Collecting Synapse worker metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-synapse-worker-metrics-to-an-external-prometheus-server) docs and updating your Prometheus configuration. **If you're collecting metrics to the integrated Prometheus server** (not enabled by default), **your Prometheus configuration will be updated automatically**. Old data (from before this change) may stick around though." msgstr "" -#: ../../../CHANGELOG.md:2123 +#: ../../../CHANGELOG.md:2730 msgid "**the format of `matrix_synapse_workers_enabled_list` has changed**. You were never advised to use this variable for directly creating workers (we advise people to control workers using `matrix_synapse_workers_preset` or by tweaking `matrix_synapse_workers_*_workers_count` variables only), but some people may have started using the `matrix_synapse_workers_enabled_list` variable to gain more control over workers. If you're one of them, you'll need to adjust its value. See `roles/custom/matrix-synapse/defaults/main.yml` for more information on the new format. The playbook will also do basic validation and complain if you got something wrong." msgstr "" -#: ../../../CHANGELOG.md:2126 +#: ../../../CHANGELOG.md:2733 msgid "2022-09-09" msgstr "" -#: ../../../CHANGELOG.md:2128 +#: ../../../CHANGELOG.md:2735 msgid "Cactus Comments support" msgstr "" -#: ../../../CHANGELOG.md:2130 +#: ../../../CHANGELOG.md:2737 msgid "Thanks to [Julian-Samuel Gebühr (@moan0s)](https://github.com/moan0s), the playbook can now set up [Cactus Comments](https://cactus.chat) — federated comment system for the web based on Matrix." msgstr "" -#: ../../../CHANGELOG.md:2132 +#: ../../../CHANGELOG.md:2739 msgid "See our [Setting up Cactus Comments](docs/configuring-playbook-cactus-comments.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2135 +#: ../../../CHANGELOG.md:2742 msgid "2022-08-23" msgstr "" -#: ../../../CHANGELOG.md:2137 +#: ../../../CHANGELOG.md:2744 msgid "Postmoogle email bridge support" msgstr "" -#: ../../../CHANGELOG.md:2139 +#: ../../../CHANGELOG.md:2746 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up the new [Postmoogle](https://github.com/etkecc/postmoogle) email bridge. Postmoogle is like the [Email2Matrix bridge](https://github.com/devture/email2matrix) (also [already supported by the playbook](docs/configuring-playbook-email2matrix.md)), but more capable and with the intention to soon support *sending* emails, not just receiving." msgstr "" -#: ../../../CHANGELOG.md:2141 +#: ../../../CHANGELOG.md:2748 msgid "See our [Setting up Postmoogle email bridging](docs/configuring-playbook-bridge-postmoogle.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2144 +#: ../../../CHANGELOG.md:2751 msgid "2022-08-10" msgstr "" -#: ../../../CHANGELOG.md:2146 +#: ../../../CHANGELOG.md:2753 msgid "mautrix-whatsapp default configuration changes" msgstr "" -#: ../../../CHANGELOG.md:2148 +#: ../../../CHANGELOG.md:2755 msgid "In [Pull Request #2012](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2012), we've made some changes to the default configuration used by the `mautrix-whatsapp` bridge." msgstr "" -#: ../../../CHANGELOG.md:2150 +#: ../../../CHANGELOG.md:2757 msgid "If you're using this bridge, you should look into this PR and see if the new configuration suits you. If not, you can always change individual preferences in your `vars.yml` file." msgstr "" -#: ../../../CHANGELOG.md:2152 +#: ../../../CHANGELOG.md:2759 msgid "Most notably, spaces support has been enabled by default. The bridge will now group rooms into a Matrix space. **If you've already bridged to Whatsapp** prior to this update, you will need to send `!wa sync space` to the bridge bot to make it create the space and put your existing rooms into it." msgstr "" -#: ../../../CHANGELOG.md:2155 +#: ../../../CHANGELOG.md:2762 msgid "2022-08-09" msgstr "" -#: ../../../CHANGELOG.md:2157 +#: ../../../CHANGELOG.md:2764 msgid "Conduit support" msgstr "" -#: ../../../CHANGELOG.md:2159 +#: ../../../CHANGELOG.md:2766 msgid "Thanks to [Charles Wright](https://github.com/cvwright), we now have optional experimental [Conduit](https://conduit.rs) homeserver support for new installations. This comes as a follow-up to the playbook getting [Dendrite support](#dendrite-support) earlier this year." msgstr "" -#: ../../../CHANGELOG.md:2161 +#: ../../../CHANGELOG.md:2768 msgid "Existing Synapse or Dendrite installations do **not** need to be updated. **Synapse is still the default homeserver implementation** installed by the playbook." msgstr "" -#: ../../../CHANGELOG.md:2163 +#: ../../../CHANGELOG.md:2770 msgid "To try out Conduit, we recommend that you **use a new server** and the following `vars.yml` configuration:" msgstr "" -#: ../../../CHANGELOG.md:2169 +#: ../../../CHANGELOG.md:2776 msgid "**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse or Dendrite to Conduit) without data loss." msgstr "" -#: ../../../CHANGELOG.md:2172 +#: ../../../CHANGELOG.md:2779 msgid "2022-07-29" msgstr "" -#: ../../../CHANGELOG.md:2174 +#: ../../../CHANGELOG.md:2781 msgid "mautrix-discord support" msgstr "" -#: ../../../CHANGELOG.md:2176 +#: ../../../CHANGELOG.md:2783 msgid "Thanks to [MdotAmaan](https://github.com/MdotAmaan)'s efforts, the playbook now supports bridging to [Discord](https://discordapp.com/) via the [mautrix-discord](https://mau.dev/mautrix/discord) bridge. See our [Setting up Mautrix Discord bridging](docs/configuring-playbook-bridge-mautrix-discord.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:2178 +#: ../../../CHANGELOG.md:2785 msgid "**Note**: this is a new Discord bridge. The playbook still retains Discord bridging via [matrix-appservice-discord](docs/configuring-playbook-bridge-appservice-discord.md) and [mx-puppet-discord](docs/configuring-playbook-bridge-mx-puppet-discord.md). You're free to use the bridge that serves you better, or even all three of them (for different users and use-cases)." msgstr "" -#: ../../../CHANGELOG.md:2181 +#: ../../../CHANGELOG.md:2788 msgid "2022-07-27" msgstr "" -#: ../../../CHANGELOG.md:2183 +#: ../../../CHANGELOG.md:2790 msgid "matrix-appservice-kakaotalk support" msgstr "" -#: ../../../CHANGELOG.md:2185 +#: ../../../CHANGELOG.md:2792 msgid "The playbook now supports bridging to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG) via [matrix-appservice-kakaotalk](https://src.miscworks.net/fair/matrix-appservice-kakaotalk) — a bridge based on [node-kakao](https://github.com/storycraft/node-kakao) (now unmaintained) and some [mautrix-facebook](https://github.com/mautrix/facebook) code. Thanks to [hnarjis](https://github.com/hnarjis) for helping us add support for this!" msgstr "" -#: ../../../CHANGELOG.md:2187 +#: ../../../CHANGELOG.md:2794 msgid "See our [Setting up Appservice Kakaotalk bridging](docs/configuring-playbook-bridge-appservice-kakaotalk.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2190 +#: ../../../CHANGELOG.md:2797 msgid "2022-07-20" msgstr "" -#: ../../../CHANGELOG.md:2192 +#: ../../../CHANGELOG.md:2799 msgid "maubot support" msgstr "" -#: ../../../CHANGELOG.md:2194 +#: ../../../CHANGELOG.md:2801 msgid "Thanks to [Stuart Mumford (@Cadair)](https://github.com/cadair) for starting ([PR #373](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/373) and [PR #622](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/622)) and to [Julian-Samuel Gebühr (@moan0s)](https://github.com/moan0s) for finishing up (in [PR #1894](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1894)), the playbook can now help you set up [maubot](https://github.com/maubot/maubot) — a plugin-based Matrix bot system." msgstr "" -#: ../../../CHANGELOG.md:2196 +#: ../../../CHANGELOG.md:2803 msgid "See our [Setting up maubot](docs/configuring-playbook-bot-maubot.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2199 +#: ../../../CHANGELOG.md:2806 msgid "2022-07-14" msgstr "" -#: ../../../CHANGELOG.md:2201 +#: ../../../CHANGELOG.md:2808 msgid "mx-puppet-skype removal" msgstr "" -#: ../../../CHANGELOG.md:2203 +#: ../../../CHANGELOG.md:2810 msgid "The playbook no longer includes the [mx-puppet-skype](https://github.com/Sorunome/mx-puppet-skype) bridge, because it has been broken and unmaintained for a long time. Users that have `matrix_mx_puppet_skype_enabled` in their configuration files will encounter an error when running the playbook until they remove references to this bridge from their configuration." msgstr "" -#: ../../../CHANGELOG.md:2205 +#: ../../../CHANGELOG.md:2812 msgid "To completely clean up your server from `mx-puppet-skype`'s presence on it:" msgstr "" -#: ../../../CHANGELOG.md:2207 +#: ../../../CHANGELOG.md:2814 msgid "ensure your Ansible configuration (`vars.yml` file) no longer contains `matrix_mx_puppet_skype_*` references" msgstr "" -#: ../../../CHANGELOG.md:2208 +#: ../../../CHANGELOG.md:2815 msgid "stop and disable the systemd service (run `systemctl disable --now matrix-mx-puppet-skype` on the server)" msgstr "" -#: ../../../CHANGELOG.md:2209 +#: ../../../CHANGELOG.md:2816 msgid "delete the systemd service (run `rm /etc/systemd/system/matrix-mx-puppet-skype.service` on the server)" msgstr "" -#: ../../../CHANGELOG.md:2210 +#: ../../../CHANGELOG.md:2817 msgid "delete `/matrix/mx-puppet-skype` (run `rm -rf /matrix/mx-puppet-skype` on the server)" msgstr "" -#: ../../../CHANGELOG.md:2211 +#: ../../../CHANGELOG.md:2818 msgid "drop the `matrix_mx_puppet_skype` database (run `/usr/local/bin/matrix-postgres-cli` on the server, and execute the `DROP DATABASE matrix_mx_puppet_skype;` query there)" msgstr "" -#: ../../../CHANGELOG.md:2213 +#: ../../../CHANGELOG.md:2820 msgid "If you still need bridging to [Skype](https://www.skype.com/), consider switching to [go-skype-bridge](https://github.com/kelaresg/go-skype-bridge) instead. See [Setting up Go Skype Bridge bridging](docs/configuring-playbook-bridge-go-skype-bridge.md)." msgstr "" -#: ../../../CHANGELOG.md:2215 +#: ../../../CHANGELOG.md:2822 msgid "If you think this is a mistake and `mx-puppet-skype` works for you (or you get it to work somehow), let us know and we may reconsider this removal." msgstr "" -#: ../../../CHANGELOG.md:2217 +#: ../../../CHANGELOG.md:2824 msgid "signald (0.19.0+) upgrade requires data migration" msgstr "" -#: ../../../CHANGELOG.md:2219 +#: ../../../CHANGELOG.md:2826 msgid "In [Pull Request #1921](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1921) we upgraded [signald](https://signald.org/) (used by the mautrix-signal bridge) from `v0.18.5` to `v0.20.0`." msgstr "" -#: ../../../CHANGELOG.md:2221 +#: ../../../CHANGELOG.md:2828 msgid "Back in the [`v0.19.0` released of signald](https://gitlab.com/signald/signald/-/blob/main/releases/0.19.0.md) (which we skipped and migrated straight to `v0.20.0`), a new `--migrate-data` command had been added that migrates avatars, group images, attachments, etc., into the database (those were previously stored in the filesystem)." msgstr "" -#: ../../../CHANGELOG.md:2223 +#: ../../../CHANGELOG.md:2830 msgid "If you've been using the mautrix-signal bridge for a while, you may have files stored in the local filesystem, which will need to be upgraded." msgstr "" -#: ../../../CHANGELOG.md:2225 +#: ../../../CHANGELOG.md:2832 msgid "We attempt to do this data migration automatically every time Signald starts (`matrix-mautrix-signal-daemon.service`) using a `ExecStartPre` systemd unit definition." msgstr "" -#: ../../../CHANGELOG.md:2227 +#: ../../../CHANGELOG.md:2834 msgid "Keep an eye on your Signal bridge and let us know (in our [support room](README.md#support) or in [Pull Request #1921](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1921)) if you experience any trouble!" msgstr "" -#: ../../../CHANGELOG.md:2230 +#: ../../../CHANGELOG.md:2837 msgid "2022-07-05" msgstr "" -#: ../../../CHANGELOG.md:2232 +#: ../../../CHANGELOG.md:2839 msgid "Ntfy push notifications support" msgstr "" -#: ../../../CHANGELOG.md:2234 +#: ../../../CHANGELOG.md:2841 msgid "Thanks to [Julian Foad](https://matrix.to/#/@julian:foad.me.uk), the playbook can now install a [ntfy](https://ntfy.sh/) push notifications server for you." msgstr "" -#: ../../../CHANGELOG.md:2236 +#: ../../../CHANGELOG.md:2843 msgid "See our [Setting up the ntfy push notifications server](docs/configuring-playbook-ntfy.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2239 +#: ../../../CHANGELOG.md:2846 msgid "2022-06-23" msgstr "" -#: ../../../CHANGELOG.md:2241 +#: ../../../CHANGELOG.md:2848 msgid "(Potential Backward Compatibility Break) Changes around metrics collection" msgstr "" -#: ../../../CHANGELOG.md:2243 +#: ../../../CHANGELOG.md:2850 msgid "**TLDR**: we've made extensive **changes to metrics exposure/collection, which concern people using an external Prometheus server**. If you don't know what that is, you don't need to read below." msgstr "" -#: ../../../CHANGELOG.md:2245 +#: ../../../CHANGELOG.md:2852 msgid "**Why do major changes to metrics**? Because various services were exposing metrics in different, hacky, ways. Synapse was exposing metrics at `/_synapse/metrics` and `/_synapse-worker-…/metrics` on the `matrix.example.com`. The Hookshot role was **repurposing** the Granana web UI domain (`stats.example.com`) for exposing its metrics on `stats.example.com/hookshot/metrics`, while protecting these routes using Basic Authentication **normally used for Synapse** (`/_synapse/metrics`). Node-exporter and Postgres-exporter roles were advising for more `stats.example.com` usage in manual ways. Each role was doing things differently and mixing variables from other roles. Each metrics endpoint was ending up in a different place, protected by who knows what Basic Authentication credentials (if protected at all)." msgstr "" -#: ../../../CHANGELOG.md:2247 +#: ../../../CHANGELOG.md:2854 msgid "**The solution**: a completely revamped way to expose metrics to an external Prometheus server. We are **introducing new `https://matrix.example.com/metrics/*` endpoints**, where various services *can* expose their metrics, for collection by external Prometheus servers. To enable the `/metrics/*` endpoints, use `matrix_nginx_proxy_proxy_matrix_metrics_enabled: true`. There's also a way to protect access using [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). See the `matrix-nginx-proxy` role or our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation for additional variables around `matrix_nginx_proxy_proxy_matrix_metrics_enabled`." msgstr "" -#: ../../../CHANGELOG.md:2249 +#: ../../../CHANGELOG.md:2856 msgid "**If you are using the [Hookshot bridge](docs/configuring-playbook-bridge-hookshot.md)**, you may find that:" msgstr "" -#: ../../../CHANGELOG.md:2250 +#: ../../../CHANGELOG.md:2857 msgid "**Metrics may not be enabled by default anymore**:" msgstr "" -#: ../../../CHANGELOG.md:2251 +#: ../../../CHANGELOG.md:2858 msgid "If Prometheus is enabled (`prometheus_enabled: true`), then Hookshot metrics will be enabled automatically (`matrix_hookshot_metrics_enabled: true`). These metrics will be collected from the local (in-container) Prometheus over the container network." msgstr "" -#: ../../../CHANGELOG.md:2252 +#: ../../../CHANGELOG.md:2859 msgid "**If Prometheus is not enabled** (you are either not using Prometheus or are using an external one), **Hookshot metrics will not be enabled by default anymore**. Feel free to enable them by setting `matrix_hookshot_metrics_enabled: true`. Also, see below." msgstr "" -#: ../../../CHANGELOG.md:2253 +#: ../../../CHANGELOG.md:2860 msgid "When metrics are meant to be **consumed by an external Prometheus server**, `matrix_hookshot_metrics_proxying_enabled` needs to be set to `true`, so that metrics would be exposed (proxied) \"publicly\" on `https://matrix.example.com/metrics/hookshot`. To make use of this, you'll also need to enable the new `https://matrix.example.com/metrics/*` endpoints mentioned above, using `matrix_nginx_proxy_proxy_matrix_metrics_enabled`. Learn more in our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation." msgstr "" -#: ../../../CHANGELOG.md:2254 +#: ../../../CHANGELOG.md:2861 msgid "**We've changed the URL we're exposing Hookshot metrics at** for external Prometheus servers. Until now, you were advised to consume Hookshot metrics from `https://stats.example.com/hookshot/metrics` (working in conjunction with `matrix_nginx_proxy_proxy_synapse_metrics`). From now on, **this no longer works**. As described above, you need to start consuming metrics from `https://matrix.example.com/metrics/hookshot`." msgstr "" -#: ../../../CHANGELOG.md:2256 +#: ../../../CHANGELOG.md:2863 msgid "**If you're using node-exporter** (`matrix_prometheus_node_exporter_enabled: true`) and would like to collect its metrics from an external Prometheus server, see `matrix_prometheus_node_exporter_metrics_proxying_enabled` described in our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation. You will be able to collect its metrics from `https://matrix.example.com/metrics/node-exporter`." msgstr "" -#: ../../../CHANGELOG.md:2258 +#: ../../../CHANGELOG.md:2865 msgid "**If you're using [postgres-exporter](docs/configuring-playbook-prometheus-grafana.md#enable-metrics-and-graphs-for-postgres-optional)** (`prometheus_postgres_exporter_enabled: true`) and would like to collect its metrics from an external Prometheus server, see `matrix_prometheus_services_proxy_connect_prometheus_postgres_exporter_metrics_proxying_enabled` described in our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation. You will be able to collect its metrics from `https://matrix.example.com/metrics/postgres-exporter`." msgstr "" -#: ../../../CHANGELOG.md:2260 +#: ../../../CHANGELOG.md:2867 msgid "**If you're using Synapse** and would like to collect its metrics from an external Prometheus server, you may find that:" msgstr "" -#: ../../../CHANGELOG.md:2262 +#: ../../../CHANGELOG.md:2869 msgid "Exposing metrics is now done using `matrix_synapse_metrics_proxying_enabled`, not `matrix_nginx_proxy_proxy_synapse_metrics: true`. You may still need to enable metrics using `matrix_synapse_metrics_enabled: true` before exposing them." msgstr "" -#: ../../../CHANGELOG.md:2263 +#: ../../../CHANGELOG.md:2870 msgid "Protecting metrics endpoints using [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) is now done in another way. See our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation" msgstr "" -#: ../../../CHANGELOG.md:2264 +#: ../../../CHANGELOG.md:2871 msgid "If Synapse metrics are exposed, they will be made available at `https://matrix.example.com/metrics/synapse/main-process` or `https://matrix.example.com/metrics/synapse/worker/TYPE-ID` (when workers are enabled), not at `https://matrix.example.com/_synapse/metrics` and `https://matrix.example.com/_synapse-worker-…/metrics`" msgstr "" -#: ../../../CHANGELOG.md:2265 +#: ../../../CHANGELOG.md:2872 msgid "The playbook still generates an `external_prometheus.yml.example` sample file for scraping Synapse from Prometheus as described in [Collecting Synapse worker metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-synapse-worker-metrics-to-an-external-prometheus-server), but it's now saved under `/matrix/synapse` (not `/matrix`)." msgstr "" -#: ../../../CHANGELOG.md:2267 +#: ../../../CHANGELOG.md:2874 msgid "**If you where already using a external Prometheus server** before this change, and you gave a hashed version of the password as a variable, the playbook will now take care of hashing the password for you. Thus, you need to provide the non-hashed version now." msgstr "" -#: ../../../CHANGELOG.md:2269 +#: ../../../CHANGELOG.md:2876 msgid "2022-06-13" msgstr "" -#: ../../../CHANGELOG.md:2271 +#: ../../../CHANGELOG.md:2878 msgid "go-skype-bridge bridging support" msgstr "" -#: ../../../CHANGELOG.md:2273 +#: ../../../CHANGELOG.md:2880 msgid "Thanks to [CyberShadow](https://github.com/CyberShadow), the playbook can now install the [go-skype-bridge](https://github.com/kelaresg/go-skype-bridge) bridge for bridging Matrix to [Skype](https://www.skype.com/)." msgstr "" -#: ../../../CHANGELOG.md:2275 +#: ../../../CHANGELOG.md:2882 msgid "See our [Setting up Go Skype Bridge bridging](docs/configuring-playbook-bridge-go-skype-bridge.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2277 +#: ../../../CHANGELOG.md:2884 msgid "The playbook has supported [mx-puppet-skype](https://github.com/Sorunome/mx-puppet-skype) bridging (see [Setting up MX Puppet Skype bridging](docs/configuring-playbook-bridge-mx-puppet-skype.md)) since [2020-04-09](#2020-04-09), but `mx-puppet-skype` is reportedly broken." msgstr "" -#: ../../../CHANGELOG.md:2280 +#: ../../../CHANGELOG.md:2887 msgid "2022-06-09" msgstr "" -#: ../../../CHANGELOG.md:2282 +#: ../../../CHANGELOG.md:2889 msgid "Running Ansible in a container can now happen on the Matrix server itself" msgstr "" -#: ../../../CHANGELOG.md:2284 +#: ../../../CHANGELOG.md:2891 msgid "If you're tired of being on an old and problematic Ansible version, you can now run [run Ansible in a container on the Matrix server itself](docs/ansible.md#running-ansible-in-a-container-on-the-matrix-server-itself)." msgstr "" -#: ../../../CHANGELOG.md:2287 +#: ../../../CHANGELOG.md:2894 msgid "2022-05-31" msgstr "" -#: ../../../CHANGELOG.md:2289 +#: ../../../CHANGELOG.md:2896 msgid "Synapse v1.60 upgrade may cause trouble and require manual intervention" msgstr "" -#: ../../../CHANGELOG.md:2291 +#: ../../../CHANGELOG.md:2898 msgid "Synapse v1.60 will try to add a new unique index to `state_group_edges` upon startup and could fail if your database is corrupted." msgstr "" -#: ../../../CHANGELOG.md:2293 +#: ../../../CHANGELOG.md:2900 msgid "We haven't observed this problem yet, but [the Synapse v1.60.0 upgrade notes](https://github.com/element-hq/synapse/blob/v1.60.0/docs/upgrade.md#adding-a-new-unique-index-to-state_group_edges-could-fail-if-your-database-is-corrupted) mention it, so we're giving you a heads up here in case you're unlucky." msgstr "" -#: ../../../CHANGELOG.md:2295 +#: ../../../CHANGELOG.md:2902 msgid "**If Synapse fails to start** after your next playbook run, you'll need to:" msgstr "" -#: ../../../CHANGELOG.md:2297 +#: ../../../CHANGELOG.md:2904 msgid "SSH into the Matrix server" msgstr "" -#: ../../../CHANGELOG.md:2298 +#: ../../../CHANGELOG.md:2905 msgid "launch `/usr/local/bin/matrix-postgres-cli`" msgstr "" -#: ../../../CHANGELOG.md:2299 +#: ../../../CHANGELOG.md:2906 msgid "switch to the `synapse` database: `\\c synapse`" msgstr "" -#: ../../../CHANGELOG.md:2300 +#: ../../../CHANGELOG.md:2907 msgid "run the following SQL query:" msgstr "" -#: ../../../CHANGELOG.md:2319 +#: ../../../CHANGELOG.md:2926 msgid "You could then restart services: `ansible-playbook -i inventory/hosts setup.yml --tags=start`" msgstr "" -#: ../../../CHANGELOG.md:2322 +#: ../../../CHANGELOG.md:2929 msgid "2022-04-25" msgstr "" -#: ../../../CHANGELOG.md:2324 +#: ../../../CHANGELOG.md:2931 msgid "Buscarron bot support" msgstr "" -#: ../../../CHANGELOG.md:2326 +#: ../../../CHANGELOG.md:2933 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up [the Buscarron bot](https://github.com/etkecc/buscarron). It's a bot you can use to send any form (HTTP POST, HTML) to a (encrypted) Matrix room" msgstr "" -#: ../../../CHANGELOG.md:2328 +#: ../../../CHANGELOG.md:2935 msgid "See our [Setting up Buscarron](docs/configuring-playbook-bot-buscarron.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2331 +#: ../../../CHANGELOG.md:2938 msgid "2022-04-21" msgstr "" -#: ../../../CHANGELOG.md:2333 +#: ../../../CHANGELOG.md:2940 msgid "matrix-registration-bot support" msgstr "" -#: ../../../CHANGELOG.md:2335 +#: ../../../CHANGELOG.md:2942 msgid "Thanks to [Julian-Samuel Gebühr (@moan0s)](https://github.com/moan0s), the playbook can now help you set up [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot) — a bot that is used to create and manage registration tokens for a Matrix server." msgstr "" -#: ../../../CHANGELOG.md:2337 +#: ../../../CHANGELOG.md:2944 msgid "See our [Setting up matrix-registration-bot](docs/configuring-playbook-bot-matrix-registration-bot.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2340 +#: ../../../CHANGELOG.md:2947 msgid "2022-04-19" msgstr "" -#: ../../../CHANGELOG.md:2342 +#: ../../../CHANGELOG.md:2949 msgid "BorgBackup support" msgstr "" -#: ../../../CHANGELOG.md:2344 +#: ../../../CHANGELOG.md:2951 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up [Borg](https://www.borgbackup.org/) backups with [borgmatic](https://torsion.org/borgmatic/) of your Matrix server." msgstr "" -#: ../../../CHANGELOG.md:2346 +#: ../../../CHANGELOG.md:2953 msgid "See our [Setting up BorgBackup](docs/configuring-playbook-backup-borg.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2348 +#: ../../../CHANGELOG.md:2955 msgid "(Compatibility Break) Upgrading to Synapse v1.57 on setups using workers may require manual action" msgstr "" -#: ../../../CHANGELOG.md:2350 +#: ../../../CHANGELOG.md:2957 msgid "If you're running a worker setup for Synapse (`matrix_synapse_workers_enabled: true`), the [Synapse v1.57 upgrade notes](https://github.com/element-hq/synapse/blob/v1.57.0rc1/docs/upgrade.md#changes-to-database-schema-for-application-services) say that you may need to take special care when upgrading:" msgstr "" -#: ../../../CHANGELOG.md:2352 +#: ../../../CHANGELOG.md:2959 msgid "Synapse v1.57.0 includes a change to the way transaction IDs are managed for application services. If your deployment uses a dedicated worker for application service traffic, **it must be stopped** when the database is upgraded (which normally happens when the main process is upgraded), to ensure the change is made safely without any risk of reusing transaction IDs." msgstr "" -#: ../../../CHANGELOG.md:2354 +#: ../../../CHANGELOG.md:2961 msgid "If you're not running an `appservice` worker (`matrix_synapse_workers_preset: little-federation-helper` or `matrix_synapse_workers_appservice_workers_count: 0`), you are probably safe to upgrade as per normal, without taking any special care." msgstr "" -#: ../../../CHANGELOG.md:2356 +#: ../../../CHANGELOG.md:2963 msgid "If you are running a setup with an `appservice` worker, or otherwise want to be on the safe side, we recommend the following upgrade path:" msgstr "" -#: ../../../CHANGELOG.md:2358 +#: ../../../CHANGELOG.md:2965 msgid "Pull the latest playbook changes" msgstr "" -#: ../../../CHANGELOG.md:2359 +#: ../../../CHANGELOG.md:2966 msgid "Stop all services (`ansible-playbook -i inventory/hosts setup.yml --tags=stop`)" msgstr "" -#: ../../../CHANGELOG.md:2360 +#: ../../../CHANGELOG.md:2967 msgid "Re-run the playbook (`ansible-playbook -i inventory/hosts setup.yml --tags=setup-all`)" msgstr "" -#: ../../../CHANGELOG.md:2361 +#: ../../../CHANGELOG.md:2968 msgid "Start Postgres (`systemctl start matrix-postgres` on the server)" msgstr "" -#: ../../../CHANGELOG.md:2362 +#: ../../../CHANGELOG.md:2969 msgid "Start the main Synapse process (`systemctl start matrix-synapse` on the server)" msgstr "" -#: ../../../CHANGELOG.md:2363 +#: ../../../CHANGELOG.md:2970 msgid "Wait a while so that Synapse can start and complete the database migrations. You can use `journalctl -fu matrix-synapse` on the server to get a clue. Waiting a few minutes should also be enough." msgstr "" -#: ../../../CHANGELOG.md:2364 +#: ../../../CHANGELOG.md:2971 msgid "It should now be safe to start all other services. `ansible-playbook -i inventory/hosts setup.yml --tags=start` will do it for you" msgstr "" -#: ../../../CHANGELOG.md:2367 +#: ../../../CHANGELOG.md:2974 msgid "2022-04-14" msgstr "" -#: ../../../CHANGELOG.md:2369 +#: ../../../CHANGELOG.md:2976 msgid "(Compatibility Break) Changes to `docker-src` permissions necessitating manual action" msgstr "" -#: ../../../CHANGELOG.md:2371 +#: ../../../CHANGELOG.md:2978 msgid "Users who build container images from source will need to manually correct file permissions of some directories on the server." msgstr "" -#: ../../../CHANGELOG.md:2373 +#: ../../../CHANGELOG.md:2980 msgid "When self-building, the playbook used to `git clone` repositories (into `/matrix/SERVICE/docker-src`) using the `root` user, but now uses `matrix` instead to work around [the following issue with git 2.35.2](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1749)." msgstr "" -#: ../../../CHANGELOG.md:2375 +#: ../../../CHANGELOG.md:2982 msgid "If you're on a non-`amd64` architecture (that is, you're overriding `matrix_architecture` in your `vars.yml` file) or you have enabled self-building for some service (e.g. `matrix_*_self_build: true`), you're certainly building some container images from source and have `docker-src` directories with mixed permissions lying around in various `/matrix/SERVICE` directories." msgstr "" -#: ../../../CHANGELOG.md:2377 +#: ../../../CHANGELOG.md:2984 msgid "The playbook *could* correct these permissions automatically, but that requires additional Ansible tasks in some ~45 different places — something that takes considerable effort. So we ask users observing errors related to `docker-src` directories to correct the problem manually by **running this command on the Matrix server** (which deletes all `/matrix/*/docker-src` directories): `find /matrix -maxdepth 2 -name 'docker-src' | xargs rm -rf`" msgstr "" -#: ../../../CHANGELOG.md:2380 +#: ../../../CHANGELOG.md:2987 msgid "2022-03-17" msgstr "" -#: ../../../CHANGELOG.md:2382 +#: ../../../CHANGELOG.md:2989 msgid "(Compatibility Break) ma1sd identity server no longer installed by default" msgstr "" -#: ../../../CHANGELOG.md:2384 +#: ../../../CHANGELOG.md:2991 msgid "The playbook no longer installs the [ma1sd](https://github.com/ma1uta/ma1sd) identity server by default. The next time you run the playbook, ma1sd will be uninstalled from your server, unless you explicitly enable the ma1sd service (see how below)." msgstr "" -#: ../../../CHANGELOG.md:2386 +#: ../../../CHANGELOG.md:2993 msgid "The main reason we used to install ma1sd by default in the past was to prevent Element clients from talking to the `matrix.org` / `vector.im` identity servers, by forcing it to talk to our own self-hosted (but otherwise useless) identity server instead, thus preventing contact list leaks." msgstr "" -#: ../../../CHANGELOG.md:2388 +#: ../../../CHANGELOG.md:2995 msgid "Since Element clients no longer default to using a public identity server if another one is not provided, we can stop installing ma1sd." msgstr "" -#: ../../../CHANGELOG.md:2390 +#: ../../../CHANGELOG.md:2997 msgid "If you need to install the ma1sd identity server for some reason, you can explicitly enable it by adding this to your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:2397 +#: ../../../CHANGELOG.md:3004 msgid "2022-02-12" msgstr "" -#: ../../../CHANGELOG.md:2399 +#: ../../../CHANGELOG.md:3006 msgid "matrix_encryption_disabler support" msgstr "" -#: ../../../CHANGELOG.md:2401 +#: ../../../CHANGELOG.md:3008 msgid "We now support installing the [matrix_encryption_disabler](https://github.com/digitalentity/matrix_encryption_disabler) Synapse module, which lets you prevent End-to-End-Encryption from being enabled by users on your homeserver. The popular opinion is that this is dangerous and shouldn't be done, but there are valid use cases for disabling encryption discussed [here](https://github.com/matrix-org/synapse/issues/4401)." msgstr "" -#: ../../../CHANGELOG.md:2403 +#: ../../../CHANGELOG.md:3010 msgid "To enable this module (and prevent encryption from being used on your homserver), add `matrix_synapse_ext_encryption_disabler_enabled: true` to your configuration. This module provides further customization. Check its other configuration settings (and defaults) in `roles/custom/matrix-synapse/defaults/main.yml`." msgstr "" -#: ../../../CHANGELOG.md:2406 +#: ../../../CHANGELOG.md:3013 msgid "2022-02-01" msgstr "" -#: ../../../CHANGELOG.md:2408 +#: ../../../CHANGELOG.md:3015 msgid "matrix-hookshot bridging support" msgstr "" -#: ../../../CHANGELOG.md:2410 +#: ../../../CHANGELOG.md:3017 msgid "Thanks to [HarHarLinks](https://github.com/HarHarLinks), the playbook can now install the [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) bridge for bridging Matrix to multiple project management services, such as GitHub, GitLab and JIRA. See our [Setting up matrix-hookshot](docs/configuring-playbook-bridge-hookshot.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2413 +#: ../../../CHANGELOG.md:3020 msgid "2022-01-31" msgstr "" -#: ../../../CHANGELOG.md:2415 +#: ../../../CHANGELOG.md:3022 msgid "ARM support for matrix-corporal" msgstr "" -#: ../../../CHANGELOG.md:2417 +#: ../../../CHANGELOG.md:3024 msgid "[matrix-corporal](https://github.com/devture/matrix-corporal) (as of version `2.2.3`) is now published to Docker Hub (see [devture/matrix-corporal](https://hub.docker.com/r/devture/matrix-corporal)) as a multi-arch container image with support for all these platforms: `linux/amd64`, `linux/arm64/v8` and `linux/arm/v7`. The playbook no longer resorts to self-building matrix-corporal on these ARM architectures." msgstr "" -#: ../../../CHANGELOG.md:2420 +#: ../../../CHANGELOG.md:3027 msgid "2022-01-07" msgstr "" -#: ../../../CHANGELOG.md:2422 +#: ../../../CHANGELOG.md:3029 msgid "Dendrite support" msgstr "" -#: ../../../CHANGELOG.md:2424 +#: ../../../CHANGELOG.md:3031 msgid "**TLDR**: We now have optional experimental [Dendrite](https://github.com/matrix-org/dendrite) homeserver support for new installations. **Existing (Synapse) installations need to be updated**, because some internals changed. See [Adapting the configuration for existing Synapse installations](#adapting-the-configuration-for-existing-synapse-installations)." msgstr "" -#: ../../../CHANGELOG.md:2426 +#: ../../../CHANGELOG.md:3033 msgid "[Jip J. Dekker](https://github.com/Dekker1) did the [initial work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/818) of adding [Dendrite](https://github.com/matrix-org/dendrite) support to the playbook back in January 2021. Lots of work (and time) later, Dendrite support is finally ready for testing." msgstr "" -#: ../../../CHANGELOG.md:2428 +#: ../../../CHANGELOG.md:3035 msgid "We believe that 2022 will be the year of the non-Synapse Matrix server!" msgstr "" -#: ../../../CHANGELOG.md:2430 +#: ../../../CHANGELOG.md:3037 msgid "The playbook was previously quite [Synapse](https://github.com/element-hq/synapse)-centric, but can now accommodate multiple homeserver implementations. Only one homeserver implementation can be active (installed) at a given time." msgstr "" -#: ../../../CHANGELOG.md:2432 +#: ../../../CHANGELOG.md:3039 msgid "**Synapse is still the default homeserver implementation** installed by the playbook. A new variable (`matrix_homeserver_implementation`) controls which server implementation is enabled (`synapse` or `dendrite` at the given moment)." msgstr "" -#: ../../../CHANGELOG.md:2434 +#: ../../../CHANGELOG.md:3041 msgid "Adapting the configuration for existing Synapse installations" msgstr "" -#: ../../../CHANGELOG.md:2436 +#: ../../../CHANGELOG.md:3043 msgid "Because the playbook is not so Synapse-centric anymore, a small configuration change is necessary for existing installations to bring them up to date." msgstr "" -#: ../../../CHANGELOG.md:2438 +#: ../../../CHANGELOG.md:3045 msgid "The `vars.yml` file for **existing installations will need to be updated** by adding this **additional configuration**:" msgstr "" -#: ../../../CHANGELOG.md:2450 +#: ../../../CHANGELOG.md:3057 msgid "Trying out Dendrite" msgstr "" -#: ../../../CHANGELOG.md:2452 +#: ../../../CHANGELOG.md:3059 msgid "Finally, **to try out Dendrite**, we recommend that you **use a new server** and the following addition to your `vars.yml` configuration:" msgstr "" -#: ../../../CHANGELOG.md:2458 +#: ../../../CHANGELOG.md:3065 msgid "**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse to Dendrite) without data loss." msgstr "" -#: ../../../CHANGELOG.md:2460 +#: ../../../CHANGELOG.md:3067 msgid "We're excited to gain support for other homeserver implementations, like [Conduit](https://conduit.rs/), etc!" msgstr "" -#: ../../../CHANGELOG.md:2462 +#: ../../../CHANGELOG.md:3069 msgid "Honoroit bot support" msgstr "" -#: ../../../CHANGELOG.md:2464 +#: ../../../CHANGELOG.md:3071 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now help you set up [Honoroit](https://github.com/etkecc/honoroit) — a helpdesk bot." msgstr "" -#: ../../../CHANGELOG.md:2466 +#: ../../../CHANGELOG.md:3073 msgid "See our [Setting up Honoroit](docs/configuring-playbook-bot-honoroit.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:2469 +#: ../../../CHANGELOG.md:3076 msgid "2022-01-06" msgstr "" -#: ../../../CHANGELOG.md:2471 +#: ../../../CHANGELOG.md:3078 msgid "Cinny support" msgstr "" -#: ../../../CHANGELOG.md:2473 +#: ../../../CHANGELOG.md:3080 msgid "Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook now supports [Cinny](https://cinny.in/) — a new simple, elegant and secure Matrix client." msgstr "" -#: ../../../CHANGELOG.md:2475 +#: ../../../CHANGELOG.md:3082 msgid "By default, we still install Element Web. Still, people who'd like to try Cinny out can now install it via the playbook." msgstr "" -#: ../../../CHANGELOG.md:2477 +#: ../../../CHANGELOG.md:3084 msgid "Additional details are available in [Setting up Cinny](docs/configuring-playbook-client-cinny.md)." msgstr "" -#: ../../../CHANGELOG.md:2480 +#: ../../../CHANGELOG.md:3087 msgid "2021-12-22" msgstr "" -#: ../../../CHANGELOG.md:2482 +#: ../../../CHANGELOG.md:3089 msgid "Twitter bridging support via mautrix-twitter" msgstr "" -#: ../../../CHANGELOG.md:2484 +#: ../../../CHANGELOG.md:3091 msgid "Thanks to [Matthew Cengia](https://github.com/mattcen) and [Shreyas Ajjarapu](https://github.com/shreyasajj), besides [mx-puppet-twitter](docs/configuring-playbook-bridge-mx-puppet-twitter.md), bridging to [Twitter](https://twitter.com/) can now also happen with [mautrix-twitter](docs/configuring-playbook-bridge-mautrix-twitter.md)." msgstr "" -#: ../../../CHANGELOG.md:2487 +#: ../../../CHANGELOG.md:3094 msgid "2021-12-14" msgstr "" -#: ../../../CHANGELOG.md:2489 +#: ../../../CHANGELOG.md:3096 msgid "(Security) Users of the Signal bridge may wish to upgrade it to work around log4j vulnerability" msgstr "" -#: ../../../CHANGELOG.md:2491 +#: ../../../CHANGELOG.md:3098 msgid "Recently, a security vulnerability affecting the Java logging package `log4j` [has been discovered](https://www.huntress.com/blog/rapid-response-critical-rce-vulnerability-is-affecting-java). Software that uses this Java package is potentially vulnerable." msgstr "" -#: ../../../CHANGELOG.md:2493 +#: ../../../CHANGELOG.md:3100 msgid "One such piece of software that is part of the playbook is the [mautrix-signal bridge](./docs/configuring-playbook-bridge-mautrix-signal.md), which [has been patched already](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1452). If you're running this bridge, you may wish to [upgrade](./docs/maintenance-upgrading-services.md)." msgstr "" -#: ../../../CHANGELOG.md:2496 +#: ../../../CHANGELOG.md:3103 msgid "2021-11-11" msgstr "" -#: ../../../CHANGELOG.md:2498 +#: ../../../CHANGELOG.md:3105 msgid "Dropped support for Postgres v9.6" msgstr "" -#: ../../../CHANGELOG.md:2500 +#: ../../../CHANGELOG.md:3107 msgid "Postgres v9.6 reached its end of life today, so the playbook will refuse to run for you if you're still on that version." msgstr "" -#: ../../../CHANGELOG.md:2502 +#: ../../../CHANGELOG.md:3109 msgid "Synapse still supports v9.6 (for now), but we're retiring support for it early, to avoid having to maintain support for so many Postgres versions. Users that are still on Postgres v9.6 can easily [upgrade Postgres](docs/maintenance-postgres.md#upgrading-postgresql) via the playbook." msgstr "" -#: ../../../CHANGELOG.md:2505 +#: ../../../CHANGELOG.md:3112 msgid "2021-10-23" msgstr "" -#: ../../../CHANGELOG.md:2507 +#: ../../../CHANGELOG.md:3114 msgid "Hangouts bridge no longer updated, superseded by a Googlechat bridge" msgstr "" -#: ../../../CHANGELOG.md:2509 +#: ../../../CHANGELOG.md:3116 msgid "The mautrix-hangouts bridge is no longer receiving updates upstream and is likely to stop working in the future. We still retain support for this bridge in the playbook, but you're encouraged to switch away from it." msgstr "" -#: ../../../CHANGELOG.md:2511 +#: ../../../CHANGELOG.md:3118 msgid "There's a new [mautrix-googlechat](https://github.com/mautrix/googlechat) bridge that you can [install using the playbook](docs/configuring-playbook-bridge-mautrix-googlechat.md). Your **Hangouts bridge data will not be migrated**, however. You need to start fresh with the new bridge." msgstr "" -#: ../../../CHANGELOG.md:2514 +#: ../../../CHANGELOG.md:3121 msgid "2021-08-23" msgstr "" -#: ../../../CHANGELOG.md:2516 +#: ../../../CHANGELOG.md:3123 msgid "LinkedIn bridging support via beeper-linkedin" msgstr "" -#: ../../../CHANGELOG.md:2518 +#: ../../../CHANGELOG.md:3125 msgid "Thanks to [Alexandar Mechev](https://github.com/apmechev), the playbook can now install the [beeper-linkedin](https://gitlab.com/beeper/linkedin) bridge for bridging to [LinkedIn](https://www.linkedin.com/) Messaging." msgstr "" -#: ../../../CHANGELOG.md:2520 +#: ../../../CHANGELOG.md:3127 msgid "This brings the total number of bridges supported by the playbook up to 20. See all supported bridges [here](docs/configuring-playbook.md#bridging-other-networks)." msgstr "" -#: ../../../CHANGELOG.md:2522 +#: ../../../CHANGELOG.md:3129 msgid "To get started with bridging to LinkedIn, see [Setting up Beeper LinkedIn bridging](docs/configuring-playbook-bridge-beeper-linkedin.md)." msgstr "" -#: ../../../CHANGELOG.md:2525 +#: ../../../CHANGELOG.md:3132 msgid "2021-08-20" msgstr "" -#: ../../../CHANGELOG.md:2527 +#: ../../../CHANGELOG.md:3134 msgid "Sygnal upgraded — ARM support and no longer requires a database" msgstr "" -#: ../../../CHANGELOG.md:2529 +#: ../../../CHANGELOG.md:3136 msgid "The [Sygnal](docs/configuring-playbook-sygnal.md) push gateway has been upgraded from `v0.9.0` to `v0.10.1`." msgstr "" -#: ../../../CHANGELOG.md:2531 +#: ../../../CHANGELOG.md:3138 msgid "This is an optional component for the playbook, so most of our users wouldn't care about this announcement." msgstr "" -#: ../../../CHANGELOG.md:2533 +#: ../../../CHANGELOG.md:3140 msgid "Since this feels like a relatively big (and untested, as of yet) Sygnal change, we're putting up this changelog entry." msgstr "" -#: ../../../CHANGELOG.md:2535 +#: ../../../CHANGELOG.md:3142 msgid "The new version is also available for the ARM architecture. It also no longer requires a database anymore. If you need to downgrade to the previous version, changing `matrix_sygnal_version` or `matrix_sygnal_docker_image` will not be enough, as we've removed the `database` configuration completely. You'd need to switch to an earlier playbook commit." msgstr "" -#: ../../../CHANGELOG.md:2538 +#: ../../../CHANGELOG.md:3145 msgid "2021-05-21" msgstr "" -#: ../../../CHANGELOG.md:2540 +#: ../../../CHANGELOG.md:3147 msgid "Hydrogen support" msgstr "" -#: ../../../CHANGELOG.md:2542 +#: ../../../CHANGELOG.md:3149 msgid "Thanks to [Aaron Raimist](https://github.com/aaronraimist), the playbook now supports [Hydrogen](https://github.com/vector-im/hydrogen-web) — a new lightweight Matrix client with legacy and mobile browser support." msgstr "" -#: ../../../CHANGELOG.md:2544 +#: ../../../CHANGELOG.md:3151 msgid "By default, we still install Element Web, as Hydrogen is still not fully-featured. Still, people who'd like to try Hydrogen out can now install it via the playbook." msgstr "" -#: ../../../CHANGELOG.md:2546 +#: ../../../CHANGELOG.md:3153 msgid "Additional details are available in [Setting up Hydrogen](docs/configuring-playbook-client-hydrogen.md)." msgstr "" -#: ../../../CHANGELOG.md:2549 +#: ../../../CHANGELOG.md:3156 msgid "2021-05-19" msgstr "" -#: ../../../CHANGELOG.md:2551 +#: ../../../CHANGELOG.md:3158 msgid "Heisenbridge support" msgstr "" -#: ../../../CHANGELOG.md:2553 +#: ../../../CHANGELOG.md:3160 msgid "Thanks to [Toni Spets (hifi)](https://github.com/hifi), the playbook now supports bridging to [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) using yet another bridge (besides matrix-appservice-irc), called [Heisenbridge](https://github.com/hifi/heisenbridge)." msgstr "" -#: ../../../CHANGELOG.md:2555 +#: ../../../CHANGELOG.md:3162 msgid "Additional details are available in [Setting up Heisenbridge bouncer-style IRC bridging](docs/configuring-playbook-bridge-heisenbridge.md)." msgstr "" -#: ../../../CHANGELOG.md:2558 +#: ../../../CHANGELOG.md:3165 msgid "2021-04-16" msgstr "" -#: ../../../CHANGELOG.md:2560 +#: ../../../CHANGELOG.md:3167 msgid "Disabling TLSv1 and TLSv1.1 for coturn" msgstr "" -#: ../../../CHANGELOG.md:2562 +#: ../../../CHANGELOG.md:3169 msgid "To improve security, we've [removed TLSv1 and TLSv1.1 support](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/999) from our default [coturn](https://github.com/coturn/coturn) configuration." msgstr "" -#: ../../../CHANGELOG.md:2564 +#: ../../../CHANGELOG.md:3171 msgid "If you need to support old clients, you can re-enable both (or whichever one you need) with the following configuration:" msgstr "" -#: ../../../CHANGELOG.md:2572 +#: ../../../CHANGELOG.md:3179 msgid "2021-04-05" msgstr "" -#: ../../../CHANGELOG.md:2574 +#: ../../../CHANGELOG.md:3181 msgid "Automated local Postgres backup support" msgstr "" -#: ../../../CHANGELOG.md:2576 +#: ../../../CHANGELOG.md:3183 msgid "Thanks to [foxcris](https://github.com/foxcris), the playbook can now make automated local Postgres backups on a fixed schedule using [docker-postgres-backup-local](https://github.com/prodrigestivill/docker-postgres-backup-local)." msgstr "" -#: ../../../CHANGELOG.md:2578 +#: ../../../CHANGELOG.md:3185 msgid "Additional details are available in [Setting up Postgres backup](docs/configuring-playbook-postgres-backup.md)." msgstr "" -#: ../../../CHANGELOG.md:2581 +#: ../../../CHANGELOG.md:3188 msgid "2021-04-03" msgstr "" -#: ../../../CHANGELOG.md:2583 +#: ../../../CHANGELOG.md:3190 msgid "Mjolnir moderation tool (bot) support" msgstr "" -#: ../../../CHANGELOG.md:2585 +#: ../../../CHANGELOG.md:3192 msgid "Thanks to [Aaron Raimist](https://github.com/aaronraimist), the playbook can now install and configure the [Mjolnir](https://github.com/matrix-org/mjolnir) moderation tool (bot)." msgstr "" -#: ../../../CHANGELOG.md:2587 +#: ../../../CHANGELOG.md:3194 msgid "Additional details are available in [Setting up Mjolnir](docs/configuring-playbook-bot-mjolnir.md)." msgstr "" -#: ../../../CHANGELOG.md:2590 +#: ../../../CHANGELOG.md:3197 msgid "2021-03-20" msgstr "" -#: ../../../CHANGELOG.md:2592 +#: ../../../CHANGELOG.md:3199 msgid "Sygnal push gateway support" msgstr "" -#: ../../../CHANGELOG.md:2594 +#: ../../../CHANGELOG.md:3201 msgid "The playbook can now install the [Sygnal](https://github.com/matrix-org/sygnal) push gateway for you." msgstr "" -#: ../../../CHANGELOG.md:2596 +#: ../../../CHANGELOG.md:3203 msgid "This is only useful to people who develop/build their own Matrix client applications." msgstr "" -#: ../../../CHANGELOG.md:2598 +#: ../../../CHANGELOG.md:3205 msgid "Additional details are available in our [Setting up the Sygnal push gateway](docs/configuring-playbook-sygnal.md) docs." msgstr "" -#: ../../../CHANGELOG.md:2601 +#: ../../../CHANGELOG.md:3208 msgid "2021-03-16" msgstr "" -#: ../../../CHANGELOG.md:2603 +#: ../../../CHANGELOG.md:3210 msgid "Go-NEB support" msgstr "" -#: ../../../CHANGELOG.md:2605 +#: ../../../CHANGELOG.md:3212 msgid "Thanks to [Zir0h](https://github.com/Zir0h), the playbook can now install and configure the [Go-NEB](https://github.com/matrix-org/go-neb) bot." msgstr "" -#: ../../../CHANGELOG.md:2607 +#: ../../../CHANGELOG.md:3214 msgid "Additional details are available in [Setting up Go-NEB](docs/configuring-playbook-bot-go-neb.md)." msgstr "" -#: ../../../CHANGELOG.md:2610 +#: ../../../CHANGELOG.md:3217 msgid "2021-02-19" msgstr "" -#: ../../../CHANGELOG.md:2612 +#: ../../../CHANGELOG.md:3219 msgid "GroupMe bridging support via mx-puppet-groupme" msgstr "" -#: ../../../CHANGELOG.md:2614 +#: ../../../CHANGELOG.md:3221 msgid "Thanks to [Cody Neiman](https://github.com/xangelix), the playbook can now install the [mx-puppet-groupme](https://gitlab.com/robintown/mx-puppet-groupme) bridge for bridging to [GroupMe](https://groupme.com)." msgstr "" -#: ../../../CHANGELOG.md:2616 +#: ../../../CHANGELOG.md:3223 msgid "This brings the total number of bridges supported by the playbook up to 18. See all supported bridges [here](docs/configuring-playbook.md#bridging-other-networks)." msgstr "" -#: ../../../CHANGELOG.md:2618 +#: ../../../CHANGELOG.md:3225 msgid "To get started, follow our [Setting up MX Puppet GroupMe](docs/configuring-playbook-bridge-mx-puppet-groupme.md) docs." msgstr "" -#: ../../../CHANGELOG.md:2620 +#: ../../../CHANGELOG.md:3227 msgid "Mautrix Instagram bridging support" msgstr "" -#: ../../../CHANGELOG.md:2622 +#: ../../../CHANGELOG.md:3229 msgid "The playbook now supports bridging with [Instagram](https://www.instagram.com/) by installing the [mautrix-instagram](https://github.com/tulir/mautrix-instagram) bridge. This playbook functionality is available thanks to [@MarcProe](https://github.com/MarcProe)." msgstr "" -#: ../../../CHANGELOG.md:2624 +#: ../../../CHANGELOG.md:3231 msgid "Additional details are available in [Setting up Mautrix Instagram bridging](docs/configuring-playbook-bridge-mautrix-instagram.md)." msgstr "" -#: ../../../CHANGELOG.md:2626 +#: ../../../CHANGELOG.md:3233 msgid "Synapse workers support" msgstr "" -#: ../../../CHANGELOG.md:2628 +#: ../../../CHANGELOG.md:3235 msgid "After [lots and lots of work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/456) (done over many months by [Marcel Partap](https://github.com/eMPee584), [Max Klenk](https://github.com/maxklenk), a few others from the [Technical University of Dresden, Germany](https://tu-dresden.de/) and various other contributors), support for Synapse workers has finally landed." msgstr "" -#: ../../../CHANGELOG.md:2630 +#: ../../../CHANGELOG.md:3237 msgid "Having support for workers makes the playbook suitable for larger homeserver deployments." msgstr "" -#: ../../../CHANGELOG.md:2632 +#: ../../../CHANGELOG.md:3239 msgid "Our setup is not yet perfect (we don't support all types of workers; scaling some of them (like `pusher`, `federation_sender`) beyond a single instance is not yet supported). Still, it's a great start and can already power homeservers with thousands of users, like the [Matrix deployment at TU Dresden](https://doc.matrix.tu-dresden.de/en/) discussed in [Matrix Live S06E09 — TU Dresden on their Matrix deployment](https://www.youtube.com/watch?v=UHJX2pmT2gk)." msgstr "" -#: ../../../CHANGELOG.md:2634 +#: ../../../CHANGELOG.md:3241 msgid "By default, workers are disabled and Synapse runs as a single process (homeservers don't necessarily need the complexity and increased memory requirements of running a worker-based setup)." msgstr "" -#: ../../../CHANGELOG.md:2636 +#: ../../../CHANGELOG.md:3243 msgid "To enable Synapse workers, follow our [Load balancing with workers](docs/configuring-playbook-synapse.md#load-balancing-with-workers) documentation." msgstr "" -#: ../../../CHANGELOG.md:2639 +#: ../../../CHANGELOG.md:3246 msgid "2021-02-12" msgstr "" -#: ../../../CHANGELOG.md:2641 +#: ../../../CHANGELOG.md:3248 msgid "(Potential Breaking Change) Monitoring/metrics support using Prometheus and Grafana" msgstr "" -#: ../../../CHANGELOG.md:2643 +#: ../../../CHANGELOG.md:3250 msgid "Thanks to [@Peetz0r](https://github.com/Peetz0r), the playbook can now install a bunch of tools for monitoring your Matrix server: the [Prometheus](https://prometheus.io) time-series database server, the Prometheus [node-exporter](https://prometheus.io/docs/guides/node-exporter/) host metrics exporter, and the [Grafana](https://grafana.com/) web UI." msgstr "" -#: ../../../CHANGELOG.md:2645 +#: ../../../CHANGELOG.md:3252 msgid "To get get these installed, follow our [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](docs/configuring-playbook-prometheus-grafana.md) docs page." msgstr "" -#: ../../../CHANGELOG.md:2647 +#: ../../../CHANGELOG.md:3254 msgid "This update comes with a **potential breaking change** for people who were already exposing Synapse metrics (for consumption via another Prometheus installation). From now on, `matrix_synapse_metrics_enabled: true` no longer exposes metrics publicly via matrix-nginx-proxy (at `https://matrix.example.com/_synapse/metrics`). To do so, you'd need to explicitly set `matrix_nginx_proxy_proxy_synapse_metrics: true`." msgstr "" -#: ../../../CHANGELOG.md:2650 +#: ../../../CHANGELOG.md:3257 msgid "2021-01-31" msgstr "" -#: ../../../CHANGELOG.md:2652 +#: ../../../CHANGELOG.md:3259 msgid "Etherpad support" msgstr "" -#: ../../../CHANGELOG.md:2654 +#: ../../../CHANGELOG.md:3261 msgid "Thanks to [@pushytoxin](https://github.com/pushytoxin), the playbook can now install the [Etherpad](https://etherpad.org) realtime collaborative text editor. It can be used in a [Jitsi](https://jitsi.org/) audio/video call or integrated as a widget into Matrix chat rooms via the [Dimension](https://dimension.t2bot.io) integration manager." msgstr "" -#: ../../../CHANGELOG.md:2656 +#: ../../../CHANGELOG.md:3263 msgid "To get it installed, follow [our Etherpad docs page](docs/configuring-playbook-etherpad.md)." msgstr "" -#: ../../../CHANGELOG.md:2659 +#: ../../../CHANGELOG.md:3266 msgid "2021-01-22" msgstr "" -#: ../../../CHANGELOG.md:2661 +#: ../../../CHANGELOG.md:3268 msgid "(Breaking Change) Postgres changes that require manual intervention" msgstr "" -#: ../../../CHANGELOG.md:2663 +#: ../../../CHANGELOG.md:3270 msgid "We've made a lot of changes to our Postgres setup and some manual action is required (described below). Sorry about the hassle." msgstr "" -#: ../../../CHANGELOG.md:2665 +#: ../../../CHANGELOG.md:3272 msgid "**TLDR**: people running an [external Postgres server](docs/configuring-playbook-external-postgres.md) don't need to change anything for now. Everyone else (the common/default case) is affected and manual intervention is required." msgstr "" -#: ../../../CHANGELOG.md:2667 +#: ../../../CHANGELOG.md:3274 msgid "Why?" msgstr "" -#: ../../../CHANGELOG.md:2669 +#: ../../../CHANGELOG.md:3276 msgid "we had a default Postgres password (`matrix_postgres_connection_password: synapse-password`), which we think is **not ideal for security anymore**. We now ask you to generate/provide a strong password yourself. Postgres is normally not exposed outside the container network, making it relatively secure, but still:" msgstr "" -#: ../../../CHANGELOG.md:2670 +#: ../../../CHANGELOG.md:3277 msgid "by tweaking the configuration, you may end up intentionally or unintentionally exposing your Postgres server to the local network (or even publicly), while still using the default default credentials (`synapse` + `synapse-password`)" msgstr "" -#: ../../../CHANGELOG.md:2671 +#: ../../../CHANGELOG.md:3278 msgid "we can't be sure we trust all these services (bridges, etc). Some of them may try to talk to or attack `matrix-postgres` using the default credentials (`synapse` + `synapse-password`)" msgstr "" -#: ../../../CHANGELOG.md:2672 +#: ../../../CHANGELOG.md:3279 msgid "you may have other containers running on the same Docker network, which may try to talk to or attack `matrix-postgres` using the default credentials (`synapse` + `synapse-password`)" msgstr "" -#: ../../../CHANGELOG.md:2673 +#: ../../../CHANGELOG.md:3280 msgid "our Postgres usage **was overly-focused on Synapse** (default username of `synapse` and default/main database of `homeserver`). Additional homeserver options are likely coming in the future ([Dendrite](https://matrix.org/docs/projects/server/dendrite), [Conduit](https://matrix.org/docs/projects/server/conduit), [The Construct](https://matrix.org/docs/projects/server/construct)), so being too focused on `matrix-synapse` is not great. From now on, Synapse is just another component of this playbook, which happens to have an *additional database* (called `synapse`) on the Postgres server." msgstr "" -#: ../../../CHANGELOG.md:2674 +#: ../../../CHANGELOG.md:3281 msgid "we try to reorganize things a bit, to make the playbook even friendlier to people running an [external Postgres server](docs/configuring-playbook-external-postgres.md). Work on this will proceed in the future." msgstr "" -#: ../../../CHANGELOG.md:2676 +#: ../../../CHANGELOG.md:3283 msgid "So, this is some **effort to improve security** and to **prepare for a brighter future of having more homeserver options** than just Synapse." msgstr "" -#: ../../../CHANGELOG.md:2678 +#: ../../../CHANGELOG.md:3285 msgid "What has really changed?" msgstr "" -#: ../../../CHANGELOG.md:2680 +#: ../../../CHANGELOG.md:3287 msgid "the default superuser Postgres username is now `matrix` (used to be `synapse`)" msgstr "" -#: ../../../CHANGELOG.md:2681 +#: ../../../CHANGELOG.md:3288 msgid "the default Postgres database is now `matrix` (used to be `homeserver`)" msgstr "" -#: ../../../CHANGELOG.md:2682 +#: ../../../CHANGELOG.md:3289 msgid "Synapse's database is now `synapse` (used to be `homeserver`). This is now just another \"additional database\" that the playbook manages for you" msgstr "" -#: ../../../CHANGELOG.md:2683 +#: ../../../CHANGELOG.md:3290 msgid "Synapse's user called `synapse` is just a regular user that can only use the `synapse` database (not a superuser anymore)" msgstr "" -#: ../../../CHANGELOG.md:2685 +#: ../../../CHANGELOG.md:3292 msgid "What do I do if I'm using the integrated Postgres server (default)?" msgstr "" -#: ../../../CHANGELOG.md:2687 +#: ../../../CHANGELOG.md:3294 msgid "By default, the playbook runs an integrated Postgres server for you in a container (`matrix-postgres`). Unless you've explicitly configured an [external Postgres server](docs/configuring-playbook-external-postgres.md), these steps are meant for you." msgstr "" -#: ../../../CHANGELOG.md:2689 +#: ../../../CHANGELOG.md:3296 msgid "To migrate to the new setup, expect a few minutes of downtime, while you follow these steps:" msgstr "" -#: ../../../CHANGELOG.md:2691 +#: ../../../CHANGELOG.md:3298 msgid "We believe the steps below are safe and you won't encounter any data loss, but consider [making a Postgres backup](docs/maintenance-postgres.md#backing-up-postgresql) anyway. If you've never backed up Postgres, now would be a good time to try it." msgstr "" -#: ../../../CHANGELOG.md:2693 +#: ../../../CHANGELOG.md:3300 msgid "Generate a strong password to be used for your superuser Postgres user (called `matrix`). You can create one with a command like `pwgen -s 64 1`. The **maximum length** for a Postgres password is 100 bytes (characters). Don't go crazy!" msgstr "" -#: ../../../CHANGELOG.md:2695 +#: ../../../CHANGELOG.md:3302 msgid "Update your playbook's `inventory/host_vars/matrix.example.com/vars.yml` file, adding a line like this:" msgstr "" -#: ../../../CHANGELOG.md:2700 -#: ../../../CHANGELOG.md:2712 +#: ../../../CHANGELOG.md:3307 +#: ../../../CHANGELOG.md:3319 msgid "… where `YOUR_POSTGRES_PASSWORD_HERE` is to be replaced with the password you generated during step #2." msgstr "" -#: ../../../CHANGELOG.md:2702 +#: ../../../CHANGELOG.md:3309 msgid "Stop all services: `ansible-playbook -i inventory/hosts setup.yml --tags=stop`" msgstr "" -#: ../../../CHANGELOG.md:2703 +#: ../../../CHANGELOG.md:3310 msgid "Log in to the server via SSH. The next commands will be performed there." msgstr "" -#: ../../../CHANGELOG.md:2704 +#: ../../../CHANGELOG.md:3311 msgid "Start the Postgres database server: `systemctl start matrix-postgres`" msgstr "" -#: ../../../CHANGELOG.md:2705 +#: ../../../CHANGELOG.md:3312 msgid "Open a Postgres shell: `/usr/local/bin/matrix-postgres-cli`" msgstr "" -#: ../../../CHANGELOG.md:2706 +#: ../../../CHANGELOG.md:3313 msgid "Execute the following query, while making sure to **change the password inside** (**don't forget the ending `;`**):" msgstr "" -#: ../../../CHANGELOG.md:2714 +#: ../../../CHANGELOG.md:3321 msgid "Execute the following queries as you see them (no modifications necessary, so you can just **paste them all at once**):" msgstr "" -#: ../../../CHANGELOG.md:2732 +#: ../../../CHANGELOG.md:3339 msgid "You may need to press *Enter* after pasting the lines above." msgstr "" -#: ../../../CHANGELOG.md:2734 +#: ../../../CHANGELOG.md:3341 msgid "Re-run the playbook normally: `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start`" msgstr "" -#: ../../../CHANGELOG.md:2736 +#: ../../../CHANGELOG.md:3343 msgid "What do I do if I'm using an external Postgres server?" msgstr "" -#: ../../../CHANGELOG.md:2738 +#: ../../../CHANGELOG.md:3345 msgid "If you've explicitly configured an [external Postgres server](docs/configuring-playbook-external-postgres.md), there are **no changes** that you need to do at this time." msgstr "" -#: ../../../CHANGELOG.md:2740 +#: ../../../CHANGELOG.md:3347 msgid "The fact that we've renamed Synapse's database from `homeserver` to `synapse` (in our defaults) should not affect you, as you're already explicitly defining `matrix_synapse_database_database` (if you've followed our guide, that is). If you're not explicitly defining this variable, you may wish to do so (`matrix_synapse_database_database: homeserver`), to avoid the new `synapse` default and keep things as they were." msgstr "" -#: ../../../CHANGELOG.md:2743 +#: ../../../CHANGELOG.md:3350 msgid "2021-01-20" msgstr "" -#: ../../../CHANGELOG.md:2745 +#: ../../../CHANGELOG.md:3352 msgid "(Breaking Change) The mautrix-facebook bridge now requires a Postgres database" msgstr "" -#: ../../../CHANGELOG.md:2747 +#: ../../../CHANGELOG.md:3354 msgid "**Update from 2021-11-15**: SQLite support has been re-added to the mautrix-facebook bridge in [v0.3.2](https://github.com/mautrix/facebook/releases/tag/v0.3.2). You can ignore this changelog entry." msgstr "" -#: ../../../CHANGELOG.md:2749 +#: ../../../CHANGELOG.md:3356 msgid "A new version of the [mautrix-facebook](https://github.com/tulir/mautrix-facebook) bridge has been released. It's a full rewrite of its backend and the bridge now requires Postgres. New versions of the bridge can no longer run on SQLite." msgstr "" -#: ../../../CHANGELOG.md:2751 +#: ../../../CHANGELOG.md:3358 msgid "**TLDR**: if you're NOT using an [external Postgres server](docs/configuring-playbook-external-postgres.md) and have NOT forcefully kept the bridge on SQLite during [The big move to all-on-Postgres (potentially dangerous)](#the-big-move-to-all-on-postgres-potentially-dangerous), you will be automatically upgraded without manual intervention. All you need to do is send a `login` message to the Facebook bridge bot again." msgstr "" -#: ../../../CHANGELOG.md:2753 +#: ../../../CHANGELOG.md:3360 msgid "Whether this change requires your intervention depends mostly on:" msgstr "" -#: ../../../CHANGELOG.md:2754 +#: ../../../CHANGELOG.md:3361 msgid "whether you're using an [external Postgres server](docs/configuring-playbook-external-postgres.md). If yes, then [you need to do something](#upgrade-path-for-people-running-an-external-postgres-server)." msgstr "" -#: ../../../CHANGELOG.md:2755 +#: ../../../CHANGELOG.md:3362 msgid "or whether you've force-changed the bridge's database engine to SQLite (`matrix_mautrix_facebook_database_engine: 'sqlite'` in your `vars.yml`) some time in the past (likely during [The big move to all-on-Postgres (potentially dangerous)](#the-big-move-to-all-on-postgres-potentially-dangerous))." msgstr "" -#: ../../../CHANGELOG.md:2757 +#: ../../../CHANGELOG.md:3364 msgid "As already mentioned above, you most likely don't need to do anything. If you rerun the playbook and don't get an error, you've been automatically upgraded. Just send a `login` message to the Facebook bridge bot again. Otherwise, read below for a solution." msgstr "" -#: ../../../CHANGELOG.md:2759 +#: ../../../CHANGELOG.md:3366 msgid "Upgrade path for people NOT running an external Postgres server (default for the playbook)" msgstr "" -#: ../../../CHANGELOG.md:2761 +#: ../../../CHANGELOG.md:3368 msgid "If you're **not running an external Postgres server**, then this bridge either already works on Postgres for you, or you've intentionally kept it back on SQLite with custom configuration (`matrix_mautrix_facebook_database_engine: 'sqlite'` in your `vars.yml`) ." msgstr "" -#: ../../../CHANGELOG.md:2763 +#: ../../../CHANGELOG.md:3370 msgid "Simply remove that custom configuration from your `vars.yml` file (if it's there) and re-run the playbook. It should upgrade you automatically. You'll need to send a `login` message to the Facebook bridge bot again." msgstr "" -#: ../../../CHANGELOG.md:2765 +#: ../../../CHANGELOG.md:3372 msgid "Alternatively, [you can stay on SQLite for a little longer](#staying-on-sqlite-for-a-little-longer-temporary-solution)." msgstr "" -#: ../../../CHANGELOG.md:2767 +#: ../../../CHANGELOG.md:3374 msgid "Upgrade path for people running an external Postgres server" msgstr "" -#: ../../../CHANGELOG.md:2769 +#: ../../../CHANGELOG.md:3376 msgid "For people using the internal Postgres server (the default for the playbook):" msgstr "" -#: ../../../CHANGELOG.md:2770 +#: ../../../CHANGELOG.md:3377 msgid "we automatically create an additional `matrix_mautrix_facebook` Postgres database and credentials to access it" msgstr "" -#: ../../../CHANGELOG.md:2771 +#: ../../../CHANGELOG.md:3378 msgid "we automatically adjust the bridge's `matrix_mautrix_facebook_database_*` variables to point the bridge to that Postgres database" msgstr "" -#: ../../../CHANGELOG.md:2772 +#: ../../../CHANGELOG.md:3379 msgid "we use [pgloader](https://pgloader.io/) to automatically import the existing SQLite data for the bridge into the `matrix_mautrix_facebook` Postgres database" msgstr "" -#: ../../../CHANGELOG.md:2774 +#: ../../../CHANGELOG.md:3381 msgid "If you are using an [external Postgres server](docs/configuring-playbook-external-postgres.md), unfortunately we currently can't do any of that for you." msgstr "" -#: ../../../CHANGELOG.md:2776 +#: ../../../CHANGELOG.md:3383 msgid "You have 3 ways to proceed:" msgstr "" -#: ../../../CHANGELOG.md:2778 +#: ../../../CHANGELOG.md:3385 msgid "contribute to the playbook to make this possible (difficult)" msgstr "" -#: ../../../CHANGELOG.md:2779 +#: ../../../CHANGELOG.md:3386 msgid "or, do the migration \"steps\" manually:" msgstr "" -#: ../../../CHANGELOG.md:2780 +#: ../../../CHANGELOG.md:3387 msgid "stop the bridge (`systemctl stop matrix-mautrix-facebook`)" msgstr "" -#: ../../../CHANGELOG.md:2781 +#: ../../../CHANGELOG.md:3388 msgid "create a new `matrix_mautrix_facebook` Postgres database for it" msgstr "" -#: ../../../CHANGELOG.md:2782 +#: ../../../CHANGELOG.md:3389 msgid "run [pgloader](https://pgloader.io/) manually (we import this bridge's data using default settings and it works well)" msgstr "" -#: ../../../CHANGELOG.md:2783 +#: ../../../CHANGELOG.md:3390 msgid "define `matrix_mautrix_facebook_database_*` variables in your `vars.yml` file (credentials, etc.) — you can find their defaults in `roles/custom/matrix-mautrix-facebook/defaults/main.yml`" msgstr "" -#: ../../../CHANGELOG.md:2784 +#: ../../../CHANGELOG.md:3391 msgid "switch the bridge to Postgres (`matrix_mautrix_facebook_database_engine: 'postgres'` in your `vars.yml` file)" msgstr "" -#: ../../../CHANGELOG.md:2785 +#: ../../../CHANGELOG.md:3392 msgid "re-run the playbook (`--tags=setup-all,start`) and ensure the bridge works (`systemctl status matrix-mautrix-facebook` and `journalctl -fu matrix-mautrix-facebook`)" msgstr "" -#: ../../../CHANGELOG.md:2786 +#: ../../../CHANGELOG.md:3393 msgid "send a `login` message to the Facebook bridge bot again" msgstr "" -#: ../../../CHANGELOG.md:2787 +#: ../../../CHANGELOG.md:3394 msgid "or, [stay on SQLite for a little longer (temporary solution)](#staying-on-sqlite-for-a-little-longer-temporary-solution)" msgstr "" -#: ../../../CHANGELOG.md:2789 +#: ../../../CHANGELOG.md:3396 msgid "Staying on SQLite for a little longer (temporary solution)" msgstr "" -#: ../../../CHANGELOG.md:2791 +#: ../../../CHANGELOG.md:3398 msgid "To keep using this bridge with SQLite for a little longer (**not recommended**), use the following configuration in your `vars.yml` file:" msgstr "" -#: ../../../CHANGELOG.md:2801 +#: ../../../CHANGELOG.md:3408 msgid "If you do this, keep in mind that **you can't run this forever**. This SQLite-supporting bridge version is not getting any updates and will break sooner or later. The playbook will also drop support for SQLite at some point in the future." msgstr "" -#: ../../../CHANGELOG.md:2804 +#: ../../../CHANGELOG.md:3411 msgid "2021-01-17" msgstr "" -#: ../../../CHANGELOG.md:2806 +#: ../../../CHANGELOG.md:3413 msgid "matrix-corporal goes 2.0" msgstr "" -#: ../../../CHANGELOG.md:2808 +#: ../../../CHANGELOG.md:3415 msgid "[matrix-corporal v2 has been released](https://github.com/devture/matrix-corporal/releases/tag/2.0.0) and the playbook also supports it now." msgstr "" -#: ../../../CHANGELOG.md:2810 +#: ../../../CHANGELOG.md:3417 msgid "No manual intervention is required in the common case." msgstr "" -#: ../../../CHANGELOG.md:2812 +#: ../../../CHANGELOG.md:3419 msgid "The new [matrix-corporal](https://github.com/devture/matrix-corporal) version is also the first one to support Interactive Authentication. If you wish to enable that (hint: you should), you'll need to set up the [REST auth password provider](docs/configuring-playbook-rest-auth.md). There's more information in [our matrix-corporal docs](docs/configuring-playbook-matrix-corporal.md)." msgstr "" -#: ../../../CHANGELOG.md:2815 +#: ../../../CHANGELOG.md:3422 msgid "2021-01-14" msgstr "" -#: ../../../CHANGELOG.md:2817 +#: ../../../CHANGELOG.md:3424 msgid "Moving from cronjobs to systemd timers" msgstr "" -#: ../../../CHANGELOG.md:2819 +#: ../../../CHANGELOG.md:3426 msgid "We no longer use cronjobs for Let's Encrypt SSL renewal and `matrix-nginx-proxy`/`matrix-coturn` reloading. Instead, we've switched to systemd timers." msgstr "" -#: ../../../CHANGELOG.md:2821 +#: ../../../CHANGELOG.md:3428 msgid "The largest benefit of this is that we no longer require you to install a cron daemon, thus simplifying our install procedure." msgstr "" -#: ../../../CHANGELOG.md:2823 +#: ../../../CHANGELOG.md:3430 msgid "The playbook will migrate you from cronjobs to systemd timers automatically. This is just a heads up." msgstr "" -#: ../../../CHANGELOG.md:2826 +#: ../../../CHANGELOG.md:3433 msgid "2021-01-08" msgstr "" -#: ../../../CHANGELOG.md:2828 +#: ../../../CHANGELOG.md:3435 msgid "(Breaking Change) New SSL configuration" msgstr "" -#: ../../../CHANGELOG.md:2830 +#: ../../../CHANGELOG.md:3437 msgid "SSL configuration (protocols, ciphers) can now be more easily controlled thanks to us making use of configuration presets." msgstr "" -#: ../../../CHANGELOG.md:2832 +#: ../../../CHANGELOG.md:3439 msgid "We define a few presets (old, intermediate, modern), following the [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/#server=nginx)." msgstr "" -#: ../../../CHANGELOG.md:2834 +#: ../../../CHANGELOG.md:3441 msgid "A new variable `matrix_nginx_proxy_ssl_preset` controls which preset is used (defaults to `\"intermediate\"`)." msgstr "" -#: ../../../CHANGELOG.md:2836 +#: ../../../CHANGELOG.md:3443 msgid "Compared to before, this changes nginx's `ssl_prefer_server_ciphers` to `off` (used to default to `on`). It also add some more ciphers to the list, giving better performance on mobile devices, and removes some weak ciphers. More information in the [documentation](docs/configuring-playbook-nginx.md)." msgstr "" -#: ../../../CHANGELOG.md:2838 +#: ../../../CHANGELOG.md:3445 msgid "To revert to the old behaviour, set the following variables:" msgstr "" -#: ../../../CHANGELOG.md:2845 +#: ../../../CHANGELOG.md:3452 msgid "Just like before, you can still use your own custom protocols by specifying them in `matrix_nginx_proxy_ssl_protocols`. Doing so overrides the values coming from the preset." msgstr "" -#: ../../../CHANGELOG.md:2848 +#: ../../../CHANGELOG.md:3455 msgid "2021-01-03" msgstr "" -#: ../../../CHANGELOG.md:2850 +#: ../../../CHANGELOG.md:3457 msgid "Signal bridging support via mautrix-signal" msgstr "" -#: ../../../CHANGELOG.md:2852 +#: ../../../CHANGELOG.md:3459 msgid "Thanks to [laszabine](https://github.com/laszabine)'s efforts, the playbook now supports bridging to [Signal](https://www.signal.org/) via the [mautrix-signal](https://github.com/tulir/mautrix-signal) bridge. See our [Setting up Mautrix Signal bridging](docs/configuring-playbook-bridge-mautrix-signal.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:2854 +#: ../../../CHANGELOG.md:3461 msgid "If you had installed the mautrix-signal bridge while its Pull Request was still work-in-progress, you can migrate your data to the new and final setup by referring to [this comment](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/686#issuecomment-753510789)." msgstr "" -#: ../../../CHANGELOG.md:2857 +#: ../../../CHANGELOG.md:3464 msgid "2020-12-23" msgstr "" -#: ../../../CHANGELOG.md:2859 +#: ../../../CHANGELOG.md:3466 msgid "The big move to all-on-Postgres (potentially dangerous)" msgstr "" -#: ../../../CHANGELOG.md:2861 +#: ../../../CHANGELOG.md:3468 msgid "**TLDR**: all your bridges (and other services) will likely be auto-migrated from SQLite/nedb to Postgres, hopefully without trouble. You can opt-out (see how below), if too worried about breakage." msgstr "" -#: ../../../CHANGELOG.md:2863 +#: ../../../CHANGELOG.md:3470 msgid "Until now, we've only used Postgres as a database for Synapse. All other services (bridges, bots, etc.) were kept simple and used a file-based database (SQLite or nedb)." msgstr "" -#: ../../../CHANGELOG.md:2865 +#: ../../../CHANGELOG.md:3472 msgid "Since [this huge pull request](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/740), **all of our services now use Postgres by default**. Thanks to [Johanna Dorothea Reichmann](https://github.com/jdreichmann) for starting the work on it and for providing great input!" msgstr "" -#: ../../../CHANGELOG.md:2867 +#: ../../../CHANGELOG.md:3474 msgid "Moving all services to Postgres brings a few **benefits** to us:" msgstr "" -#: ../../../CHANGELOG.md:2869 +#: ../../../CHANGELOG.md:3476 msgid "**improved performance**" msgstr "" -#: ../../../CHANGELOG.md:2870 +#: ../../../CHANGELOG.md:3477 msgid "**improved compatibility**. Most bridges are deprecating SQLite/nedb support or offer less features when not on Postgres." msgstr "" -#: ../../../CHANGELOG.md:2871 +#: ../../../CHANGELOG.md:3478 msgid "**easier backups**. It's still some effort to take a proper backup (Postgres dump + various files, keys), but a Postgres dump now takes you much further." msgstr "" -#: ../../../CHANGELOG.md:2872 +#: ../../../CHANGELOG.md:3479 msgid "we're now **more prepared to introduce other services** that need a Postgres database — [Dendrite](https://github.com/matrix-org/dendrite), the [mautrix-signal](https://github.com/tulir/mautrix-signal) bridge (existing [pull request](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/686)), etc." msgstr "" -#: ../../../CHANGELOG.md:2874 +#: ../../../CHANGELOG.md:3481 msgid "Key takeway" msgstr "" -#: ../../../CHANGELOG.md:2876 +#: ../../../CHANGELOG.md:3483 msgid "existing installations that use an [external Postgres](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-external-postgres.md) server should be unaffected (they remain on SQLite/nedb for all services, except Synapse)" msgstr "" -#: ../../../CHANGELOG.md:2878 +#: ../../../CHANGELOG.md:3485 msgid "for existing installations which use our integrated Postgres database server (`matrix-postgres`, which is the default), **we automatically migrate data** from SQLite/nedb to Postgres and **archive the database files** (`something.db` -> `something.db.backup`), so you can restore them if you need to go back (see how below)." msgstr "" -#: ../../../CHANGELOG.md:2880 +#: ../../../CHANGELOG.md:3487 msgid "Opting-out of the Postgres migration" msgstr "" -#: ../../../CHANGELOG.md:2882 +#: ../../../CHANGELOG.md:3489 msgid "This is a **very large and somewhat untested change** (potentially dangerous), so **if you're not feeling confident/experimental, opt-out** of it for now. Still, it's the new default and what we (and various bridges) will focus on going forward, so don't stick to old ways for too long." msgstr "" -#: ../../../CHANGELOG.md:2884 +#: ../../../CHANGELOG.md:3491 msgid "You can remain on SQLite/nedb (at least for now) by adding a variable like this to your `vars.yml` file for each service you use: `matrix_COMPONENT_database_engine: sqlite` (e.g. `matrix_mautrix_facebook_database_engine: sqlite`)." msgstr "" -#: ../../../CHANGELOG.md:2886 +#: ../../../CHANGELOG.md:3493 msgid "Some services (like `appservice-irc` and `appservice-slack`) don't use SQLite, so use `nedb`, instead of `sqlite` for them." msgstr "" -#: ../../../CHANGELOG.md:2888 +#: ../../../CHANGELOG.md:3495 msgid "Going back to SQLite/nedb if things went wrong" msgstr "" -#: ../../../CHANGELOG.md:2890 +#: ../../../CHANGELOG.md:3497 msgid "If you went with the Postgres migration and it went badly for you (some bridge not working as expected or not working at all), do this:" msgstr "" -#: ../../../CHANGELOG.md:2892 +#: ../../../CHANGELOG.md:3499 msgid "stop all services (`ansible-playbook -i inventory/hosts setup.yml --tags=stop`)" msgstr "" -#: ../../../CHANGELOG.md:2893 +#: ../../../CHANGELOG.md:3500 msgid "SSH into the server and rename the old database files (`something.db.backup` -> `something.db`). Example: `mv /matrix/mautrix-facebook/data/mautrix-facebook.db.backup /matrix/mautrix-facebook/data/mautrix-facebook.db`" msgstr "" -#: ../../../CHANGELOG.md:2894 +#: ../../../CHANGELOG.md:3501 msgid "switch the affected service back to SQLite (e.g. `matrix_mautrix_facebook_database_engine: sqlite`). Some services (like `appservice-irc` and `appservice-slack`) don't use SQLite, so use `nedb`, instead of `sqlite` for them." msgstr "" -#: ../../../CHANGELOG.md:2895 +#: ../../../CHANGELOG.md:3502 msgid "re-run the playbook (`ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start`)" msgstr "" -#: ../../../CHANGELOG.md:2896 +#: ../../../CHANGELOG.md:3503 msgid "[get in touch](README.md#support) with us" msgstr "" -#: ../../../CHANGELOG.md:2898 +#: ../../../CHANGELOG.md:3505 msgid "2020-12-11" msgstr "" -#: ../../../CHANGELOG.md:2900 +#: ../../../CHANGELOG.md:3507 msgid "synapse-janitor support removed" msgstr "" -#: ../../../CHANGELOG.md:2902 +#: ../../../CHANGELOG.md:3509 msgid "We've removed support for the unmaintained [synapse-janitor](https://github.com/xwiki-labs/synapse_scripts) script. There's been past reports of it corrupting the Synapse database. Since there hasn't been any new development on it and it doesn't seem too useful nowadays, there's no point in including it in the playbook." msgstr "" -#: ../../../CHANGELOG.md:2904 +#: ../../../CHANGELOG.md:3511 msgid "If you need to clean up or compact your database, consider using the Synapse Admin APIs directly. See our [Synapse maintenance](docs/maintenance-synapse.md) and [Postgres maintenance](docs/maintenance-postgres.md) documentation pages for more details." msgstr "" -#: ../../../CHANGELOG.md:2906 +#: ../../../CHANGELOG.md:3513 msgid "Docker 20.10 is here" msgstr "" -#: ../../../CHANGELOG.md:2908 +#: ../../../CHANGELOG.md:3515 msgid "(No need to do anything special in relation to this. Just something to keep in mind)" msgstr "" -#: ../../../CHANGELOG.md:2910 +#: ../../../CHANGELOG.md:3517 msgid "Docker 20.10 got released recently and your server will likely get it the next time you update." msgstr "" -#: ../../../CHANGELOG.md:2912 +#: ../../../CHANGELOG.md:3519 msgid "This is the first major Docker update in a long time and it packs a lot of changes. Some of them introduced some breakage for us initially (see [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/d08b27784f222effcbce2abf924bf07bbe0893be) and [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/7593d969e316cc0144bce378a5be58c76c2c37ee)), but it should be all good now." msgstr "" -#: ../../../CHANGELOG.md:2915 +#: ../../../CHANGELOG.md:3522 msgid "2020-12-08" msgstr "" -#: ../../../CHANGELOG.md:2917 +#: ../../../CHANGELOG.md:3524 msgid "openid APIs exposed by default on the federation port when federation disabled" msgstr "" -#: ../../../CHANGELOG.md:2919 +#: ../../../CHANGELOG.md:3526 msgid "We've changed some defaults. People running with our default configuration (federation enabled), are not affected at all." msgstr "" -#: ../../../CHANGELOG.md:2921 +#: ../../../CHANGELOG.md:3528 msgid "If you are running an unfederated server (`matrix_synapse_federation_enabled: false`), this may be of interest to you." msgstr "" -#: ../../../CHANGELOG.md:2923 +#: ../../../CHANGELOG.md:3530 msgid "When federation is disabled, but ma1sd or Dimension are enabled, we'll now expose the `openid` APIs on the federation port. These APIs are necessary for some ma1sd features to work. If you'd like to prevent this, you can: `matrix_synapse_federation_port_openid_resource_required: false`." msgstr "" -#: ../../../CHANGELOG.md:2926 +#: ../../../CHANGELOG.md:3533 msgid "2020-11-27" msgstr "" -#: ../../../CHANGELOG.md:2928 +#: ../../../CHANGELOG.md:3535 msgid "Recent Jitsi updates may require configuration changes" msgstr "" -#: ../../../CHANGELOG.md:2930 +#: ../../../CHANGELOG.md:3537 msgid "We've recently [updated from Jitsi build 4857 to build 5142](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/719), which brings a lot of configuration changes." msgstr "" -#: ../../../CHANGELOG.md:2932 +#: ../../../CHANGELOG.md:3539 msgid "**If you use our default Jitsi settings, you won't have to do anything.**" msgstr "" -#: ../../../CHANGELOG.md:2934 +#: ../../../CHANGELOG.md:3541 msgid "People who have [fine-tuned Jitsi](docs/configuring-playbook-jitsi.md#optional-fine-tune-jitsi) may find that some options got renamed now, others are gone and yet others still need to be defined in another way." msgstr "" -#: ../../../CHANGELOG.md:2936 +#: ../../../CHANGELOG.md:3543 msgid "The next time you run the playbook [installation](docs/installing.md) command, our validation logic will tell you if you're using some variables like that and will recommend a migration path for each one." msgstr "" -#: ../../../CHANGELOG.md:2938 +#: ../../../CHANGELOG.md:3545 msgid "Additionally, we've recently disabled transcriptions (`jitsi_enable_transcriptions: false`) and recording (`jitsi_enable_recording: false`) by default. These features did not work anyway, because we don't install the required dependencies for them (Jigasi and Jibri, respectively). If you've been somehow pointing your Jitsi installation to some manually installed Jigasi/Jibri service, you may need to toggle these flags back to enabled to have transcriptions and recordings working." msgstr "" -#: ../../../CHANGELOG.md:2941 +#: ../../../CHANGELOG.md:3548 msgid "2020-11-23" msgstr "" -#: ../../../CHANGELOG.md:2943 -#: ../../../CHANGELOG.md:2951 +#: ../../../CHANGELOG.md:3550 +#: ../../../CHANGELOG.md:3558 msgid "Breaking change matrix-sms-bridge" msgstr "" -#: ../../../CHANGELOG.md:2945 +#: ../../../CHANGELOG.md:3552 msgid "Because of many problems using gammu as SMS provider, matrix-sms-bridge now uses (https://github.com/RebekkaMa/android-sms-gateway-server) by default. See (the docs)[./docs/configuring-playbook-bridge-matrix-bridge-sms.md] which new vars you need to add." msgstr "" -#: ../../../CHANGELOG.md:2947 +#: ../../../CHANGELOG.md:3554 msgid "If you are using this playbook to deploy matrix-sms-bridge and still really want to use gammu as SMS provider, we could possibly add support for both android-sms-gateway-server and gammu." msgstr "" -#: ../../../CHANGELOG.md:2949 +#: ../../../CHANGELOG.md:3556 msgid "2020-11-13" msgstr "" -#: ../../../CHANGELOG.md:2953 +#: ../../../CHANGELOG.md:3560 msgid "The new version of [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) changed its database from neo4j to h2. You need to sync the bridge at the first start. Note that this only will sync rooms where the @smsbot:yourServer is member. For rooms without @smsbot:yourServer you need to kick and invite the telephone number **or** invite @smsbot:yourServer." msgstr "" -#: ../../../CHANGELOG.md:2955 +#: ../../../CHANGELOG.md:3562 msgid "Add the following to your `vars.yml` file: `matrix_sms_bridge_container_extra_arguments=['--env SPRING_PROFILES_ACTIVE=initialsync']`" msgstr "" -#: ../../../CHANGELOG.md:2956 +#: ../../../CHANGELOG.md:3563 msgid "Login to your host shell and remove old systemd file from your host: `rm /etc/systemd/system/matrix-sms-bridge-database.service`" msgstr "" -#: ../../../CHANGELOG.md:2957 +#: ../../../CHANGELOG.md:3564 msgid "Run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-matrix-sms-bridge,start`" msgstr "" -#: ../../../CHANGELOG.md:2958 +#: ../../../CHANGELOG.md:3565 msgid "Login to your host shell and check the logs with `journalctl -u matrix-sms-bridge` until the sync finished." msgstr "" -#: ../../../CHANGELOG.md:2959 +#: ../../../CHANGELOG.md:3566 msgid "Remove the var from the first step." msgstr "" -#: ../../../CHANGELOG.md:2960 +#: ../../../CHANGELOG.md:3567 msgid "Run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start`." msgstr "" -#: ../../../CHANGELOG.md:2962 +#: ../../../CHANGELOG.md:3569 msgid "2020-11-10" msgstr "" -#: ../../../CHANGELOG.md:2964 +#: ../../../CHANGELOG.md:3571 msgid "Dynamic DNS support" msgstr "" -#: ../../../CHANGELOG.md:2966 +#: ../../../CHANGELOG.md:3573 msgid "Thanks to [Scott Crossen](https://github.com/scottcrossen), the playbook can now manage Dynamic DNS for you using [ddclient](https://ddclient.net/)." msgstr "" -#: ../../../CHANGELOG.md:2968 +#: ../../../CHANGELOG.md:3575 msgid "To learn more, follow our [Dynamic DNS docs page](docs/configuring-playbook-dynamic-dns.md)." msgstr "" -#: ../../../CHANGELOG.md:2971 +#: ../../../CHANGELOG.md:3578 msgid "2020-10-28" msgstr "" -#: ../../../CHANGELOG.md:2973 +#: ../../../CHANGELOG.md:3580 msgid "(Compatibility Break) https://matrix.example.com/ now redirects to https://element.example.com/" msgstr "" -#: ../../../CHANGELOG.md:2975 +#: ../../../CHANGELOG.md:3582 msgid "Until now, we used to serve a static page coming from Synapse at `https://matrix.example.com/`. This page was not very useful to anyone." msgstr "" -#: ../../../CHANGELOG.md:2977 +#: ../../../CHANGELOG.md:3584 msgid "Since `matrix.example.com` may be accessed by regular users in certain conditions, it's probably better to redirect them to a better place (e.g. to [Element Web](docs/configuring-playbook-client-element-web.md))." msgstr "" -#: ../../../CHANGELOG.md:2979 +#: ../../../CHANGELOG.md:3586 msgid "If Element Web is installed (`matrix_client_element_enabled: true`, which it is by default), we now redirect people to it, instead of showing them a Synapse static page." msgstr "" -#: ../../../CHANGELOG.md:2981 +#: ../../../CHANGELOG.md:3588 msgid "If you'd like to control where the redirect goes, use the `matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain` variable. To restore the old behavior of not redirecting anywhere and serving the Synapse static page, set it to an empty value (`matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain: \"\"`)." msgstr "" -#: ../../../CHANGELOG.md:2984 +#: ../../../CHANGELOG.md:3591 msgid "2020-10-26" msgstr "" -#: ../../../CHANGELOG.md:2986 +#: ../../../CHANGELOG.md:3593 msgid "(Compatibility Break) /_synapse/admin is no longer publicly exposed by default" msgstr "" -#: ../../../CHANGELOG.md:2988 +#: ../../../CHANGELOG.md:3595 msgid "We used to expose the Synapse Admin APIs publicly (at `https://matrix.example.com/_synapse/admin`). These APIs require authentication with a valid access token, so it's not that big a deal to expose them." msgstr "" -#: ../../../CHANGELOG.md:2990 +#: ../../../CHANGELOG.md:3597 msgid "However, following [official Synapse's reverse-proxying recommendations](https://github.com/element-hq/synapse/blob/master/docs/reverse_proxy.md#synapse-administration-endpoints), we're no longer exposing `/_synapse/admin` by default." msgstr "" -#: ../../../CHANGELOG.md:2992 +#: ../../../CHANGELOG.md:3599 msgid "If you'd like to restore restore the old behavior and expose `/_synapse/admin` publicly, you can use the following configuration (in your `vars.yml`):" msgstr "" -#: ../../../CHANGELOG.md:2999 +#: ../../../CHANGELOG.md:3606 msgid "2020-10-02" msgstr "" -#: ../../../CHANGELOG.md:3001 +#: ../../../CHANGELOG.md:3608 msgid "Minimum Ansible version raised to v2.7.0" msgstr "" -#: ../../../CHANGELOG.md:3003 +#: ../../../CHANGELOG.md:3610 msgid "We were claiming to support [Ansible](https://www.ansible.com/) v2.5.2 and higher, but issues like [#662](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/662) demonstrate that we need at least v2.7.0." msgstr "" -#: ../../../CHANGELOG.md:3005 +#: ../../../CHANGELOG.md:3612 msgid "If you've been using the playbook without getting any errors until now, you're probably on a version higher than that already (or you're not using the `matrix-ma1sd` and `matrix-client-element` roles)." msgstr "" -#: ../../../CHANGELOG.md:3007 +#: ../../../CHANGELOG.md:3614 msgid "Our [Ansible docs page](docs/ansible.md) contains information on how to run a more up-to-date version of Ansible." msgstr "" -#: ../../../CHANGELOG.md:3010 +#: ../../../CHANGELOG.md:3617 msgid "2020-10-01" msgstr "" -#: ../../../CHANGELOG.md:3012 +#: ../../../CHANGELOG.md:3619 msgid "Postgres 13 support" msgstr "" -#: ../../../CHANGELOG.md:3014 +#: ../../../CHANGELOG.md:3621 msgid "The playbook now installs [Postgres 13](https://www.postgresql.org/about/news/postgresql-13-released-2077/) by default." msgstr "" -#: ../../../CHANGELOG.md:3016 +#: ../../../CHANGELOG.md:3623 msgid "If you have have an existing setup, it's likely running on an older Postgres version (9.x, 10.x, 11.x or 12.x). You can easily upgrade by following the [upgrading PostgreSQL guide](docs/maintenance-postgres.md#upgrading-postgresql)." msgstr "" -#: ../../../CHANGELOG.md:3018 +#: ../../../CHANGELOG.md:3625 msgid "2020-09-01" msgstr "" -#: ../../../CHANGELOG.md:3020 +#: ../../../CHANGELOG.md:3627 msgid "matrix-registration support" msgstr "" -#: ../../../CHANGELOG.md:3022 +#: ../../../CHANGELOG.md:3629 msgid "The playbook can now help you set up [matrix-registration](https://github.com/ZerataX/matrix-registration) — an application that lets you keep your Matrix server's registration private, but still allow certain users (those having a unique registration link) to register by themselves." msgstr "" -#: ../../../CHANGELOG.md:3024 +#: ../../../CHANGELOG.md:3631 msgid "See our [Setting up matrix-registration](docs/configuring-playbook-matrix-registration.md) documentation page to get started." msgstr "" -#: ../../../CHANGELOG.md:3027 +#: ../../../CHANGELOG.md:3634 msgid "2020-08-21" msgstr "" -#: ../../../CHANGELOG.md:3029 +#: ../../../CHANGELOG.md:3636 msgid "rust-synapse-compress-state support" msgstr "" -#: ../../../CHANGELOG.md:3031 +#: ../../../CHANGELOG.md:3638 msgid "The playbook can now help you use [rust-synapse-compress-state](https://github.com/matrix-org/rust-synapse-compress-state) to compress the state groups in your Synapse database." msgstr "" -#: ../../../CHANGELOG.md:3033 +#: ../../../CHANGELOG.md:3640 msgid "See our [Compressing state with rust-synapse-compress-state](docs/maintenance-synapse.md#compressing-state-with-rust-synapse-compress-state) documentation page to get started." msgstr "" -#: ../../../CHANGELOG.md:3036 +#: ../../../CHANGELOG.md:3643 msgid "2020-07-22" msgstr "" -#: ../../../CHANGELOG.md:3038 +#: ../../../CHANGELOG.md:3645 msgid "Synapse Admin support" msgstr "" -#: ../../../CHANGELOG.md:3040 +#: ../../../CHANGELOG.md:3647 msgid "The playbook can now help you set up [synapse-admin](https://github.com/Awesome-Technologies/synapse-admin)." msgstr "" -#: ../../../CHANGELOG.md:3042 +#: ../../../CHANGELOG.md:3649 msgid "See our [Setting up Synapse Admin](docs/configuring-playbook-synapse-admin.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:3045 +#: ../../../CHANGELOG.md:3652 msgid "2020-07-20" msgstr "" -#: ../../../CHANGELOG.md:3047 +#: ../../../CHANGELOG.md:3654 msgid "matrix-reminder-bot support" msgstr "" -#: ../../../CHANGELOG.md:3049 +#: ../../../CHANGELOG.md:3656 msgid "The playbook can now help you set up [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot)." msgstr "" -#: ../../../CHANGELOG.md:3051 +#: ../../../CHANGELOG.md:3658 msgid "See our [Setting up matrix-reminder-bot](docs/configuring-playbook-bot-matrix-reminder-bot.md) documentation to get started." msgstr "" -#: ../../../CHANGELOG.md:3054 +#: ../../../CHANGELOG.md:3661 msgid "2020-07-17" msgstr "" -#: ../../../CHANGELOG.md:3056 +#: ../../../CHANGELOG.md:3663 msgid "(Compatibility Break) Riot is now Element" msgstr "" -#: ../../../CHANGELOG.md:3058 +#: ../../../CHANGELOG.md:3665 msgid "As per the official announcement, [Riot has been rebraned to Element](https://element.io/blog/welcome-to-element/)." msgstr "" -#: ../../../CHANGELOG.md:3060 +#: ../../../CHANGELOG.md:3667 msgid "The playbook follows suit. Existing installations have a few options for how to handle this." msgstr "" -#: ../../../CHANGELOG.md:3062 +#: ../../../CHANGELOG.md:3669 msgid "See our [Migrating to Element Web](docs/configuring-playbook-riot-web.md#migrating-to-element) documentation page for more details." msgstr "" -#: ../../../CHANGELOG.md:3065 +#: ../../../CHANGELOG.md:3672 msgid "2020-07-03" msgstr "" -#: ../../../CHANGELOG.md:3067 +#: ../../../CHANGELOG.md:3674 msgid "Steam bridging support via mx-puppet-steam" msgstr "" -#: ../../../CHANGELOG.md:3069 +#: ../../../CHANGELOG.md:3676 msgid "Thanks to [Hugues Morisset](https://github.com/izissise)'s efforts, the playbook now supports bridging to [Steam](https://steamapp.com/) via the [mx-puppet-steam](https://codeberg.org/icewind/mx-puppet-steam) bridge. See our [Setting up MX Puppet Steam bridging](docs/configuring-playbook-bridge-mx-puppet-steam.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:3072 +#: ../../../CHANGELOG.md:3679 msgid "2020-07-01" msgstr "" -#: ../../../CHANGELOG.md:3074 +#: ../../../CHANGELOG.md:3681 msgid "Discord bridging support via mx-puppet-discord" msgstr "" -#: ../../../CHANGELOG.md:3076 +#: ../../../CHANGELOG.md:3683 msgid "Thanks to [Hugues Morisset](https://github.com/izissise)'s efforts, the playbook now supports bridging to [Discord](https://discordapp.com/) via the [mx-puppet-discord](https://github.com/Sorunome/mx-puppet-discord) bridge. See our [Setting up MX Puppet Discord bridging](docs/configuring-playbook-bridge-mx-puppet-discord.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:3078 +#: ../../../CHANGELOG.md:3685 msgid "**Note**: this is a new Discord bridge. The playbook still retains Discord bridging via [matrix-appservice-discord](docs/configuring-playbook-bridge-appservice-discord.md). You're free too use the bridge that serves you better, or even both (for different users and use-cases)." msgstr "" -#: ../../../CHANGELOG.md:3081 +#: ../../../CHANGELOG.md:3688 msgid "2020-06-30" msgstr "" -#: ../../../CHANGELOG.md:3083 +#: ../../../CHANGELOG.md:3690 msgid "Instagram and Twitter bridging support" msgstr "" -#: ../../../CHANGELOG.md:3085 +#: ../../../CHANGELOG.md:3692 msgid "Thanks to [Johanna Dorothea Reichmann](https://github.com/jdreichmann)'s efforts, the playbook now supports bridging to [Instagram](https://www.instagram.com/) via the [mx-puppet-instagram](https://github.com/Sorunome/mx-puppet-instagram) bridge. See our [Setting up MX Puppet Instagram bridging](docs/configuring-playbook-bridge-mx-puppet-instagram.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:3087 +#: ../../../CHANGELOG.md:3694 msgid "Thanks to [Tulir Asokan](https://github.com/tulir)'s efforts, the playbook now supports bridging to [Twitter](https://twitter.com/) via the [mx-puppet-twitter](https://github.com/Sorunome/mx-puppet-twitter) bridge. See our [Setting up MX Puppet Twitter bridging](docs/configuring-playbook-bridge-mx-puppet-twitter.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:3090 +#: ../../../CHANGELOG.md:3697 msgid "2020-06-28" msgstr "" -#: ../../../CHANGELOG.md:3092 +#: ../../../CHANGELOG.md:3699 msgid "(Post Mortem / fixed Security Issue) Re-enabling User Directory search powered by the ma1sd Identity Server" msgstr "" -#: ../../../CHANGELOG.md:3094 -#: ../../../CHANGELOG.md:3123 +#: ../../../CHANGELOG.md:3701 +#: ../../../CHANGELOG.md:3730 msgid "User Directory search requests used to go to the ma1sd identity server by default, which queried its own stores and the Synapse database." msgstr "" -#: ../../../CHANGELOG.md:3096 +#: ../../../CHANGELOG.md:3703 msgid "ma1sd's [security issue](https://github.com/ma1uta/ma1sd/issues/44) has been fixed in version `2.4.0`, with [this commit](ma1uta/ma1sd@2bb5a734d11662b06471113cf3d6b4cee5e33a85). `ma1sd 2.4.0` is now the default version for this playbook. For more information on what happened, please check the mentioned issue." msgstr "" -#: ../../../CHANGELOG.md:3098 +#: ../../../CHANGELOG.md:3705 msgid "We are re-enabling user directory search with this update. Those who would like to keep it disabled can use this configuration: `matrix_nginx_proxy_proxy_matrix_user_directory_search_enabled: false`" msgstr "" -#: ../../../CHANGELOG.md:3100 +#: ../../../CHANGELOG.md:3707 msgid "As always, re-running the playbook is enough to get the updated bits." msgstr "" -#: ../../../CHANGELOG.md:3102 +#: ../../../CHANGELOG.md:3709 msgid "2020-06-11" msgstr "" -#: ../../../CHANGELOG.md:3104 +#: ../../../CHANGELOG.md:3711 msgid "SMS bridging requires db reset" msgstr "" -#: ../../../CHANGELOG.md:3106 +#: ../../../CHANGELOG.md:3713 msgid "The current version of [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) needs you to delete the database to work as expected. Just remove `/matrix/matrix-sms-bridge/database/*`. It also adds a new required var `matrix_sms_bridge_default_region`." msgstr "" -#: ../../../CHANGELOG.md:3108 +#: ../../../CHANGELOG.md:3715 msgid "To reuse your existing rooms, invite `@smsbot:yourServer` to the room or write a message. You are also able to use automated room creation with telephonenumers by writing `sms send -t 01749292923 \"Hello World\"` in a room with `@smsbot:yourServer`. See [the docs](https://github.com/benkuly/matrix-sms-bridge) for more information." msgstr "" -#: ../../../CHANGELOG.md:3110 +#: ../../../CHANGELOG.md:3717 msgid "2020-06-05" msgstr "" -#: ../../../CHANGELOG.md:3112 +#: ../../../CHANGELOG.md:3719 msgid "SMS bridging support" msgstr "" -#: ../../../CHANGELOG.md:3114 +#: ../../../CHANGELOG.md:3721 msgid "Thanks to [benkuly](https://github.com/benkuly)'s efforts, the playbook now supports bridging to SMS (with one telephone number only) via [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge)." msgstr "" -#: ../../../CHANGELOG.md:3116 +#: ../../../CHANGELOG.md:3723 msgid "See our [Setting up Matrix SMS bridging](docs/configuring-playbook-bridge-matrix-bridge-sms.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:3119 +#: ../../../CHANGELOG.md:3726 msgid "2020-05-19" msgstr "" -#: ../../../CHANGELOG.md:3121 +#: ../../../CHANGELOG.md:3728 msgid "(Compatibility Break / Security Issue) Disabling User Directory search powered by the ma1sd Identity Server" msgstr "" -#: ../../../CHANGELOG.md:3125 +#: ../../../CHANGELOG.md:3732 msgid "ma1sd current has [a security issue](https://github.com/ma1uta/ma1sd/issues/44), which made it leak information about all users — including users created by bridges, etc." msgstr "" -#: ../../../CHANGELOG.md:3127 +#: ../../../CHANGELOG.md:3734 msgid "Until the issue gets fixed, we're making User Directory search not go to ma1sd by default. You **need to re-run the playbook and restart services to apply this workaround**." msgstr "" -#: ../../../CHANGELOG.md:3129 +#: ../../../CHANGELOG.md:3736 msgid "*If you insist on restoring the old behavior* (**which has a security issue!**), you *might* use this configuration: `matrix_nginx_proxy_proxy_matrix_user_directory_search_enabled: \"{{ matrix_ma1sd_enabled }}\"`" msgstr "" -#: ../../../CHANGELOG.md:3132 +#: ../../../CHANGELOG.md:3739 msgid "2020-04-28" msgstr "" -#: ../../../CHANGELOG.md:3134 +#: ../../../CHANGELOG.md:3741 msgid "Newer IRC bridge (with potential breaking change)" msgstr "" -#: ../../../CHANGELOG.md:3136 +#: ../../../CHANGELOG.md:3743 msgid "This upgrades matrix-appservice-irc from 0.14.1 to 0.16.0. Upstream made a change to how you define manual mappings. If you added a `mapping` to your configuration, you will need to update it according to the [upstream instructions](https://github.com/matrix-org/matrix-appservice-irc/blob/master/CHANGELOG.md#0150-2020-02-05). If you did not include `mappings` in your configuration for IRC, no change is necessary. `mappings` is not part of the default configuration." msgstr "" -#: ../../../CHANGELOG.md:3145 +#: ../../../CHANGELOG.md:3752 msgid "2020-04-23" msgstr "" -#: ../../../CHANGELOG.md:3147 -#: ../../../CHANGELOG.md:3378 +#: ../../../CHANGELOG.md:3754 +#: ../../../CHANGELOG.md:3985 msgid "Slack bridging support" msgstr "" -#: ../../../CHANGELOG.md:3149 +#: ../../../CHANGELOG.md:3756 msgid "Thanks to [Rodrigo Belem](https://github.com/rbelem)'s efforts, the playbook now supports bridging to [Slack](https://slack.com) via the [mx-puppet-slack](https://github.com/Sorunome/mx-puppet-slack) bridge." msgstr "" -#: ../../../CHANGELOG.md:3151 +#: ../../../CHANGELOG.md:3758 msgid "See our [Setting up MX Puppet Slack bridging](docs/configuring-playbook-bridge-mx-puppet-slack.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:3154 +#: ../../../CHANGELOG.md:3761 msgid "2020-04-09" msgstr "" -#: ../../../CHANGELOG.md:3156 +#: ../../../CHANGELOG.md:3763 msgid "Skype bridging support" msgstr "" -#: ../../../CHANGELOG.md:3158 +#: ../../../CHANGELOG.md:3765 msgid "Thanks to [Rodrigo Belem](https://github.com/rbelem)'s efforts, the playbook now supports bridging to [Skype](https://www.skype.com) via the [mx-puppet-skype](https://github.com/Sorunome/mx-puppet-skype) bridge." msgstr "" -#: ../../../CHANGELOG.md:3160 +#: ../../../CHANGELOG.md:3767 msgid "See our [Setting up MX Puppet Skype bridging](docs/configuring-playbook-bridge-mx-puppet-skype.md) documentation page for getting started." msgstr "" -#: ../../../CHANGELOG.md:3163 +#: ../../../CHANGELOG.md:3770 msgid "2020-04-05" msgstr "" -#: ../../../CHANGELOG.md:3165 +#: ../../../CHANGELOG.md:3772 msgid "Private Jitsi support" msgstr "" -#: ../../../CHANGELOG.md:3167 +#: ../../../CHANGELOG.md:3774 msgid "The [Jitsi support](#jitsi-support) we had landed a few weeks ago was working well, but it was always open to the whole world." msgstr "" -#: ../../../CHANGELOG.md:3169 +#: ../../../CHANGELOG.md:3776 msgid "Running such an open instance is not desirable to most people, so [teutat3s](https://github.com/teutat3s) has contributed support for making Jitsi use authentication." msgstr "" -#: ../../../CHANGELOG.md:3171 +#: ../../../CHANGELOG.md:3778 msgid "To make your Jitsi server more private, see the [configure internal Jitsi authentication and guests mode](docs/configuring-playbook-jitsi.md#optional-configure-internal-jitsi-authentication-and-guests-mode) section in our Jitsi documentation." msgstr "" -#: ../../../CHANGELOG.md:3174 +#: ../../../CHANGELOG.md:3781 msgid "2020-04-03" msgstr "" -#: ../../../CHANGELOG.md:3176 +#: ../../../CHANGELOG.md:3783 msgid "(Potential Backward Compatibility Break) ma1sd replaces mxisd" msgstr "" -#: ../../../CHANGELOG.md:3178 +#: ../../../CHANGELOG.md:3785 msgid "Thanks to [Marcel Partap](https://github.com/eMPee584)'s efforts, the [mxisd](https://github.com/kamax-io/mxisd) identity server, which has been deprecated for a long time, has finally been replaced by [ma1sd](https://github.com/ma1uta/ma1sd), a compatible fork." msgstr "" -#: ../../../CHANGELOG.md:3180 +#: ../../../CHANGELOG.md:3787 msgid "**If you're using the default playbook configuration**, you don't need to do anything — your mxisd installation will be replaced with ma1sd and all existing data will be migrated automatically the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3182 +#: ../../../CHANGELOG.md:3789 msgid "**If you're doing something more special** (defining custom `matrix_mxisd_*` variables), the playbook will ask you to rename them to `matrix_ma1sd_*`. You're also encouraged to test that ma1sd works well for such a more custom setup." msgstr "" -#: ../../../CHANGELOG.md:3185 +#: ../../../CHANGELOG.md:3792 msgid "2020-03-29" msgstr "" -#: ../../../CHANGELOG.md:3187 +#: ../../../CHANGELOG.md:3794 msgid "Archlinux support" msgstr "" -#: ../../../CHANGELOG.md:3189 +#: ../../../CHANGELOG.md:3796 msgid "Thanks to [Christian Lupus](https://github.com/christianlupus)'s efforts, the playbook now supports installing to an [Archlinux](https://www.archlinux.org/) server." msgstr "" -#: ../../../CHANGELOG.md:3192 +#: ../../../CHANGELOG.md:3799 msgid "2020-03-24" msgstr "" -#: ../../../CHANGELOG.md:3194 +#: ../../../CHANGELOG.md:3801 msgid "Jitsi support" msgstr "" -#: ../../../CHANGELOG.md:3196 +#: ../../../CHANGELOG.md:3803 msgid "The playbook can now (optionally) install the [Jitsi](https://jitsi.org/) video-conferencing platform and integrate it with [Riot](docs/configuring-playbook-riot-web.md)." msgstr "" -#: ../../../CHANGELOG.md:3198 +#: ../../../CHANGELOG.md:3805 msgid "See our [Jitsi documentation page](docs/configuring-playbook-jitsi.md) to get started." msgstr "" -#: ../../../CHANGELOG.md:3201 +#: ../../../CHANGELOG.md:3808 msgid "2020-03-15" msgstr "" -#: ../../../CHANGELOG.md:3203 +#: ../../../CHANGELOG.md:3810 msgid "Raspberry Pi support" msgstr "" -#: ../../../CHANGELOG.md:3205 +#: ../../../CHANGELOG.md:3812 msgid "Thanks to [Gergely Horváth](https://github.com/hooger)'s effort, the playbook supports installing to a Raspberry Pi server, for at least some of the services." msgstr "" -#: ../../../CHANGELOG.md:3207 +#: ../../../CHANGELOG.md:3814 msgid "Since most ready-made container images do not support that architecture, we achieve this by building images locally on the device itself. See our [Self-building documentation page](docs/self-building.md) for how to get started." msgstr "" -#: ../../../CHANGELOG.md:3210 +#: ../../../CHANGELOG.md:3817 msgid "2020-02-26" msgstr "" -#: ../../../CHANGELOG.md:3212 +#: ../../../CHANGELOG.md:3819 msgid "Riot-web themes are here" msgstr "" -#: ../../../CHANGELOG.md:3214 +#: ../../../CHANGELOG.md:3821 msgid "The playbook now makes it easy to install custom riot-web themes." msgstr "" -#: ../../../CHANGELOG.md:3216 +#: ../../../CHANGELOG.md:3823 msgid "To learn more, take a look at our [riot-web documentation on Themes](docs/configuring-playbook-riot-web.md#themes)." msgstr "" -#: ../../../CHANGELOG.md:3219 +#: ../../../CHANGELOG.md:3826 msgid "2020-02-24" msgstr "" -#: ../../../CHANGELOG.md:3221 +#: ../../../CHANGELOG.md:3828 msgid "Customize the server name in Riot's login page" msgstr "" -#: ../../../CHANGELOG.md:3223 +#: ../../../CHANGELOG.md:3830 msgid "You can now customize the server name string that Riot-web displays in its login page." msgstr "" -#: ../../../CHANGELOG.md:3225 +#: ../../../CHANGELOG.md:3832 msgid "These playbook variables, with these default values, have been added:" msgstr "" -#: ../../../CHANGELOG.md:3231 +#: ../../../CHANGELOG.md:3838 msgid "The login page previously said \"Sign in to your Matrix account on matrix.example.org\" (the homeserver's domain name). It will now say \"Sign in … on example.org\" (the server name) by default, or \"Sign in … on Our Server\" if you set the variable to \"Our Server\"." msgstr "" -#: ../../../CHANGELOG.md:3233 +#: ../../../CHANGELOG.md:3840 msgid "To support this, the config.json template is changed to use the configuration key `default_server_config` for setting the default HS/IS, and the new configuration key `server_name` is added in there." msgstr "" -#: ../../../CHANGELOG.md:3236 +#: ../../../CHANGELOG.md:3843 msgid "2020-01-30" msgstr "" -#: ../../../CHANGELOG.md:3238 +#: ../../../CHANGELOG.md:3845 msgid "Disabling TLSv1.1" msgstr "" -#: ../../../CHANGELOG.md:3240 +#: ../../../CHANGELOG.md:3847 msgid "To improve security, we've removed TLSv1.1 support from our default matrix-nginx-proxy configuration." msgstr "" -#: ../../../CHANGELOG.md:3242 +#: ../../../CHANGELOG.md:3849 msgid "If you need to support old clients, you can re-enable it with the following configuration: `matrix_nginx_proxy_ssl_protocols: \"TLSv1.1 TLSv1.2 TLSv1.3\"`" msgstr "" -#: ../../../CHANGELOG.md:3245 +#: ../../../CHANGELOG.md:3852 msgid "2020-01-21" msgstr "" -#: ../../../CHANGELOG.md:3247 +#: ../../../CHANGELOG.md:3854 msgid "Postgres collation changes (action required!)" msgstr "" -#: ../../../CHANGELOG.md:3249 +#: ../../../CHANGELOG.md:3856 msgid "By default, we've been using a UTF-8 collation for Postgres. This is known to cause Synapse some troubles (see the [relevant issue](https://github.com/matrix-org/synapse/issues/6722)) on systems that use [glibc](https://www.gnu.org/software/libc/). We run Postgres in an [Alpine Linux](https://alpinelinux.org/) container (which uses [musl](https://www.musl-libc.org/), and not glibc), so our users are likely not affected by the index corruption problem observed by others." msgstr "" -#: ../../../CHANGELOG.md:3251 +#: ../../../CHANGELOG.md:3858 msgid "Still, we might become affected in the future. In any case, it's imminent that Synapse will complain about databases which do not use a C collation." msgstr "" -#: ../../../CHANGELOG.md:3253 +#: ../../../CHANGELOG.md:3860 msgid "To avoid future problems, we recommend that you run the following command:" msgstr "" -#: ../../../CHANGELOG.md:3259 +#: ../../../CHANGELOG.md:3866 msgid "It forces a [Postgres database upgrade](docs/maintenance-postgres.md#upgrading-postgresql), which would recreate your Postgres database using the proper (`C`) collation. If you are low on disk space, or run into trouble, refer to the Postgres database upgrade documentation page." msgstr "" -#: ../../../CHANGELOG.md:3262 +#: ../../../CHANGELOG.md:3869 msgid "2020-01-14" msgstr "" -#: ../../../CHANGELOG.md:3264 +#: ../../../CHANGELOG.md:3871 msgid "Added support for Appservice Webhooks" msgstr "" -#: ../../../CHANGELOG.md:3266 +#: ../../../CHANGELOG.md:3873 msgid "Thanks to a contribution from [Björn Marten](https://github.com/tripleawwy) from [netresearch](https://www.netresearch.de/), the playbook can now install and configure [matrix-appservice-webhooks](https://github.com/turt2live/matrix-appservice-webhooks) for you. This bridge provides support for Slack-compatible webhooks." msgstr "" -#: ../../../CHANGELOG.md:3268 +#: ../../../CHANGELOG.md:3875 msgid "Learn more in [Setting up Appservice Webhooks bridging](docs/configuring-playbook-bridge-appservice-webhooks.md)." msgstr "" -#: ../../../CHANGELOG.md:3271 +#: ../../../CHANGELOG.md:3878 msgid "2020-01-12" msgstr "" -#: ../../../CHANGELOG.md:3273 +#: ../../../CHANGELOG.md:3880 msgid "Added support for automatic Double Puppeting for all Mautrix bridges" msgstr "" -#: ../../../CHANGELOG.md:3275 +#: ../../../CHANGELOG.md:3882 msgid "Double Puppeting can now be easily enabled for all Mautrix bridges supported by the playbook (Facebook, Hangouts, Whatsapp, Telegram)." msgstr "" -#: ../../../CHANGELOG.md:3277 +#: ../../../CHANGELOG.md:3884 msgid "This is possible due to those bridges' integration with [matrix-synapse-shared-secret-auth](https://github.com/devture/matrix-synapse-shared-secret-auth) — yet another component that this playbook can install for you." msgstr "" -#: ../../../CHANGELOG.md:3279 +#: ../../../CHANGELOG.md:3886 msgid "To get started, following the playbook's documentation for the bridge you'd like to configure." msgstr "" -#: ../../../CHANGELOG.md:3282 +#: ../../../CHANGELOG.md:3889 msgid "2019-12-06" msgstr "" -#: ../../../CHANGELOG.md:3284 +#: ../../../CHANGELOG.md:3891 msgid "Added support for an alternative method for using another webserver" msgstr "" -#: ../../../CHANGELOG.md:3286 +#: ../../../CHANGELOG.md:3893 msgid "We have added support for making `matrix-nginx-proxy` not being so invasive, so that it would be easier to [use your own webserver](docs/configuring-playbook-own-webserver.md)." msgstr "" -#: ../../../CHANGELOG.md:3288 +#: ../../../CHANGELOG.md:3895 msgid "The documentation has been updated with a **Method 2**, which might make \"own webserver\" setup easier in some cases (such as [reverse-proxying using Traefik](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/296))." msgstr "" -#: ../../../CHANGELOG.md:3290 +#: ../../../CHANGELOG.md:3897 msgid "**Existing users** are not affected by this and **don't need to change anything**. The defaults are still the same (`matrix-nginx-proxy` obtaining SSL certificates and doing everything for you automatically)." msgstr "" -#: ../../../CHANGELOG.md:3293 +#: ../../../CHANGELOG.md:3900 msgid "2019-11-10" msgstr "" -#: ../../../CHANGELOG.md:3295 +#: ../../../CHANGELOG.md:3902 msgid "Tightened security around room directory publishing" msgstr "" -#: ../../../CHANGELOG.md:3297 +#: ../../../CHANGELOG.md:3904 msgid "As per this [advisory blog post](https://matrix.org/blog/2019/11/09/avoiding-unwelcome-visitors-on-private-matrix-servers), we've decided to change the default publishing rules for the Matrix room directory." msgstr "" -#: ../../../CHANGELOG.md:3299 +#: ../../../CHANGELOG.md:3906 msgid "Our general goal is to favor privacy and security when running personal (family & friends) and corporate homeservers. Both of these likely benefit from having a more secure default of **not showing the room directory without authentication** and **not publishing the room directory over federation**." msgstr "" -#: ../../../CHANGELOG.md:3301 +#: ../../../CHANGELOG.md:3908 msgid "As with anything else, these new defaults can be overridden by changing the `matrix_synapse_allow_public_rooms_without_auth` and `matrix_synapse_allow_public_rooms_over_federation` variables, respectively." msgstr "" -#: ../../../CHANGELOG.md:3304 +#: ../../../CHANGELOG.md:3911 msgid "2019-10-05" msgstr "" -#: ../../../CHANGELOG.md:3306 +#: ../../../CHANGELOG.md:3913 msgid "Improved Postgres upgrading/importing" msgstr "" -#: ../../../CHANGELOG.md:3308 +#: ../../../CHANGELOG.md:3915 msgid "Postgres [upgrading](docs/maintenance-postgres.md#upgrading-postgresql) and [importing](docs/importing-postgres.md) have been improved to add support for multiple databases and roles." msgstr "" -#: ../../../CHANGELOG.md:3310 +#: ../../../CHANGELOG.md:3917 msgid "Previously, the playbook would only take care of the `homeserver` database and `synapse` user. We now back up and restore all databases and users on the Postgres server." msgstr "" -#: ../../../CHANGELOG.md:3312 +#: ../../../CHANGELOG.md:3919 msgid "For now, the playbook only uses that one database (`homeserver`) and that one single user (`synapse`), so it's all the same. However, in the future, additional components besides Synapse may also make use the Postgres database server. One such example is the [matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) bridge, which strongly encourages use of Postgres in its v1.0 release. We are yet to upgrade to it." msgstr "" -#: ../../../CHANGELOG.md:3314 +#: ../../../CHANGELOG.md:3921 msgid "Additionally, Postgres [upgrading](docs/maintenance-postgres.md#upgrading-postgresql) now uses gzipped dump files by default, to minimize disk space usage." msgstr "" -#: ../../../CHANGELOG.md:3317 +#: ../../../CHANGELOG.md:3924 msgid "2019-10-04" msgstr "" -#: ../../../CHANGELOG.md:3319 +#: ../../../CHANGELOG.md:3926 msgid "Postgres 12 support" msgstr "" -#: ../../../CHANGELOG.md:3321 +#: ../../../CHANGELOG.md:3928 msgid "The playbook now installs [Postgres 12](https://www.postgresql.org/about/news/1976/) by default." msgstr "" -#: ../../../CHANGELOG.md:3323 +#: ../../../CHANGELOG.md:3930 msgid "If you have have an existing setup, it's likely running on an older Postgres version (9.x, 10.x or 11.x). You can easily upgrade by following the [upgrading PostgreSQL guide](docs/maintenance-postgres.md#upgrading-postgresql)." msgstr "" -#: ../../../CHANGELOG.md:3326 +#: ../../../CHANGELOG.md:3933 msgid "2019-10-03" msgstr "" -#: ../../../CHANGELOG.md:3328 +#: ../../../CHANGELOG.md:3935 msgid "Synapse 1.4.0" msgstr "" -#: ../../../CHANGELOG.md:3330 +#: ../../../CHANGELOG.md:3937 msgid "Synapse 1.4.0 [is out](https://matrix.org/blog/2019/10/03/synapse-1-4-0-released) with lots of changes related to privacy." msgstr "" -#: ../../../CHANGELOG.md:3332 +#: ../../../CHANGELOG.md:3939 msgid "Its new defaults (which we adopt as well) mean that certain old data will automatically get purged after a certain number of days. 1.4.0 automatically garbage collects redacted messages (defaults to 7 days) and removes unused IP and user agent information stored in the user_ips table (defaults to 30 days). If you'd like to preserve this data, we encourage you to look at the `redaction_retention_period` and `user_ips_max_age` options (controllable by the `matrix_synapse_redaction_retention_period` and `matrix_synapse_user_ips_max_age` playbook variables, respectively) before doing the upgrade. If you'd like to keep data indefinitely, set these variables to `null` (e.g. `matrix_synapse_redaction_retention_period: ~`)." msgstr "" -#: ../../../CHANGELOG.md:3334 +#: ../../../CHANGELOG.md:3941 msgid "From now on the `trusted_key_servers` setting for Synapse is configurable. It still defaults to `matrix.org` just like it always has, but in a more explicit way now. If you'd like to use another trusted key server, adjust the `matrix_synapse_trusted_key_servers` playbook variable." msgstr "" -#: ../../../CHANGELOG.md:3336 +#: ../../../CHANGELOG.md:3943 msgid "Synapse 1.4.0 also changes lots of things related to identity server integration. Because Synapse will now by default be responsible for validating email addresses for user accounts, running without an identity server looks more feasible. We still [have concerns](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/275/files#r331104117) over disabling the identity server by default, so for now it remains enabled." msgstr "" -#: ../../../CHANGELOG.md:3339 +#: ../../../CHANGELOG.md:3946 msgid "2019-09-09" msgstr "" -#: ../../../CHANGELOG.md:3341 +#: ../../../CHANGELOG.md:3948 msgid "Synapse Simple Antispam support" msgstr "" -#: ../../../CHANGELOG.md:3343 +#: ../../../CHANGELOG.md:3950 msgid "There have been lots of invite-spam attacks lately and [Travis](https://github.com/t2bot) has created a Synapse module ([synapse-simple-antispam](https://github.com/t2bot/synapse-simple-antispam)) to let people protect themselves." msgstr "" -#: ../../../CHANGELOG.md:3345 +#: ../../../CHANGELOG.md:3952 msgid "From now on, you can easily install and configure this spam checker module through the playbook." msgstr "" -#: ../../../CHANGELOG.md:3347 +#: ../../../CHANGELOG.md:3954 msgid "Learn more in [Setting up Synapse Simple Antispam](docs/configuring-playbook-synapse-simple-antispam.md)." msgstr "" -#: ../../../CHANGELOG.md:3350 +#: ../../../CHANGELOG.md:3957 msgid "2019-08-25" msgstr "" -#: ../../../CHANGELOG.md:3352 +#: ../../../CHANGELOG.md:3959 msgid "Extensible Riot-web configuration" msgstr "" -#: ../../../CHANGELOG.md:3354 +#: ../../../CHANGELOG.md:3961 msgid "Similarly to [Extensible Synapse configuration](#extensible-synapse-configuration) (below), Riot-web configuration is also extensible now." msgstr "" -#: ../../../CHANGELOG.md:3356 +#: ../../../CHANGELOG.md:3963 msgid "From now on, you can extend/override Riot-web's configuration by making use of the `matrix_riot_web_configuration_extension_json` variable. This should be enough for most customization needs." msgstr "" -#: ../../../CHANGELOG.md:3358 +#: ../../../CHANGELOG.md:3965 msgid "If you need even more power, you can now also take full control and override `matrix_riot_web_configuration_default` (or `matrix_riot_web_configuration`) directly." msgstr "" -#: ../../../CHANGELOG.md:3360 +#: ../../../CHANGELOG.md:3967 msgid "Learn more in [Configuring Riot-web](docs/configuring-playbook-riot-web.md)." msgstr "" -#: ../../../CHANGELOG.md:3363 +#: ../../../CHANGELOG.md:3970 msgid "2019-08-22" msgstr "" -#: ../../../CHANGELOG.md:3365 +#: ../../../CHANGELOG.md:3972 msgid "Extensible Synapse configuration" msgstr "" -#: ../../../CHANGELOG.md:3367 +#: ../../../CHANGELOG.md:3974 msgid "Previously, we had to create custom Ansible variables for each and every Synapse setting. This lead to too much effort (and configuration ugliness) to all of Synapse's settings, so naturally, not all features of Synapse could be controlled through the playbook." msgstr "" -#: ../../../CHANGELOG.md:3369 +#: ../../../CHANGELOG.md:3976 msgid "From now on, you can extend/override the Synapse server's configuration by making use of the `matrix_synapse_configuration_extension_yaml` variable. This should be enough for most customization needs." msgstr "" -#: ../../../CHANGELOG.md:3371 +#: ../../../CHANGELOG.md:3978 msgid "If you need even more power, you can now also take full control and override `matrix_synapse_configuration` (or `matrix_synapse_configuration_yaml`) directly." msgstr "" -#: ../../../CHANGELOG.md:3373 +#: ../../../CHANGELOG.md:3980 msgid "Learn more here in [Configuring Synapse](docs/configuring-playbook-synapse.md)." msgstr "" -#: ../../../CHANGELOG.md:3376 +#: ../../../CHANGELOG.md:3983 msgid "2019-08-21" msgstr "" -#: ../../../CHANGELOG.md:3380 +#: ../../../CHANGELOG.md:3987 msgid "Thanks to the [great work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/205) of [kingoftheconnors](https://github.com/kingoftheconnors) and [Stuart Mumford (Cadair)](https://github.com/Cadair), the playbook now supports bridging to [Slack](https://slack.com) via the [appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) bridge." msgstr "" -#: ../../../CHANGELOG.md:3382 +#: ../../../CHANGELOG.md:3989 msgid "Additional details are available in [Setting up Appservice Slack bridging](docs/configuring-playbook-bridge-appservice-slack.md)." msgstr "" -#: ../../../CHANGELOG.md:3384 +#: ../../../CHANGELOG.md:3991 msgid "Google Hangouts bridging support" msgstr "" -#: ../../../CHANGELOG.md:3386 +#: ../../../CHANGELOG.md:3993 msgid "Thanks to the [great work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/251) of [Eduardo Beltrame (Munfred)](https://github.com/Munfred) and [Robbie D (microchipster)](https://github.com/microchipster), the playbook now supports bridging to [Google Hangouts](https://hangouts.google.com/) via the [mautrix-hangouts](https://mau.dev/tulir/mautrix-hangouts) bridge." msgstr "" -#: ../../../CHANGELOG.md:3388 +#: ../../../CHANGELOG.md:3995 msgid "Additional details are available in [Setting up Mautrix Hangouts bridging](docs/configuring-playbook-bridge-mautrix-hangouts.md)." msgstr "" -#: ../../../CHANGELOG.md:3391 +#: ../../../CHANGELOG.md:3998 msgid "2019-08-05" msgstr "" -#: ../../../CHANGELOG.md:3393 +#: ../../../CHANGELOG.md:4000 msgid "Email2Matrix support" msgstr "" -#: ../../../CHANGELOG.md:3395 +#: ../../../CHANGELOG.md:4002 msgid "Support for [Email2Matrix](https://github.com/devture/email2matrix) has been added." msgstr "" -#: ../../../CHANGELOG.md:3397 +#: ../../../CHANGELOG.md:4004 msgid "It's an optional feature that you can enable via the playbook." msgstr "" -#: ../../../CHANGELOG.md:3399 +#: ../../../CHANGELOG.md:4006 msgid "To learn more, see the [playbook's documentation on Email2Matrix](./docs/configuring-playbook-email2matrix.md)." msgstr "" -#: ../../../CHANGELOG.md:3402 +#: ../../../CHANGELOG.md:4009 msgid "2019-08-03" msgstr "" -#: ../../../CHANGELOG.md:3404 +#: ../../../CHANGELOG.md:4011 msgid "Synapse logging level has been reduced to WARNING" msgstr "" -#: ../../../CHANGELOG.md:3406 +#: ../../../CHANGELOG.md:4013 msgid "After [some discussion in our support room](https://matrix.to/#/!PukFFdIcHgtaaHZflT:devture.com/$156476852524179TBeKy:matrix.org?via=devture.com&via=matrix.org&via=librem.one), we've decided to change the default logging level for Synapse from `INFO` to `WARNING`." msgstr "" -#: ../../../CHANGELOG.md:3408 +#: ../../../CHANGELOG.md:4015 msgid "This greatly reduces the number of log messages that are being logged, leading to:" msgstr "" -#: ../../../CHANGELOG.md:3410 +#: ../../../CHANGELOG.md:4017 msgid "much less disk space dedicated to Synapse and thus, logs kept for longer" msgstr "" -#: ../../../CHANGELOG.md:3411 +#: ../../../CHANGELOG.md:4018 msgid "easier to find some important `WARNING`, `ERROR` and `CRITICAL` messages, as they're not longer buried in thousands of non-important `INFO` messages" msgstr "" -#: ../../../CHANGELOG.md:3413 +#: ../../../CHANGELOG.md:4020 msgid "If you'd like to track down an issue, you [can always increase the logging level as described here](./docs/maintenance-and-troubleshooting.md#increasing-synapse-logging)." msgstr "" -#: ../../../CHANGELOG.md:3416 +#: ../../../CHANGELOG.md:4023 msgid "2019-07-08" msgstr "" -#: ../../../CHANGELOG.md:3418 +#: ../../../CHANGELOG.md:4025 msgid "Synapse Maintenance docs and synapse-janitor support are available" msgstr "" -#: ../../../CHANGELOG.md:3420 +#: ../../../CHANGELOG.md:4027 msgid "The playbook can now help you with Synapse's maintenance." msgstr "" -#: ../../../CHANGELOG.md:3422 +#: ../../../CHANGELOG.md:4029 msgid "There's a new documentation page about [Synapse maintenance](./docs/maintenance-synapse.md) and another section on [Postgres vacuuming](./docs/maintenance-postgres.md#vacuuming-postgresql)." msgstr "" -#: ../../../CHANGELOG.md:3424 +#: ../../../CHANGELOG.md:4031 msgid "Among other things, if your Postgres database has grown significantly over time, you may wish to [ask the playbook to purge unused data with synapse-janitor](./docs/maintenance-synapse.md#purging-unused-data-with-synapse-janitor) for you." msgstr "" -#: ../../../CHANGELOG.md:3426 +#: ../../../CHANGELOG.md:4033 msgid "(BC Break) Rename run control variables" msgstr "" -#: ../../../CHANGELOG.md:3428 +#: ../../../CHANGELOG.md:4035 msgid "Some internal playbook control variables have been renamed." msgstr "" -#: ../../../CHANGELOG.md:3430 +#: ../../../CHANGELOG.md:4037 msgid "This change **only affects people who run this playbook's roles from another playbook**. If you're using this playbook as-is, you're not affected and don't need to do anything." msgstr "" -#: ../../../CHANGELOG.md:3432 +#: ../../../CHANGELOG.md:4039 msgid "The following variables have been renamed:" msgstr "" -#: ../../../CHANGELOG.md:3434 +#: ../../../CHANGELOG.md:4041 msgid "from `run_import_postgres` to `run_postgres_import`" msgstr "" -#: ../../../CHANGELOG.md:3435 +#: ../../../CHANGELOG.md:4042 msgid "from `run_import_sqlite_db` to `run_postgres_import_sqlite_db`" msgstr "" -#: ../../../CHANGELOG.md:3436 +#: ../../../CHANGELOG.md:4043 msgid "from `run_upgrade_postgres` to `run_postgres_upgrade`" msgstr "" -#: ../../../CHANGELOG.md:3437 +#: ../../../CHANGELOG.md:4044 msgid "from `run_import_media_store` to `run_synapse_import_media_store`" msgstr "" -#: ../../../CHANGELOG.md:3438 +#: ../../../CHANGELOG.md:4045 msgid "from `run_register_user` to `run_synapse_register_user`" msgstr "" -#: ../../../CHANGELOG.md:3439 +#: ../../../CHANGELOG.md:4046 msgid "from `run_update_user_password` to `run_synapse_update_user_password`" msgstr "" -#: ../../../CHANGELOG.md:3442 +#: ../../../CHANGELOG.md:4049 msgid "2019-07-04" msgstr "" -#: ../../../CHANGELOG.md:3444 +#: ../../../CHANGELOG.md:4051 msgid "Synapse no longer logs to text files" msgstr "" -#: ../../../CHANGELOG.md:3446 +#: ../../../CHANGELOG.md:4053 msgid "Following what the official Synapse Docker image is doing ([#5565](https://github.com/matrix-org/synapse/pull/5565)) and what we've been doing for mostly everything installed by this playbook, **Synapse no longer logs to text files** (`/matrix/synapse/run/homeserver.log*`)." msgstr "" -#: ../../../CHANGELOG.md:3448 +#: ../../../CHANGELOG.md:4055 msgid "From now on, Synapse would only log to console, which goes to systemd's journald. To see Synapse's logs, execute: `journalctl -fu matrix-synapse`" msgstr "" -#: ../../../CHANGELOG.md:3450 +#: ../../../CHANGELOG.md:4057 msgid "Because of this, the following variables have become obsolete and were removed:" msgstr "" -#: ../../../CHANGELOG.md:3452 +#: ../../../CHANGELOG.md:4059 msgid "`matrix_synapse_max_log_file_size_mb`" msgstr "" -#: ../../../CHANGELOG.md:3453 +#: ../../../CHANGELOG.md:4060 msgid "`matrix_synapse_max_log_files_count`" msgstr "" -#: ../../../CHANGELOG.md:3455 +#: ../../../CHANGELOG.md:4062 msgid "To prevent confusion, it'd be better if you delete all old files manually after you've upgraded (`rm -f /matrix/synapse/run/homeserver.log*`)." msgstr "" -#: ../../../CHANGELOG.md:3457 +#: ../../../CHANGELOG.md:4064 msgid "Because Synapse is incredibly chatty when it comes to logging (here's [one such issue](https://github.com/matrix-org/synapse/issues/4751) describing the problem), if you're running an ancient distribution (like CentOS 7.0), be advised that systemd's journald default logging restrictions may not be high enough to capture all log messages generated by Synapse. This is especially true if you've got a busy (Synapse) server. We advise that you manually add `RateLimitInterval=0` and `RateLimitBurst=0` under `[Storage]` in the `/etc/systemd/journald.conf` file, followed by restarting the logging service (`systemctl restart systemd-journald`)." msgstr "" -#: ../../../CHANGELOG.md:3460 +#: ../../../CHANGELOG.md:4067 msgid "2019-06-27" msgstr "" -#: ../../../CHANGELOG.md:3462 +#: ../../../CHANGELOG.md:4069 msgid "(BC Break) Discord bridge configuration is now entirely managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:3464 +#: ../../../CHANGELOG.md:4071 msgid "Until now, the `config.yaml` file for the [Discord bridge](docs/configuring-playbook-bridge-appservice-discord.md) was managed by the playbook, but the `registration.yaml` file was not." msgstr "" -#: ../../../CHANGELOG.md:3466 +#: ../../../CHANGELOG.md:4073 msgid "From now on, the playbook will keep both configuration files sync for you." msgstr "" -#: ../../../CHANGELOG.md:3468 +#: ../../../CHANGELOG.md:4075 msgid "This means that if you were making manual changes to the `/matrix/appservice-discord/discord-registration.yaml` configuration file, those would be lost the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3470 +#: ../../../CHANGELOG.md:4077 msgid "The bridge now stores configuration in a subdirectory (`/matrix/appservice-discord/config`)." msgstr "" -#: ../../../CHANGELOG.md:3472 +#: ../../../CHANGELOG.md:4079 msgid "Likewise, data is now also stored in a subdirectory (`/matrix/appservice-discord/data`). When you run the playbook with an existing database file (`/matrix/appservice-discord/discord.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3474 +#: ../../../CHANGELOG.md:4081 msgid "The main directory (`/matrix/appservice-discord`) may contain some leftover files (`user-store.db`, `room-store.db`, `config.yaml`, `discord-registration.yaml`, `invite_link`). These are no longer necessary and can be deleted manually." msgstr "" -#: ../../../CHANGELOG.md:3476 +#: ../../../CHANGELOG.md:4083 msgid "We're now following the default sample configuration for the Discord bridge. If you need to override some values, define them in `matrix_appservice_discord_configuration_extension_yaml`." msgstr "" -#: ../../../CHANGELOG.md:3479 +#: ../../../CHANGELOG.md:4086 msgid "2019-06-24" msgstr "" -#: ../../../CHANGELOG.md:3481 +#: ../../../CHANGELOG.md:4088 msgid "(BC Break) WhatsApp bridge configuration is now entirely managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:3483 +#: ../../../CHANGELOG.md:4090 msgid "Until now, configuration files for the [WhatsApp bridge](docs/configuring-playbook-bridge-mautrix-whatsapp.md) were created by the playbook initially, but never modified later on." msgstr "" -#: ../../../CHANGELOG.md:3485 -#: ../../../CHANGELOG.md:3502 -#: ../../../CHANGELOG.md:3521 -#: ../../../CHANGELOG.md:3560 +#: ../../../CHANGELOG.md:4092 +#: ../../../CHANGELOG.md:4109 +#: ../../../CHANGELOG.md:4128 +#: ../../../CHANGELOG.md:4167 msgid "From now on, the playbook will keep the configuration in sync for you." msgstr "" -#: ../../../CHANGELOG.md:3487 +#: ../../../CHANGELOG.md:4094 msgid "This means that if you were making manual changes to the `/matrix/mautrix-whatsapp/config.yaml` or `/matrix/mautrix-whatsapp/registration.yaml` configuration files, those would be lost the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3489 +#: ../../../CHANGELOG.md:4096 msgid "The bridge now stores configuration in a subdirectory (`/matrix/mautrix-whatsapp/config`), so your old configuration remains in the base directory (`/matrix/mautrix-whatsapp`). You need to migrate any manual changes over to the new `matrix_mautrix_whatsapp_configuration_extension_yaml` variable, so that the playbook would apply them for you." msgstr "" -#: ../../../CHANGELOG.md:3491 +#: ../../../CHANGELOG.md:4098 msgid "Likewise, data is now also stored in a subdirectory (`/matrix/mautrix-whatsapp/data`). When you run the playbook with an existing database file (`/matrix/mautrix-whatsapp/mautrix-whatsapp.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3493 +#: ../../../CHANGELOG.md:4100 msgid "We're now following the default configuration for the WhatsApp bridge." msgstr "" -#: ../../../CHANGELOG.md:3496 +#: ../../../CHANGELOG.md:4103 msgid "2019-06-20" msgstr "" -#: ../../../CHANGELOG.md:3498 +#: ../../../CHANGELOG.md:4105 msgid "(BC Break) IRC bridge configuration is now entirely managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:3500 +#: ../../../CHANGELOG.md:4107 msgid "Until now, configuration files for the [IRC bridge](docs/configuring-playbook-bridge-appservice-irc.md) were created by the playbook initially, but never modified later on." msgstr "" -#: ../../../CHANGELOG.md:3504 +#: ../../../CHANGELOG.md:4111 msgid "This means that if you were making manual changes to the `/matrix/appservice-irc/config.yaml` or `/matrix/appservice-irc/registration.yaml` configuration files, those would be lost the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3506 +#: ../../../CHANGELOG.md:4113 msgid "The bridge now stores configuration in a subdirectory (`/matrix/appservice-irc/config`), so your old configuration remains in the base directory (`/matrix/appservice-irc`)." msgstr "" -#: ../../../CHANGELOG.md:3508 +#: ../../../CHANGELOG.md:4115 msgid "Previously, we asked people to configure bridged IRC servers by extending the bridge configuration (`matrix_appservice_irc_configuration_extension_yaml`). While this is still possible and will continue working forever, **we now recommend defining IRC servers in the easier to use `matrix_appservice_irc_ircService_servers` variable**. See [our IRC bridge documentation page](docs/configuring-playbook-bridge-appservice-irc.md) for an example." msgstr "" -#: ../../../CHANGELOG.md:3510 +#: ../../../CHANGELOG.md:4117 msgid "If you decide to continue using `matrix_appservice_irc_configuration_extension_yaml`, you might be interested to know that `ircService.databaseUri` and a few other keys now have default values in the base configuration (`matrix_appservice_irc_configuration_yaml`). You may wish to stop redefining those keys, unless you really intend to override them. You most likely only need to override `ircService.servers`." msgstr "" -#: ../../../CHANGELOG.md:3512 +#: ../../../CHANGELOG.md:4119 msgid "Bridge data (`passkey.pem` and database files) is now also stored in a subdirectory (`/matrix/appservice-irc/data`). When you run the playbook with an existing `/matrix/appservice-irc/passkey.pem` file, the playbook will stop the bridge and relocate the passkey and database files (`rooms.db` and `users.db`) to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3515 +#: ../../../CHANGELOG.md:4122 msgid "2019-06-15" msgstr "" -#: ../../../CHANGELOG.md:3517 +#: ../../../CHANGELOG.md:4124 msgid "(BC Break) Telegram bridge configuration is now entirely managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:3519 +#: ../../../CHANGELOG.md:4126 msgid "Until now, configuration files for the [Telegram bridge](docs/configuring-playbook-bridge-mautrix-telegram.md) were created by the playbook initially, but never modified later on." msgstr "" -#: ../../../CHANGELOG.md:3523 +#: ../../../CHANGELOG.md:4130 msgid "This means that if you were making manual changes to the `/matrix/mautrix-telegram/config.yaml` or `/matrix/mautrix-telegram/registration.yaml` configuration files, those would be lost the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3525 +#: ../../../CHANGELOG.md:4132 msgid "The bridge now stores configuration in a subdirectory (`/matrix/mautrix-telegram/config`), so your old configuration remains in the base directory (`/matrix/mautrix-telegram`). You need to migrate any manual changes over to the new `matrix_mautrix_telegram_configuration_extension_yaml` variable, so that the playbook would apply them for you." msgstr "" -#: ../../../CHANGELOG.md:3527 +#: ../../../CHANGELOG.md:4134 msgid "Likewise, data is now also stored in a subdirectory (`/matrix/mautrix-telegram/data`). When you run the playbook with an existing database file (`/matrix/mautrix-telegram/mautrix-telegram.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3529 +#: ../../../CHANGELOG.md:4136 msgid "Also, we're now following the default configuration for the Telegram bridge, so some default configuration values are different:" msgstr "" -#: ../../../CHANGELOG.md:3531 +#: ../../../CHANGELOG.md:4138 msgid "`edits_as_replies` (used to be `false`, now `true`) — previously replies were not sent over to Matrix at all; ow they are sent over as a reply to the original message" msgstr "" -#: ../../../CHANGELOG.md:3532 +#: ../../../CHANGELOG.md:4139 msgid "`inline_images` (used to be `true`, now `false`) — this has to do with captioned images. Inline-image (included caption) are said to exhibit troubles on Riot iOS. When `false`, the caption arrives on the Matrix side as a separate message." msgstr "" -#: ../../../CHANGELOG.md:3533 +#: ../../../CHANGELOG.md:4140 msgid "`authless_portals` (used to be `false`, now `true`) — creating portals from the Telegram side is now possible" msgstr "" -#: ../../../CHANGELOG.md:3534 +#: ../../../CHANGELOG.md:4141 msgid "`whitelist_group_admins` (used to be `false`, now `true`) — allows Telegram group admins to use the bot commands" msgstr "" -#: ../../../CHANGELOG.md:3536 +#: ../../../CHANGELOG.md:4143 msgid "If the new values are not to your liking, use `matrix_mautrix_telegram_configuration_extension_yaml` to specify an override (refer to `matrix_mautrix_telegram_configuration_yaml` to figure out which variable goes where)." msgstr "" -#: ../../../CHANGELOG.md:3539 +#: ../../../CHANGELOG.md:4146 msgid "2019-06-12" msgstr "" -#: ../../../CHANGELOG.md:3541 +#: ../../../CHANGELOG.md:4148 msgid "Synapse v1.0" msgstr "" -#: ../../../CHANGELOG.md:3543 +#: ../../../CHANGELOG.md:4150 msgid "With [Synapse v1.0 now available](https://matrix.org/blog/2019/06/11/introducing-matrix-1-0-and-the-matrix-org-foundation) and most people being on at least Synapse v0.99, it's time to remove the `_matrix._tcp` DNS SRV record that we've been keeping for compatibility with old Synapse versions (<= 0.34)." msgstr "" -#: ../../../CHANGELOG.md:3545 +#: ../../../CHANGELOG.md:4152 msgid "According to the [Server Discovery specification](https://matrix.org/docs/spec/server_server/r0.1.2.html#server-discovery), it's no harm to keep the DNS SRV record. But since it's not necessary for federating with the larger Matrix network anymore, you should be safe to get rid of it." msgstr "" -#: ../../../CHANGELOG.md:3547 +#: ../../../CHANGELOG.md:4154 msgid "**Note**: don't confuse the `_matrix._tcp` and `_matrix-identity._tcp` DNS SRV records. The latter, **must not** be removed." msgstr "" -#: ../../../CHANGELOG.md:3549 +#: ../../../CHANGELOG.md:4156 msgid "For completeness, we must say that using a `_matrix._tcp` [SRV record for Server Delegation](docs/howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced) is still valid and useful for certain deployments. It's just that our guide recommends the [`/.well-known/matrix/server` Server Delegation method](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), due to its easier implementation when using this playbook." msgstr "" -#: ../../../CHANGELOG.md:3551 +#: ../../../CHANGELOG.md:4158 msgid "Besides this optional/non-urgent DNS change, assuming you're already on Synapse v0.99, upgrading to Synapse v1.0 should be as simple as [re-running the playbook](docs/maintenance-upgrading-services.md)." msgstr "" -#: ../../../CHANGELOG.md:3554 +#: ../../../CHANGELOG.md:4161 msgid "2019-06-07" msgstr "" -#: ../../../CHANGELOG.md:3556 +#: ../../../CHANGELOG.md:4163 msgid "(BC Break) Facebook bridge configuration is now entirely managed by the playbook" msgstr "" -#: ../../../CHANGELOG.md:3558 +#: ../../../CHANGELOG.md:4165 msgid "Until now, configuration files for the [Facebook bridge](docs/configuring-playbook-bridge-mautrix-facebook.md) were created by the playbook initially, but never modified later on." msgstr "" -#: ../../../CHANGELOG.md:3562 +#: ../../../CHANGELOG.md:4169 msgid "This means that if you were making manual changes to the `/matrix/mautrix-facebook/config.yaml` or `/matrix/mautrix-facebook/registration.yaml` configuration files, those would be lost the next time you run the playbook." msgstr "" -#: ../../../CHANGELOG.md:3564 +#: ../../../CHANGELOG.md:4171 msgid "The bridge now stores configuration in a subdirectory (`/matrix/mautrix-facebook/config`), so your old configuration remains in the base directory (`/matrix/mautrix-facebook`). You need to migrate any manual changes over to the new `matrix_mautrix_facebook_configuration_extension_yaml` variable, so that the playbook would apply them for you." msgstr "" -#: ../../../CHANGELOG.md:3566 +#: ../../../CHANGELOG.md:4173 msgid "Likewise, data is now also stored in a subdirectory (`/matrix/mautrix-facebook/data`). When you run the playbook with an existing database file (`/matrix/mautrix-facebook/mautrix-facebook.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3569 +#: ../../../CHANGELOG.md:4176 msgid "2019-05-25" msgstr "" -#: ../../../CHANGELOG.md:3571 +#: ../../../CHANGELOG.md:4178 msgid "Support for exposing container ports publicly (not just to the host)" msgstr "" -#: ../../../CHANGELOG.md:3573 +#: ../../../CHANGELOG.md:4180 msgid "Until now, various roles supported a `matrix_*_expose_port` variable, which would expose their container's port to the host. This was mostly useful for reverse-proxying manually (in case `matrix-nginx-proxy` was disabled). It could also be used for installing some playbook services (e.g. bridges, etc.) and wiring them to a separate (manual) Matrix setup." msgstr "" -#: ../../../CHANGELOG.md:3575 +#: ../../../CHANGELOG.md:4182 msgid "`matrix_*_expose_port` variables were not granular enough — sometimes they would expose one port, other times multiple. They also didn't provide control over **where** to expose (to which port number and to which network interface), because they would usually hardcode something like `127.0.0.1:8080`." msgstr "" -#: ../../../CHANGELOG.md:3577 +#: ../../../CHANGELOG.md:4184 msgid "All such variables have been superseded by a better (more flexible) way to do it." msgstr "" -#: ../../../CHANGELOG.md:3579 +#: ../../../CHANGELOG.md:4186 msgid "**Most** people (including those not using `matrix-nginx-proxy`), **don't need** to bother with this." msgstr "" -#: ../../../CHANGELOG.md:3581 +#: ../../../CHANGELOG.md:4188 msgid "Porting examples follow for people having more customized setups:" msgstr "" -#: ../../../CHANGELOG.md:3583 +#: ../../../CHANGELOG.md:4190 msgid "**from** `matrix_synapse_container_expose_client_api_port: true` **to** `matrix_synapse_container_client_api_host_bind_port: '127.0.0.1:8008'`" msgstr "" -#: ../../../CHANGELOG.md:3585 +#: ../../../CHANGELOG.md:4192 msgid "**from** `matrix_synapse_container_expose_federation_api_port: true` **to** `matrix_synapse_container_federation_api_plain_host_bind_port: '127.0.0.1:8048'` and possibly `matrix_synapse_container_federation_api_tls_host_bind_port: '8448'`" msgstr "" -#: ../../../CHANGELOG.md:3587 +#: ../../../CHANGELOG.md:4194 msgid "**from** `matrix_synapse_container_expose_metrics_port: true` **to** `matrix_synapse_container_metrics_api_host_bind_port: '127.0.0.1:9100'`" msgstr "" -#: ../../../CHANGELOG.md:3589 +#: ../../../CHANGELOG.md:4196 msgid "**from** `matrix_riot_web_container_expose_port: true` **to** `matrix_riot_web_container_http_host_bind_port: '127.0.0.1:8765'`" msgstr "" -#: ../../../CHANGELOG.md:3591 +#: ../../../CHANGELOG.md:4198 msgid "**from** `matrix_mxisd_container_expose_port: true` **to** `matrix_mxisd_container_http_host_bind_port: '127.0.0.1:8090'`" msgstr "" -#: ../../../CHANGELOG.md:3593 +#: ../../../CHANGELOG.md:4200 msgid "**from** `matrix_dimension_container_expose_port: true` **to** `matrix_dimension_container_http_host_bind_port: '127.0.0.1:8184'`" msgstr "" -#: ../../../CHANGELOG.md:3595 +#: ../../../CHANGELOG.md:4202 msgid "**from** `matrix_corporal_container_expose_ports: true` **to** `matrix_corporal_container_http_gateway_host_bind_port: '127.0.0.1:41080'` and possibly `matrix_corporal_container_http_api_host_bind_port: '127.0.0.1:41081'`" msgstr "" -#: ../../../CHANGELOG.md:3597 +#: ../../../CHANGELOG.md:4204 msgid "**from** `matrix_appservice_irc_container_expose_client_server_api_port: true` **to** `matrix_appservice_irc_container_http_host_bind_port: '127.0.0.1:9999'`" msgstr "" -#: ../../../CHANGELOG.md:3599 +#: ../../../CHANGELOG.md:4206 msgid "**from** `matrix_appservice_discord_container_expose_client_server_api_port: true` **to** `matrix_appservice_discord_container_http_host_bind_port: '127.0.0.1:9005'`" msgstr "" -#: ../../../CHANGELOG.md:3601 +#: ../../../CHANGELOG.md:4208 msgid "As always, if you forget to remove usage of some outdated variable, the playbook will warn you." msgstr "" -#: ../../../CHANGELOG.md:3604 +#: ../../../CHANGELOG.md:4211 msgid "2019-05-23" msgstr "" -#: ../../../CHANGELOG.md:3606 +#: ../../../CHANGELOG.md:4213 msgid "(BC Break) Ansible 2.8 compatibility" msgstr "" -#: ../../../CHANGELOG.md:3608 +#: ../../../CHANGELOG.md:4215 msgid "Thanks to [@danbob](https://github.com/danbob), the playbook now [supports the new Ansible 2.8](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/187)." msgstr "" -#: ../../../CHANGELOG.md:3610 +#: ../../../CHANGELOG.md:4217 msgid "A manual change is required to the `inventory/hosts` file, changing the group name from `matrix-servers` to `matrix_servers` (dash to underscore)." msgstr "" -#: ../../../CHANGELOG.md:3612 +#: ../../../CHANGELOG.md:4219 msgid "To avoid doing it manually, run this:" msgstr "" -#: ../../../CHANGELOG.md:3613 +#: ../../../CHANGELOG.md:4220 msgid "Linux: `sed -i 's/matrix-servers/matrix_servers/g' inventory/hosts`" msgstr "" -#: ../../../CHANGELOG.md:3614 +#: ../../../CHANGELOG.md:4221 msgid "Mac: `sed -i '' 's/matrix-servers/matrix_servers/g' inventory/hosts`" msgstr "" -#: ../../../CHANGELOG.md:3617 +#: ../../../CHANGELOG.md:4224 msgid "2019-05-21" msgstr "" -#: ../../../CHANGELOG.md:3619 +#: ../../../CHANGELOG.md:4226 msgid "Synapse no longer required" msgstr "" -#: ../../../CHANGELOG.md:3621 +#: ../../../CHANGELOG.md:4228 msgid "The playbook no longer insists on installing [Synapse](https://github.com/element-hq/synapse) via the `matrix-synapse` role." msgstr "" -#: ../../../CHANGELOG.md:3623 +#: ../../../CHANGELOG.md:4230 msgid "If you would prefer to install Synapse another way and just use the playbook to install other services, it should be possible (`matrix_synapse_enabled: false`)." msgstr "" -#: ../../../CHANGELOG.md:3625 +#: ../../../CHANGELOG.md:4232 msgid "Note that it won't necessarily be the best experience, since the playbook wires things to Synapse by default. If you're using your own Synapse instance (especially one not running in a container), you may have to override many variables to point them to the correct place." msgstr "" -#: ../../../CHANGELOG.md:3627 +#: ../../../CHANGELOG.md:4234 msgid "Having Synapse not be a required component potentially opens the door for installing alternative Matrix homeservers." msgstr "" -#: ../../../CHANGELOG.md:3629 +#: ../../../CHANGELOG.md:4236 msgid "Bridges are now separate from the Synapse role" msgstr "" -#: ../../../CHANGELOG.md:3631 +#: ../../../CHANGELOG.md:4238 msgid "Bridges are no longer part of the `matrix-synapse` role. Each bridge now lives in its own separate role (`roles/custom/matrix-bridge-*`)." msgstr "" -#: ../../../CHANGELOG.md:3633 +#: ../../../CHANGELOG.md:4240 msgid "These bridge roles are independent of the `matrix-synapse` role, so it should be possible to use them with a Synapse instance installed another way (not through the playbook)." msgstr "" -#: ../../../CHANGELOG.md:3635 +#: ../../../CHANGELOG.md:4242 msgid "Renaming inconsistently-named Synapse variables" msgstr "" -#: ../../../CHANGELOG.md:3637 +#: ../../../CHANGELOG.md:4244 msgid "For better consistency, the following variables have been renamed:" msgstr "" -#: ../../../CHANGELOG.md:3639 +#: ../../../CHANGELOG.md:4246 msgid "`matrix_enable_room_list_search` was renamed to `matrix_synapse_enable_room_list_search`" msgstr "" -#: ../../../CHANGELOG.md:3640 +#: ../../../CHANGELOG.md:4247 msgid "`matrix_alias_creation_rules` was renamed to `matrix_synapse_alias_creation_rules`" msgstr "" -#: ../../../CHANGELOG.md:3641 +#: ../../../CHANGELOG.md:4248 msgid "`matrix_nginx_proxy_matrix_room_list_publication_rulesdata_path` was renamed to `matrix_synapse_room_list_publication_rules`" msgstr "" -#: ../../../CHANGELOG.md:3644 +#: ../../../CHANGELOG.md:4251 msgid "2019-05-09" msgstr "" -#: ../../../CHANGELOG.md:3646 +#: ../../../CHANGELOG.md:4253 msgid "Besides a myriad of bug fixes and minor improvements, here are the more notable (bigger) features we can announce today." msgstr "" -#: ../../../CHANGELOG.md:3648 +#: ../../../CHANGELOG.md:4255 msgid "Mautrix Facebook/Messenger bridging support" msgstr "" -#: ../../../CHANGELOG.md:3650 +#: ../../../CHANGELOG.md:4257 msgid "The playbook now supports bridging with [Facebook](https://www.facebook.com/) by installing the [mautrix-facebook](https://github.com/tulir/mautrix-facebook) bridge. This playbook functionality is available thanks to [@izissise](https://github.com/izissise)." msgstr "" -#: ../../../CHANGELOG.md:3652 +#: ../../../CHANGELOG.md:4259 msgid "Additional details are available in [Setting up Mautrix Facebook bridging](docs/configuring-playbook-bridge-mautrix-facebook.md)." msgstr "" -#: ../../../CHANGELOG.md:3654 +#: ../../../CHANGELOG.md:4261 msgid "mxisd Registration feature integration" msgstr "" -#: ../../../CHANGELOG.md:3656 +#: ../../../CHANGELOG.md:4263 msgid "The playbook can now help you integrate with mxisd's [Registration](https://github.com/kamax-matrix/mxisd/blob/master/docs/features/registration.md) feature." msgstr "" -#: ../../../CHANGELOG.md:3658 +#: ../../../CHANGELOG.md:4265 msgid "Learn more in [mxisd-controlled Registration](docs/configuring-playbook-mxisd.md#mxisd-controlled-registration)." msgstr "" -#: ../../../CHANGELOG.md:3661 +#: ../../../CHANGELOG.md:4268 msgid "2019-04-16" msgstr "" -#: ../../../CHANGELOG.md:3663 +#: ../../../CHANGELOG.md:4270 msgid "Caddy webserver examples" msgstr "" -#: ../../../CHANGELOG.md:3665 +#: ../../../CHANGELOG.md:4272 msgid "If you prefer using the [Caddy](https://caddyserver.com/) webserver instead of our own integrated nginx, we now have examples for it in the [`examples/caddy`](examples/caddy) directory" msgstr "" -#: ../../../CHANGELOG.md:3667 +#: ../../../CHANGELOG.md:4274 msgid "2019-04-10" msgstr "" -#: ../../../CHANGELOG.md:3669 +#: ../../../CHANGELOG.md:4276 msgid "Goofys support for other S3-compatible object stores" msgstr "" -#: ../../../CHANGELOG.md:3671 +#: ../../../CHANGELOG.md:4278 msgid "Until now, you could optionally host Synapse's media repository on Amazon S3, but we now also support [using other S3-compatible object stores](docs/configuring-playbook-s3.md)," msgstr "" -#: ../../../CHANGELOG.md:3674 +#: ../../../CHANGELOG.md:4281 msgid "2019-04-03" msgstr "" -#: ../../../CHANGELOG.md:3676 +#: ../../../CHANGELOG.md:4283 msgid "Ansible >= 2.5 is required" msgstr "" -#: ../../../CHANGELOG.md:3678 +#: ../../../CHANGELOG.md:4285 msgid "Due to recent playbook improvements and the fact that the world keeps turning, we're bumping the [version requirement for Ansible](docs/ansible.md#supported-ansible-versions) (2.4 -> 2.5)." msgstr "" -#: ../../../CHANGELOG.md:3680 +#: ../../../CHANGELOG.md:4287 msgid "We've also started building our own Docker image of Ansible ([devture/ansible](https://hub.docker.com/r/devture/ansible/)), which is useful for people who can't upgrade their local Ansible installation (see [Using Ansible via Docker](docs/ansible.md#using-ansible-via-docker))." msgstr "" -#: ../../../CHANGELOG.md:3683 +#: ../../../CHANGELOG.md:4290 msgid "2019-03-19" msgstr "" -#: ../../../CHANGELOG.md:3685 +#: ../../../CHANGELOG.md:4292 msgid "TLS support for coturn" msgstr "" -#: ../../../CHANGELOG.md:3687 +#: ../../../CHANGELOG.md:4294 msgid "We've added TLS support to the coturn TURN server installed by the playbook by default. The certificates from the Matrix domain will be used for the coturn server." msgstr "" -#: ../../../CHANGELOG.md:3689 +#: ../../../CHANGELOG.md:4296 msgid "This feature is enabled by default for new installations. To make use of TLS support for your existing Matrix server's coturn, make sure to rebuild both coturn and Synapse:" msgstr "" -#: ../../../CHANGELOG.md:3695 +#: ../../../CHANGELOG.md:4302 msgid "People who have an extra firewall (besides the iptables firewall, which Docker manages automatically), will need to open these additional firewall ports: `5349/tcp` (TURN over TCP) and `5349/udp` (TURN over UDP)." msgstr "" -#: ../../../CHANGELOG.md:3697 +#: ../../../CHANGELOG.md:4304 msgid "People who build their own custom playbook from our roles should be aware that:" msgstr "" -#: ../../../CHANGELOG.md:3699 +#: ../../../CHANGELOG.md:4306 msgid "the `matrix-coturn` role and actually starting coturn (e.g. `--tags=start`), requires that certificates are already put in place. For this reason, it's usually a good idea to have the `matrix-coturn` role execute after `matrix-nginx-proxy` (which retrieves the certificates)." msgstr "" -#: ../../../CHANGELOG.md:3701 +#: ../../../CHANGELOG.md:4308 msgid "there are a few variables that can help you enable TLS support for coturn. See the `matrix-coturn` section in [group_vars/matrix-servers](./group_vars/matrix-servers)." msgstr "" -#: ../../../CHANGELOG.md:3704 +#: ../../../CHANGELOG.md:4311 msgid "2019-03-12" msgstr "" -#: ../../../CHANGELOG.md:3706 +#: ../../../CHANGELOG.md:4313 msgid "matrix-nginx-proxy support for serving the base domain" msgstr "" -#: ../../../CHANGELOG.md:3708 +#: ../../../CHANGELOG.md:4315 msgid "If you don't have a dedicated server for your base domain and want to set up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), the playbook has got you covered now." msgstr "" -#: ../../../CHANGELOG.md:3710 +#: ../../../CHANGELOG.md:4317 msgid "It's now possible for the playbook to obtain an SSL certificate and serve the necessary files for Matrix Server Delegation on your base domain. Take a look at the new [Serving the base domain](docs/configuring-playbook-base-domain-serving.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:3712 +#: ../../../CHANGELOG.md:4319 msgid "(BC break) matrix-nginx-proxy data variable renamed" msgstr "" -#: ../../../CHANGELOG.md:3714 +#: ../../../CHANGELOG.md:4321 msgid "`matrix_nginx_proxy_data_path` was renamed to `matrix_nginx_proxy_base_path`." msgstr "" -#: ../../../CHANGELOG.md:3716 +#: ../../../CHANGELOG.md:4323 msgid "There's a new `matrix_nginx_proxy_data_path` variable, which has a different use-purpose now (it's a subdirectory of `matrix_nginx_proxy_base_path` and is meant for storing various data files)." msgstr "" -#: ../../../CHANGELOG.md:3719 +#: ../../../CHANGELOG.md:4326 msgid "2019-03-10" msgstr "" -#: ../../../CHANGELOG.md:3721 +#: ../../../CHANGELOG.md:4328 msgid "Dimension integration manager support" msgstr "" -#: ../../../CHANGELOG.md:3723 +#: ../../../CHANGELOG.md:4330 msgid "Thanks to [NullIsNot0](https://github.com/NullIsNot0), the playbook can now (optionally) install the [Dimension](https://dimension.t2bot.io/) integration manager. To learn more, see the [Setting up Dimension](docs/configuring-playbook-dimension.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:3726 +#: ../../../CHANGELOG.md:4333 msgid "2019-03-07" msgstr "" -#: ../../../CHANGELOG.md:3728 +#: ../../../CHANGELOG.md:4335 msgid "Ability to customize mxisd's email templates" msgstr "" -#: ../../../CHANGELOG.md:3730 +#: ../../../CHANGELOG.md:4337 msgid "Thanks to [Sylvia van Os](https://github.com/TheLastProject), mxisd's email templates can now be customized easily. To learn more, see the [Customizing email templates](docs/configuring-playbook-mxisd.md#customizing-email-templates) documentation page." msgstr "" -#: ../../../CHANGELOG.md:3733 +#: ../../../CHANGELOG.md:4340 msgid "2019-03-05" msgstr "" -#: ../../../CHANGELOG.md:3735 +#: ../../../CHANGELOG.md:4342 msgid "Discord bridging support" msgstr "" -#: ../../../CHANGELOG.md:3737 +#: ../../../CHANGELOG.md:4344 msgid "[@Lionstiger](https://github.com/Lionstiger) has done some great work adding Discord bridging support via [matrix-appservice-discord](https://github.com/matrix-org/matrix-appservice-discord). To learn more, see the [Setting up Appservice Discord bridging](docs/configuring-playbook-bridge-appservice-discord.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:3740 +#: ../../../CHANGELOG.md:4347 msgid "2019-02-19" msgstr "" -#: ../../../CHANGELOG.md:3742 +#: ../../../CHANGELOG.md:4349 msgid "Renaming variables" msgstr "" -#: ../../../CHANGELOG.md:3744 -#: ../../../CHANGELOG.md:4061 -#: ../../../CHANGELOG.md:4146 -#: ../../../CHANGELOG.md:4266 +#: ../../../CHANGELOG.md:4351 +#: ../../../CHANGELOG.md:4668 +#: ../../../CHANGELOG.md:4753 +#: ../../../CHANGELOG.md:4873 msgid "The following playbook variables were renamed:" msgstr "" -#: ../../../CHANGELOG.md:3746 +#: ../../../CHANGELOG.md:4353 msgid "from `host_specific_hostname_identity` to `matrix_domain`" msgstr "" -#: ../../../CHANGELOG.md:3747 +#: ../../../CHANGELOG.md:4354 msgid "from `hostname_identity` to `matrix_domain`" msgstr "" -#: ../../../CHANGELOG.md:3748 +#: ../../../CHANGELOG.md:4355 msgid "from `hostname_matrix` to `matrix_server_fqn_matrix`" msgstr "" -#: ../../../CHANGELOG.md:3749 +#: ../../../CHANGELOG.md:4356 msgid "from `hostname_riot` to `matrix_server_fqn_riot`" msgstr "" -#: ../../../CHANGELOG.md:3750 +#: ../../../CHANGELOG.md:4357 msgid "from `host_specific_matrix_ssl_lets_encrypt_support_email` to `matrix_ssl_lets_encrypt_support_email`" msgstr "" -#: ../../../CHANGELOG.md:3752 +#: ../../../CHANGELOG.md:4359 msgid "Doing that, we've simplified things, made names less confusing (hopefully) and moved all variable names under the `matrix_` prefix." msgstr "" -#: ../../../CHANGELOG.md:3755 +#: ../../../CHANGELOG.md:4362 msgid "2019-02-16" msgstr "" -#: ../../../CHANGELOG.md:3757 +#: ../../../CHANGELOG.md:4364 msgid "Riot v1.0.1 support" msgstr "" -#: ../../../CHANGELOG.md:3759 +#: ../../../CHANGELOG.md:4366 msgid "You can now use the brand new and redesigned Riot." msgstr "" -#: ../../../CHANGELOG.md:3761 +#: ../../../CHANGELOG.md:4368 msgid "The new version no longer has a homepage by default, so we've also removed the custom homepage that we've been installing." msgstr "" -#: ../../../CHANGELOG.md:3763 +#: ../../../CHANGELOG.md:4370 msgid "However, we still provide you with hooks to install your own `home.html` file by specifying the `matrix_riot_web_embedded_pages_home_path` variable (used to be called `matrix_riot_web_homepage_template` before)." msgstr "" -#: ../../../CHANGELOG.md:3766 +#: ../../../CHANGELOG.md:4373 msgid "2019-02-14" msgstr "" -#: ../../../CHANGELOG.md:3768 +#: ../../../CHANGELOG.md:4375 msgid "Synapse v0.99.1" msgstr "" -#: ../../../CHANGELOG.md:3770 +#: ../../../CHANGELOG.md:4377 msgid "As we're moving toward Synapse v1.0, things are beginning to stabilize. Upgrading from v0.99.0 to v0.99.1 should be painless." msgstr "" -#: ../../../CHANGELOG.md:3772 +#: ../../../CHANGELOG.md:4379 msgid "If you've been overriding the default configuration so that you can terminate TLS at the Synapse side (`matrix_synapse_no_tls: false`), you'll now have to replace this custom configuration with `matrix_synapse_tls_federation_listener_enabled: true`. The `matrix_synapse_no_tls` variable is no more." msgstr "" -#: ../../../CHANGELOG.md:3775 +#: ../../../CHANGELOG.md:4382 msgid "2019-02-06" msgstr "" -#: ../../../CHANGELOG.md:3777 +#: ../../../CHANGELOG.md:4384 msgid "Synapse v0.99 support and preparation for Synapse v1.0" msgstr "" -#: ../../../CHANGELOG.md:3779 +#: ../../../CHANGELOG.md:4386 msgid "Matrix is undergoing a lot of changes as it matures towards Synapse v1.0. The first step is the Synapse v0.99 transitional release, which this playbook now supports." msgstr "" -#: ../../../CHANGELOG.md:3781 +#: ../../../CHANGELOG.md:4388 msgid "If you've been using this playbook successfully until now, you'd be aware that we've been doing [Server Delegation](docs/howto-server-delegation.md) using a `_matrix._tcp` DNS SRV record (as per [Configuring DNS](docs/configuring-dns.md))." msgstr "" -#: ../../../CHANGELOG.md:3783 +#: ../../../CHANGELOG.md:4390 msgid "Due to changes related to certificate file requirements that will affect us at Synapse v1.0, we'll have to stop using a **`_matrix._tcp` DNS SRV record in the future** (when Synapse goes to v1.0 — around 5th of March 2019). We **still need to keep the SRV record for now**, for backward compatibility with older Synapse versions (lower than v0.99)." msgstr "" -#: ../../../CHANGELOG.md:3785 +#: ../../../CHANGELOG.md:4392 msgid "**What you need to do now** is make use of this transitional Synapse v0.99 release to **prepare your federation settings for the future**. You have 2 choices to prepare yourself for compatibility with the future Synapse v1.0:" msgstr "" -#: ../../../CHANGELOG.md:3787 +#: ../../../CHANGELOG.md:4394 msgid "(recommended) set up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), unless you are affected by the [Downsides of well-known-based Server Delegation](docs/howto-server-delegation.md#downsides-of-well-known-based-server-delegation). If you had previously set up the well-known `client` file, depending on how you've done it, it may be that there is nothing new required of you (besides [upgrading](docs/maintenance-upgrading-services.md)). After upgrading, you can [run a self-check](docs/maintenance-and-troubleshooting.md#how-to-check-if-services-work), which will tell you if you need to do anything extra with regard to setting up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file). After some time, when most people have upgraded to Synapse v0.99 and older releases have disappeared, be prepared to drop your `_matrix._tcp` SRV record." msgstr "" -#: ../../../CHANGELOG.md:3789 +#: ../../../CHANGELOG.md:4396 msgid "(more advanced) if the [Downsides of well-known-based Server Delegation](docs/howto-server-delegation.md#downsides-of-well-known-based-server-delegation) are not to your liking, **as an alternative**, you can set up [Server Delegation via a DNS SRV record](docs/howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced). In such a case, you get to keep using your existing `_matrix._tcp` DNS SRV record forever and need to NOT set up a `/.well-known/matrix/server` file. Don't forget that you need to do certificate changes though. Follow the guide at [Server Delegation via a DNS SRV record](docs/howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced)." msgstr "" -#: ../../../CHANGELOG.md:3792 +#: ../../../CHANGELOG.md:4399 msgid "2019-02-01" msgstr "" -#: ../../../CHANGELOG.md:3794 +#: ../../../CHANGELOG.md:4401 msgid "TLS v1.3 support" msgstr "" -#: ../../../CHANGELOG.md:3796 +#: ../../../CHANGELOG.md:4403 msgid "Now that the [nginx Docker image](https://hub.docker.com/_/nginx) has [added support for TLS v1.3](https://github.com/nginxinc/docker-nginx/issues/190), we have enabled that protocol by default." msgstr "" -#: ../../../CHANGELOG.md:3798 +#: ../../../CHANGELOG.md:4405 msgid "When using:" msgstr "" -#: ../../../CHANGELOG.md:3800 +#: ../../../CHANGELOG.md:4407 msgid "the **integrated nginx server**: TLS v1.3 support might not kick in immediately, because the nginx version hasn't been bumped and you may have an older build of the nginx Docker image (currently `nginx:1.15.8-alpine`). Typically, we do not re-pull images that you already have. When the nginx version gets bumped in the future, everyone will get the update. Until then, you could manually force-pull the rebuilt Docker image by running this on the server: `docker pull nginx:1.15.8-alpine`." msgstr "" -#: ../../../CHANGELOG.md:3802 +#: ../../../CHANGELOG.md:4409 msgid "**your own external nginx server**: if your external nginx server is too old, the new configuration we generate for you in `/matrix/nginx-proxy/conf.d/` might not work anymore, because it mentions `TLSv1.3` and your nginx version might not support that. You can adjust the SSL protocol list by overriding the `matrix_nginx_proxy_ssl_protocols` variable. Learn more in the documentation page for [Using your own webserver, instead of this playbook's nginx proxy](docs/configuring-playbook-own-webserver.md)" msgstr "" -#: ../../../CHANGELOG.md:3804 +#: ../../../CHANGELOG.md:4411 msgid "**another web server**: you don't need to do anything to accommodate this change" msgstr "" -#: ../../../CHANGELOG.md:3807 +#: ../../../CHANGELOG.md:4414 msgid "2019-01-31" msgstr "" -#: ../../../CHANGELOG.md:3809 +#: ../../../CHANGELOG.md:4416 msgid "IRC bridging support" msgstr "" -#: ../../../CHANGELOG.md:3811 +#: ../../../CHANGELOG.md:4418 msgid "[Devon Maloney (@Plailect)](https://github.com/Plailect) has done some great work bringing IRC bridging support via [matrix-appservice-irc](https://github.com/TeDomum/matrix-appservice-irc). To learn more, see the [Setting up Appservice IRC bridging](docs/configuring-playbook-bridge-appservice-irc.md) documentation page." msgstr "" -#: ../../../CHANGELOG.md:3814 +#: ../../../CHANGELOG.md:4421 msgid "2019-01-29" msgstr "" -#: ../../../CHANGELOG.md:3816 +#: ../../../CHANGELOG.md:4423 msgid "Running container processes as non-root, without capabilities and read-only" msgstr "" -#: ../../../CHANGELOG.md:3818 +#: ../../../CHANGELOG.md:4425 msgid "To improve security, this playbook no longer starts container processes as the `root` user. Most containers were dropping privileges anyway, but we were trusting them with `root` privileges until they would do that. Not anymore — container processes now start as a non-root user (usually `matrix`) from the get-go." msgstr "" -#: ../../../CHANGELOG.md:3820 +#: ../../../CHANGELOG.md:4427 msgid "For additional security, various capabilities are also dropped (see [why it's important](https://github.com/projectatomic/atomic-site/issues/203)) for all containers." msgstr "" -#: ../../../CHANGELOG.md:3822 +#: ../../../CHANGELOG.md:4429 msgid "Additionally, most containers now use a read-only filesystem (see [why it's important](https://www.projectatomic.io/blog/2015/12/making-docker-images-write-only-in-production/)). Containers are given write access only to the directories they need to write to." msgstr "" -#: ../../../CHANGELOG.md:3824 +#: ../../../CHANGELOG.md:4431 msgid "A minor breaking change is the `matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size` variable having being renamed to `matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb` (note the `_mb` suffix). The new variable expects a number value (e.g. `25M` -> `25`). If you weren't customizing this variable, this wouldn't affect you." msgstr "" -#: ../../../CHANGELOG.md:3826 +#: ../../../CHANGELOG.md:4433 msgid "matrix-mailer is now based on Exim, not Postfix" msgstr "" -#: ../../../CHANGELOG.md:3828 +#: ../../../CHANGELOG.md:4435 msgid "While we would have preferred to stay with [Postfix](http://www.postfix.org/), we found out that it cannot run as a non-root user. We've had to replace it with [Exim](https://www.exim.org/) (via the [devture/exim-relay](https://hub.docker.com/r/devture/exim-relay) container image)." msgstr "" -#: ../../../CHANGELOG.md:3830 +#: ../../../CHANGELOG.md:4437 msgid "The internal `matrix-mailer` service (running in a container) now listens on port `8025` (used to be `587` before). The playbook will update your Synapse and mxisd email settings to match (`matrix-mailer:587` -> `matrix-mailer:8025`)." msgstr "" -#: ../../../CHANGELOG.md:3832 +#: ../../../CHANGELOG.md:4439 msgid "Using the [devture/exim-relay](https://hub.docker.com/r/devture/exim-relay) container image instead of [panubo/postfix](https://hub.docker.com/r/panubo/postfix/) also gives us a nice disk usage reduction (~200MB -> 8MB)." msgstr "" -#: ../../../CHANGELOG.md:3835 +#: ../../../CHANGELOG.md:4442 msgid "2019-01-17" msgstr "" -#: ../../../CHANGELOG.md:3837 +#: ../../../CHANGELOG.md:4444 msgid "(BC Break) Making the playbook's roles more independent of one another" msgstr "" -#: ../../../CHANGELOG.md:3839 +#: ../../../CHANGELOG.md:4446 msgid "The following change **affects people running a more non-standard setup** — external Postgres or using our roles in their own other playbook. **Most users don't need to do anything**, besides becoming aware of the new glue variables file [`group_vars/matrix-servers`](group_vars/matrix-servers)." msgstr "" -#: ../../../CHANGELOG.md:3842 +#: ../../../CHANGELOG.md:4449 msgid "Because people like using the playbook's components independently (outside of this playbook) and because it's much better for maintainability, we've continued working on separating them. Still, we'd like to offer a turnkey solution for running a fully-featured Matrix server, so this playbook remains important for wiring up the various components." msgstr "" -#: ../../../CHANGELOG.md:3844 +#: ../../../CHANGELOG.md:4451 msgid "With the new changes, **all roles are now only dependent on the minimal `matrix-base` role**. They are no longer dependent among themselves." msgstr "" -#: ../../../CHANGELOG.md:3846 +#: ../../../CHANGELOG.md:4453 msgid "In addition, the following components can now be completely disabled (for those who want/need to):" msgstr "" -#: ../../../CHANGELOG.md:3847 +#: ../../../CHANGELOG.md:4454 msgid "`matrix-coturn` by using `coturn_enabled: false`" msgstr "" -#: ../../../CHANGELOG.md:3848 +#: ../../../CHANGELOG.md:4455 msgid "`matrix-mailer` by using `matrix_mailer_enabled: false`" msgstr "" -#: ../../../CHANGELOG.md:3849 +#: ../../../CHANGELOG.md:4456 msgid "`matrix-postgres` by using `matrix_postgres_enabled: false`" msgstr "" -#: ../../../CHANGELOG.md:3851 +#: ../../../CHANGELOG.md:4458 msgid "The following changes had to be done:" msgstr "" -#: ../../../CHANGELOG.md:3853 +#: ../../../CHANGELOG.md:4460 msgid "glue variables had to be introduced to the playbook, so it can wire together the various components. Those glue vars are stored in the [`group_vars/matrix-servers`](group_vars/matrix-servers) file. When overriding variables for a given component (role), you need to be aware of both the role defaults (`role/ROLE/defaults/main.yml`) and the role's corresponding section in the [`group_vars/matrix-servers`](group_vars/matrix-servers) file." msgstr "" -#: ../../../CHANGELOG.md:3855 +#: ../../../CHANGELOG.md:4462 msgid "`matrix_postgres_use_external` has been superseded by the more consistently named `matrix_postgres_enabled` variable and a few other `matrix_synapse_database_` variables. See the [Using an external PostgreSQL server (optional)](docs/configuring-playbook-external-postgres.md) documentation page for an up-to-date replacement." msgstr "" -#: ../../../CHANGELOG.md:3857 +#: ../../../CHANGELOG.md:4464 msgid "Postgres tools (`matrix-postgres-cli` and `matrix-make-user-admin`) are no longer installed if you're not enabling the `matrix-postgres` role (`matrix_postgres_enabled: false`)" msgstr "" -#: ../../../CHANGELOG.md:3859 +#: ../../../CHANGELOG.md:4466 msgid "roles, being more independent now, are more minimal and do not do so much magic for you. People that are building their own playbook using our roles will definitely need to take a look at the [`group_vars/matrix-servers`](group_vars/matrix-servers) file and adapt their playbooks with the same (or similar) wiring logic." msgstr "" -#: ../../../CHANGELOG.md:3862 +#: ../../../CHANGELOG.md:4469 msgid "2019-01-16" msgstr "" -#: ../../../CHANGELOG.md:3864 +#: ../../../CHANGELOG.md:4471 msgid "Splitting the playbook into multiple roles" msgstr "" -#: ../../../CHANGELOG.md:3866 +#: ../../../CHANGELOG.md:4473 msgid "For better maintainability, the playbook logic (which all used to reside in a single `matrix-server` role) has been split out into a number of different roles: `matrix-synapse`, `matrix-postgres`, `matrix-riot-web`, `matrix-mxisd`, etc. (see the `roles/` directory)." msgstr "" -#: ../../../CHANGELOG.md:3869 +#: ../../../CHANGELOG.md:4476 msgid "To keep the filesystem more consistent with this separation, the **Postgres data had to be relocated**." msgstr "" -#: ../../../CHANGELOG.md:3871 +#: ../../../CHANGELOG.md:4478 msgid "The default value of `matrix_postgres_data_path` was changed from `/matrix/postgres` to `/matrix/postgres/data`. The `/matrix/postgres` directory is what we consider a base path now (new variable `matrix_postgres_base_path`). **Your Postgres data files will automatically be relocated by the playbook** (`/matrix/postgres/*` -> `/matrix/postgres/data/`) when you run with `--tags=setup-all` (or `--tags=setup-postgres`). While this shouldn't cause data-loss, **it's better if you do a Postgres backup just in case**. You'd need to restart all services after this migration (`--tags=start`)." msgstr "" -#: ../../../CHANGELOG.md:3874 +#: ../../../CHANGELOG.md:4481 msgid "2019-01-11" msgstr "" -#: ../../../CHANGELOG.md:3876 +#: ../../../CHANGELOG.md:4483 msgid "(BC Break) mxisd configuration changes" msgstr "" -#: ../../../CHANGELOG.md:3878 +#: ../../../CHANGELOG.md:4485 msgid "To be more flexible and to support the upcoming [mxisd](https://github.com/kamax-io/mxisd) 1.3.0 (when it gets released), we've had to redo how mxisd gets configured." msgstr "" -#: ../../../CHANGELOG.md:3881 +#: ../../../CHANGELOG.md:4488 msgid "The following variables are no longer supported by this playbook:" msgstr "" -#: ../../../CHANGELOG.md:3883 +#: ../../../CHANGELOG.md:4490 msgid "`matrix_mxisd_ldap_enabled`" msgstr "" -#: ../../../CHANGELOG.md:3884 +#: ../../../CHANGELOG.md:4491 msgid "`matrix_mxisd_ldap_connection_host`" msgstr "" -#: ../../../CHANGELOG.md:3885 +#: ../../../CHANGELOG.md:4492 msgid "`matrix_mxisd_ldap_connection_tls`" msgstr "" -#: ../../../CHANGELOG.md:3886 +#: ../../../CHANGELOG.md:4493 msgid "`matrix_mxisd_ldap_connection_port`" msgstr "" -#: ../../../CHANGELOG.md:3887 +#: ../../../CHANGELOG.md:4494 msgid "`matrix_mxisd_ldap_connection_baseDn`" msgstr "" -#: ../../../CHANGELOG.md:3888 +#: ../../../CHANGELOG.md:4495 msgid "`matrix_mxisd_ldap_connection_baseDns`" msgstr "" -#: ../../../CHANGELOG.md:3889 -#: ../../../CHANGELOG.md:3890 +#: ../../../CHANGELOG.md:4496 +#: ../../../CHANGELOG.md:4497 msgid "`matrix_mxisd_ldap_connection_bindDn`" msgstr "" -#: ../../../CHANGELOG.md:3891 -#: ../../../CHANGELOG.md:3895 +#: ../../../CHANGELOG.md:4498 +#: ../../../CHANGELOG.md:4502 msgid "`matrix_mxisd_ldap_connection_bindPassword`" msgstr "" -#: ../../../CHANGELOG.md:3892 +#: ../../../CHANGELOG.md:4499 msgid "`matrix_mxisd_ldap_filter`" msgstr "" -#: ../../../CHANGELOG.md:3893 +#: ../../../CHANGELOG.md:4500 msgid "`matrix_mxisd_ldap_attribute_uid_type`" msgstr "" -#: ../../../CHANGELOG.md:3894 +#: ../../../CHANGELOG.md:4501 msgid "`matrix_mxisd_ldap_attribute_uid_value`" msgstr "" -#: ../../../CHANGELOG.md:3896 +#: ../../../CHANGELOG.md:4503 msgid "`matrix_mxisd_ldap_attribute_name`" msgstr "" -#: ../../../CHANGELOG.md:3897 +#: ../../../CHANGELOG.md:4504 msgid "`matrix_mxisd_ldap_attribute_threepid_email`" msgstr "" -#: ../../../CHANGELOG.md:3898 +#: ../../../CHANGELOG.md:4505 msgid "`matrix_mxisd_ldap_attribute_threepid_msisdn`" msgstr "" -#: ../../../CHANGELOG.md:3899 +#: ../../../CHANGELOG.md:4506 msgid "`matrix_mxisd_ldap_identity_filter`" msgstr "" -#: ../../../CHANGELOG.md:3900 +#: ../../../CHANGELOG.md:4507 msgid "`matrix_mxisd_ldap_identity_medium`" msgstr "" -#: ../../../CHANGELOG.md:3901 +#: ../../../CHANGELOG.md:4508 msgid "`matrix_mxisd_ldap_auth_filter`" msgstr "" -#: ../../../CHANGELOG.md:3902 +#: ../../../CHANGELOG.md:4509 msgid "`matrix_mxisd_ldap_directory_filter`" msgstr "" -#: ../../../CHANGELOG.md:3903 +#: ../../../CHANGELOG.md:4510 msgid "`matrix_mxisd_template_config`" msgstr "" -#: ../../../CHANGELOG.md:3905 +#: ../../../CHANGELOG.md:4512 msgid "You are encouraged to use the `matrix_mxisd_configuration_extension_yaml` variable to define your own mxisd configuration additions and overrides. Refer to the [default variables file](roles/custom/matrix-mxisd/defaults/main.yml) for more information." msgstr "" -#: ../../../CHANGELOG.md:3907 +#: ../../../CHANGELOG.md:4514 msgid "This new way of configuring mxisd is beneficial because:" msgstr "" -#: ../../../CHANGELOG.md:3909 +#: ../../../CHANGELOG.md:4516 msgid "it lets us support all mxisd configuration options, as the playbook simply forwards them to mxisd without needing to care or understand them" msgstr "" -#: ../../../CHANGELOG.md:3910 +#: ../../../CHANGELOG.md:4517 msgid "it lets you upgrade to newer mxisd versions and make use of their features, without us having to add support for them explicitly" msgstr "" -#: ../../../CHANGELOG.md:3913 +#: ../../../CHANGELOG.md:4520 msgid "2019-01-08" msgstr "" -#: ../../../CHANGELOG.md:3915 +#: ../../../CHANGELOG.md:4522 msgid "(BC Break) Cronjob schedule no longer configurable" msgstr "" -#: ../../../CHANGELOG.md:3917 +#: ../../../CHANGELOG.md:4524 msgid "Due to the way we manage cronjobs now, you can no longer configure the schedule they're invoked at." msgstr "" -#: ../../../CHANGELOG.md:3919 +#: ../../../CHANGELOG.md:4526 msgid "If you were previously using `matrix_ssl_lets_encrypt_renew_cron_time_definition` or `matrix_nginx_proxy_reload_cron_time_definition` to set a custom schedule, you should note that these variables don't affect anything anymore." msgstr "" -#: ../../../CHANGELOG.md:3922 +#: ../../../CHANGELOG.md:4529 msgid "If you miss this functionality, please [open an Issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/new) and let us know about your use case!" msgstr "" -#: ../../../CHANGELOG.md:3925 +#: ../../../CHANGELOG.md:4532 msgid "2018-12-23" msgstr "" -#: ../../../CHANGELOG.md:3927 +#: ../../../CHANGELOG.md:4534 msgid "(BC Break) More SSL certificate retrieval methods" msgstr "" -#: ../../../CHANGELOG.md:3929 +#: ../../../CHANGELOG.md:4536 msgid "The playbook now lets you decide between 3 different SSL certificate retrieval methods:" msgstr "" -#: ../../../CHANGELOG.md:3930 +#: ../../../CHANGELOG.md:4537 msgid "(default) obtaining free SSL certificates from Let's Encrypt" msgstr "" -#: ../../../CHANGELOG.md:3931 +#: ../../../CHANGELOG.md:4538 msgid "generating self-signed SSL certificates" msgstr "" -#: ../../../CHANGELOG.md:3932 +#: ../../../CHANGELOG.md:4539 msgid "managing SSL certificates manually" msgstr "" -#: ../../../CHANGELOG.md:3934 +#: ../../../CHANGELOG.md:4541 msgid "Learn more in [Adjusting SSL certificate retrieval](docs/configuring-playbook-ssl-certificates.md)." msgstr "" -#: ../../../CHANGELOG.md:3936 +#: ../../../CHANGELOG.md:4543 msgid "For people who use Let's Encrypt (mostly everyone, since it's the default), you'll also have to rename a variable in your configuration:" msgstr "" -#: ../../../CHANGELOG.md:3938 +#: ../../../CHANGELOG.md:4545 msgid "before: `host_specific_matrix_ssl_support_email`" msgstr "" -#: ../../../CHANGELOG.md:3939 +#: ../../../CHANGELOG.md:4546 msgid "after: `host_specific_matrix_ssl_lets_encrypt_support_email`" msgstr "" -#: ../../../CHANGELOG.md:3941 +#: ../../../CHANGELOG.md:4548 msgid "(BC Break) mxisd upgrade with multiple base DN support" msgstr "" -#: ../../../CHANGELOG.md:3943 +#: ../../../CHANGELOG.md:4550 msgid "mxisd has bee upgraded to [version 1.2.2](https://github.com/kamax-matrix/mxisd/releases/tag/v1.2.2), which supports [multiple base DNs](https://github.com/kamax-matrix/mxisd/blob/v1.2.2/docs/stores/ldap.md#base)." msgstr "" -#: ../../../CHANGELOG.md:3945 +#: ../../../CHANGELOG.md:4552 msgid "If you were configuring this playbook's `matrix_mxisd_ldap_connection_baseDn` variable until now (a string containing a single base DN), you'll need to change to configuring the `matrix_mxisd_ldap_connection_baseDns` variable (an array containing multiple base DNs)." msgstr "" -#: ../../../CHANGELOG.md:3947 +#: ../../../CHANGELOG.md:4554 msgid "Example change:" msgstr "" -#: ../../../CHANGELOG.md:3949 +#: ../../../CHANGELOG.md:4556 msgid "before: `matrix_mxisd_ldap_connection_baseDn: OU=Users,DC=example,DC=org`" msgstr "" -#: ../../../CHANGELOG.md:3950 +#: ../../../CHANGELOG.md:4557 msgid "after: `matrix_mxisd_ldap_connection_baseDns: ['OU=Users,DC=example,DC=org']`" msgstr "" -#: ../../../CHANGELOG.md:3953 +#: ../../../CHANGELOG.md:4560 msgid "2018-12-21" msgstr "" -#: ../../../CHANGELOG.md:3955 +#: ../../../CHANGELOG.md:4562 msgid "Synapse 0.34.0 and Python 3" msgstr "" -#: ../../../CHANGELOG.md:3957 +#: ../../../CHANGELOG.md:4564 msgid "Synapse has been upgraded to 0.34.0 and now uses Python 3. Based on feedback from others, running Synapse on Python 3 is supposed to decrease memory usage significantly (~2x)." msgstr "" -#: ../../../CHANGELOG.md:3960 +#: ../../../CHANGELOG.md:4567 msgid "2018-12-12" msgstr "" -#: ../../../CHANGELOG.md:3962 +#: ../../../CHANGELOG.md:4569 msgid "Riot homepage customization" msgstr "" -#: ../../../CHANGELOG.md:3964 +#: ../../../CHANGELOG.md:4571 msgid "You can now customize some parts of the Riot homepage (or even completely replace it with your own custom page). See the `matrix_riot_web_homepage_` variables in `roles/custom/matrix-riot-web/defaults/main.yml`." msgstr "" -#: ../../../CHANGELOG.md:3967 +#: ../../../CHANGELOG.md:4574 msgid "2018-12-04" msgstr "" -#: ../../../CHANGELOG.md:3969 +#: ../../../CHANGELOG.md:4576 msgid "mxisd extensibility" msgstr "" -#: ../../../CHANGELOG.md:3971 +#: ../../../CHANGELOG.md:4578 msgid "The [LDAP identity store for mxisd](https://github.com/kamax-matrix/mxisd/blob/master/docs/stores/ldap.md) can now be configured easily using playbook variables (see the `matrix_mxisd_ldap_` variables in `roles/custom/matrix-server/defaults/main.yml`)." msgstr "" -#: ../../../CHANGELOG.md:3974 +#: ../../../CHANGELOG.md:4581 msgid "2018-11-28" msgstr "" -#: ../../../CHANGELOG.md:3976 +#: ../../../CHANGELOG.md:4583 msgid "More scripts" msgstr "" -#: ../../../CHANGELOG.md:3978 +#: ../../../CHANGELOG.md:4585 msgid "matrix-remove-all allows to uninstall everything with a single command" msgstr "" -#: ../../../CHANGELOG.md:3979 +#: ../../../CHANGELOG.md:4586 msgid "matrix-make-user-admin allows to upgrade a user's privileges" msgstr "" -#: ../../../CHANGELOG.md:3981 +#: ../../../CHANGELOG.md:4588 msgid "LDAP auth support via matrix-synapse-ldap3" msgstr "" -#: ../../../CHANGELOG.md:3983 +#: ../../../CHANGELOG.md:4590 msgid "The playbook can now install and configure [LDAP auth support](https://github.com/matrix-org/matrix-synapse-ldap3) for you." msgstr "" -#: ../../../CHANGELOG.md:3985 +#: ../../../CHANGELOG.md:4592 msgid "Additional details are available in [Setting up the LDAP authentication password provider module](docs/configuring-playbook-ldap-auth.md)." msgstr "" -#: ../../../CHANGELOG.md:3988 +#: ../../../CHANGELOG.md:4595 msgid "2018-11-23" msgstr "" -#: ../../../CHANGELOG.md:3990 +#: ../../../CHANGELOG.md:4597 msgid "Support for controlling public registration and room auto-join" msgstr "" -#: ../../../CHANGELOG.md:3992 +#: ../../../CHANGELOG.md:4599 msgid "The playbook now lets you enable public registration for users (controlled via `matrix_synapse_enable_registration`). By default, public registration is forbidden." msgstr "" -#: ../../../CHANGELOG.md:3994 +#: ../../../CHANGELOG.md:4601 msgid "You can also make people automatically get auto-joined to rooms (controlled via `matrix_synapse_auto_join_rooms`)." msgstr "" -#: ../../../CHANGELOG.md:3996 +#: ../../../CHANGELOG.md:4603 msgid "Support for changing the welcome user ID (welcome bot)" msgstr "" -#: ../../../CHANGELOG.md:3998 +#: ../../../CHANGELOG.md:4605 msgid "By default, `@riot-bot:matrix.org` is used to welcome newly registered users. This can be changed to something else (or disabled) via the new `matrix_riot_web_welcome_user_id` variable." msgstr "" -#: ../../../CHANGELOG.md:4001 +#: ../../../CHANGELOG.md:4608 msgid "2018-11-14" msgstr "" -#: ../../../CHANGELOG.md:4003 +#: ../../../CHANGELOG.md:4610 msgid "Ability to set Synapse log levels" msgstr "" -#: ../../../CHANGELOG.md:4005 +#: ../../../CHANGELOG.md:4612 msgid "The playbook now allows you to set the log levels used by Synapse. The default logging levels remain the same." msgstr "" -#: ../../../CHANGELOG.md:4007 +#: ../../../CHANGELOG.md:4614 msgid "You can now override following variables with any of the supported log levels listed here: https://docs.python.org/3/library/logging.html#logging-levels" msgstr "" -#: ../../../CHANGELOG.md:4016 +#: ../../../CHANGELOG.md:4623 msgid "2018-11-03" msgstr "" -#: ../../../CHANGELOG.md:4018 +#: ../../../CHANGELOG.md:4625 msgid "Customize parts of Riot's config" msgstr "" -#: ../../../CHANGELOG.md:4020 +#: ../../../CHANGELOG.md:4627 msgid "You can now customize some parts of Riot's `config.json`. These playbook variables, with these default values, have been added:" msgstr "" -#: ../../../CHANGELOG.md:4031 +#: ../../../CHANGELOG.md:4638 msgid "This now allows you use a custom integration manager like [Dimension](https://dimension.t2bot.io). For example, if you wish to use the Dimension instance hosted at dimension.t2bot.io, you can set the following in your vars.yml file:" msgstr "" -#: ../../../CHANGELOG.md:4040 +#: ../../../CHANGELOG.md:4647 msgid "SSL protocols used to serve Riot and Synapse" msgstr "" -#: ../../../CHANGELOG.md:4042 +#: ../../../CHANGELOG.md:4649 msgid "There's now a new `matrix_nginx_proxy_ssl_protocols` playbook variable, which controls the SSL protocols used to serve Riot and Synapse. Its default value is `TLSv1.1 TLSv1.2`. This playbook previously used `TLSv1 TLSv1.1 TLSv1.2` to serve Riot and Synapse." msgstr "" -#: ../../../CHANGELOG.md:4044 +#: ../../../CHANGELOG.md:4651 msgid "You may wish to re-enable TLSv1 if you need to access Riot in older browsers." msgstr "" -#: ../../../CHANGELOG.md:4046 +#: ../../../CHANGELOG.md:4653 msgid "Note: Currently the dockerized nginx doesn't support TLSv1.3. See https://github.com/nginxinc/docker-nginx/issues/190 for more details." msgstr "" -#: ../../../CHANGELOG.md:4049 +#: ../../../CHANGELOG.md:4656 msgid "2018-11-01" msgstr "" -#: ../../../CHANGELOG.md:4051 +#: ../../../CHANGELOG.md:4658 msgid "Postgres 11 support" msgstr "" -#: ../../../CHANGELOG.md:4053 +#: ../../../CHANGELOG.md:4660 msgid "The playbook now installs [Postgres 11](https://www.postgresql.org/about/news/1894/) by default." msgstr "" -#: ../../../CHANGELOG.md:4055 +#: ../../../CHANGELOG.md:4662 msgid "If you have have an existing setup, it's likely running on an older Postgres version (9.x or 10.x). You can easily upgrade by following the [upgrading PostgreSQL guide](docs/maintenance-postgres.md#upgrading-postgresql)." msgstr "" -#: ../../../CHANGELOG.md:4057 -#: ../../../CHANGELOG.md:4144 -#: ../../../CHANGELOG.md:4264 +#: ../../../CHANGELOG.md:4664 +#: ../../../CHANGELOG.md:4751 +#: ../../../CHANGELOG.md:4871 msgid "(BC Break) Renaming playbook variables" msgstr "" -#: ../../../CHANGELOG.md:4059 +#: ../../../CHANGELOG.md:4666 msgid "Due to the large amount of features added to this playbook lately, to keep things manageable we've had to reorganize its configuration variables a bit." msgstr "" -#: ../../../CHANGELOG.md:4063 +#: ../../../CHANGELOG.md:4670 msgid "from `matrix_docker_image_mxisd` to `matrix_mxisd_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:4064 +#: ../../../CHANGELOG.md:4671 msgid "from `matrix_docker_image_mautrix_telegram` to `matrix_mautrix_telegram_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:4065 +#: ../../../CHANGELOG.md:4672 msgid "from `matrix_docker_image_mautrix_whatsapp` to `matrix_mautrix_whatsapp_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:4066 +#: ../../../CHANGELOG.md:4673 msgid "from `matrix_docker_image_mailer` to `matrix_mailer_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:4067 +#: ../../../CHANGELOG.md:4674 msgid "from `matrix_docker_image_coturn` to `coturn_container_image`" msgstr "" -#: ../../../CHANGELOG.md:4068 +#: ../../../CHANGELOG.md:4675 msgid "from `matrix_docker_image_goofys` to `matrix_s3_goofys_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:4069 +#: ../../../CHANGELOG.md:4676 msgid "from `matrix_docker_image_riot` to `matrix_riot_web_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:4070 +#: ../../../CHANGELOG.md:4677 msgid "from `matrix_docker_image_nginx` to `matrix_nginx_proxy_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:4071 +#: ../../../CHANGELOG.md:4678 msgid "from `matrix_docker_image_synapse` to `matrix_synapse_docker_image`" msgstr "" -#: ../../../CHANGELOG.md:4072 +#: ../../../CHANGELOG.md:4679 msgid "from `matrix_docker_image_postgres_v9` to `matrix_postgres_docker_image_v9`" msgstr "" -#: ../../../CHANGELOG.md:4073 +#: ../../../CHANGELOG.md:4680 msgid "from `matrix_docker_image_postgres_v10` to `matrix_postgres_docker_image_v10`" msgstr "" -#: ../../../CHANGELOG.md:4074 +#: ../../../CHANGELOG.md:4681 msgid "from `matrix_docker_image_postgres_latest` to `matrix_postgres_docker_image_latest`" msgstr "" -#: ../../../CHANGELOG.md:4077 +#: ../../../CHANGELOG.md:4684 msgid "2018-10-26" msgstr "" -#: ../../../CHANGELOG.md:4079 +#: ../../../CHANGELOG.md:4686 msgid "Mautrix Whatsapp bridging support" msgstr "" -#: ../../../CHANGELOG.md:4081 +#: ../../../CHANGELOG.md:4688 msgid "The playbook now supports bridging with [Whatsapp](https://www.whatsapp.com/) by installing the [mautrix-whatsapp](https://github.com/tulir/mautrix-whatsapp) bridge. This playbook functionality is available thanks to [@izissise](https://github.com/izissise)." msgstr "" -#: ../../../CHANGELOG.md:4083 +#: ../../../CHANGELOG.md:4690 msgid "Additional details are available in [Setting up Mautrix Whatsapp bridging](docs/configuring-playbook-bridge-mautrix-whatsapp.md)." msgstr "" -#: ../../../CHANGELOG.md:4086 +#: ../../../CHANGELOG.md:4693 msgid "2018-10-25" msgstr "" -#: ../../../CHANGELOG.md:4088 +#: ../../../CHANGELOG.md:4695 msgid "Support for controlling Matrix federation" msgstr "" -#: ../../../CHANGELOG.md:4090 +#: ../../../CHANGELOG.md:4697 msgid "The playbook can now help you with [Controlling Matrix federation](docs/configuring-playbook-federation), should you wish to run a more private (isolated) server." msgstr "" -#: ../../../CHANGELOG.md:4093 +#: ../../../CHANGELOG.md:4700 msgid "2018-10-24" msgstr "" -#: ../../../CHANGELOG.md:4095 +#: ../../../CHANGELOG.md:4702 msgid "Disabling riot-web guests" msgstr "" -#: ../../../CHANGELOG.md:4097 +#: ../../../CHANGELOG.md:4704 msgid "From now on, Riot's configuration setting `disable_guests` would be set to `true`. The homeserver was rejecting guests anyway, so this is just a cosmetic change affecting Riot's UI." msgstr "" -#: ../../../CHANGELOG.md:4100 +#: ../../../CHANGELOG.md:4707 msgid "2018-10-21" msgstr "" -#: ../../../CHANGELOG.md:4102 +#: ../../../CHANGELOG.md:4709 msgid "Self-check maintenance command" msgstr "" -#: ../../../CHANGELOG.md:4104 +#: ../../../CHANGELOG.md:4711 msgid "The playbook can now [check if services are configured correctly](docs/maintenance-and-troubleshooting.md#how-to-check-if-services-work)." msgstr "" -#: ../../../CHANGELOG.md:4107 +#: ../../../CHANGELOG.md:4714 msgid "2018-10-05" msgstr "" -#: ../../../CHANGELOG.md:4109 +#: ../../../CHANGELOG.md:4716 msgid "Presence tracking made configurable" msgstr "" -#: ../../../CHANGELOG.md:4111 +#: ../../../CHANGELOG.md:4718 msgid "The playbook can now enable/disable user presence-status tracking in Synapse, through the playbook's `matrix_synapse_use_presence` variable (having a default value of `true` — enabled)." msgstr "" -#: ../../../CHANGELOG.md:4113 +#: ../../../CHANGELOG.md:4720 msgid "If users participate in large rooms with many other servers, disabling presence will decrease server load significantly." msgstr "" -#: ../../../CHANGELOG.md:4116 +#: ../../../CHANGELOG.md:4723 msgid "2018-09-27" msgstr "" -#: ../../../CHANGELOG.md:4118 +#: ../../../CHANGELOG.md:4725 msgid "Synapse Cache Factor made configurable" msgstr "" -#: ../../../CHANGELOG.md:4120 +#: ../../../CHANGELOG.md:4727 msgid "The playbook now makes the Synapse cache factor configurable, through the playbook's `matrix_synapse_cache_factor` variable (having a default value of `0.5`)." msgstr "" -#: ../../../CHANGELOG.md:4122 +#: ../../../CHANGELOG.md:4729 msgid "Changing that value allows you to potentially decrease RAM usage or to increase performance by caching more stuff. Some information on it is available here: https://github.com/element-hq/synapse#help-synapse-eats-all-my-ram" msgstr "" -#: ../../../CHANGELOG.md:4125 +#: ../../../CHANGELOG.md:4732 msgid "2018-09-26" msgstr "" -#: ../../../CHANGELOG.md:4127 +#: ../../../CHANGELOG.md:4734 msgid "Disabling Docker container logging" msgstr "" -#: ../../../CHANGELOG.md:4129 +#: ../../../CHANGELOG.md:4736 msgid "`--log-driver=none` is used for all Docker containers now." msgstr "" -#: ../../../CHANGELOG.md:4131 +#: ../../../CHANGELOG.md:4738 msgid "All these containers are started through systemd anyway and get logged in journald, so there's no need for Docker to be logging the same thing using the default `json-file` driver. Doing that was growing `/var/lib/docker/containers/…` infinitely until service/container restart." msgstr "" -#: ../../../CHANGELOG.md:4133 +#: ../../../CHANGELOG.md:4740 msgid "As a result of this, things like `docker logs matrix-synapse` won't work anymore. `journalctl -u matrix-synapse` is how one can see the logs." msgstr "" -#: ../../../CHANGELOG.md:4136 +#: ../../../CHANGELOG.md:4743 msgid "2018-09-17" msgstr "" -#: ../../../CHANGELOG.md:4138 +#: ../../../CHANGELOG.md:4745 msgid "Service discovery support" msgstr "" -#: ../../../CHANGELOG.md:4140 +#: ../../../CHANGELOG.md:4747 msgid "The playbook now helps you set up [service discovery](https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery) using a `/.well-known/matrix/client` file." msgstr "" -#: ../../../CHANGELOG.md:4142 +#: ../../../CHANGELOG.md:4749 msgid "Additional details are available in [Configuring service discovery via .well-known](docs/configuring-well-known.md)." msgstr "" -#: ../../../CHANGELOG.md:4148 +#: ../../../CHANGELOG.md:4755 msgid "from `matrix_nginx_riot_web_data_path` to `matrix_riot_web_data_path`" msgstr "" -#: ../../../CHANGELOG.md:4149 +#: ../../../CHANGELOG.md:4756 msgid "from `matrix_riot_web_default_identity_server_url` to `matrix_identity_server_url`" msgstr "" -#: ../../../CHANGELOG.md:4152 +#: ../../../CHANGELOG.md:4759 msgid "2018-09-07" msgstr "" -#: ../../../CHANGELOG.md:4154 +#: ../../../CHANGELOG.md:4761 msgid "Mautrix Telegram bridging support" msgstr "" -#: ../../../CHANGELOG.md:4156 +#: ../../../CHANGELOG.md:4763 msgid "The playbook now supports bridging with [Telegram](https://telegram.org/) by installing the [mautrix-telegram](https://github.com/tulir/mautrix-telegram) bridge. This playbook functionality is available thanks to [@izissise](https://github.com/izissise)." msgstr "" -#: ../../../CHANGELOG.md:4158 +#: ../../../CHANGELOG.md:4765 msgid "Additional details are available in [Setting up Mautrix Telegram bridging](docs/configuring-playbook-bridge-mautrix-telegram.md)." msgstr "" -#: ../../../CHANGELOG.md:4160 +#: ../../../CHANGELOG.md:4767 msgid "Events cache size increase and configurability for Matrix Synapse" msgstr "" -#: ../../../CHANGELOG.md:4162 +#: ../../../CHANGELOG.md:4769 msgid "The playbook now lets you configure Matrix Synapse's `event_cache_size` configuration via the `matrix_synapse_event_cache_size` playbook variable." msgstr "" -#: ../../../CHANGELOG.md:4164 +#: ../../../CHANGELOG.md:4771 msgid "Previously, this value was hardcoded to `\"10K\"`. From now on, a more reasonable default of `\"100K\"` is used." msgstr "" -#: ../../../CHANGELOG.md:4166 +#: ../../../CHANGELOG.md:4773 msgid "Password-peppering support for Matrix Synapse" msgstr "" -#: ../../../CHANGELOG.md:4168 +#: ../../../CHANGELOG.md:4775 msgid "The playbook now supports enabling password-peppering for increased security in Matrix Synapse via the `matrix_synapse_password_config_pepper` playbook variable. Using a password pepper is disabled by default (just like it used to be before this playbook variable got introduced) and is not to be enabled/disabled after initial setup, as that would invalidate all existing passwords." msgstr "" -#: ../../../CHANGELOG.md:4170 +#: ../../../CHANGELOG.md:4777 msgid "Statistics-reporting support for Matrix Synapse" msgstr "" -#: ../../../CHANGELOG.md:4172 +#: ../../../CHANGELOG.md:4779 msgid "There's now a new `matrix_synapse_report_stats` playbook variable, which controls the `report_stats` configuration option for Matrix Synapse. It defaults to `false`, so no change is required to retain your privacy." msgstr "" -#: ../../../CHANGELOG.md:4174 +#: ../../../CHANGELOG.md:4781 msgid "If you'd like to start reporting statistics about your homeserver (things like number of users, number of messages sent, uptime, load, etc.) to matrix.org, you can turn on stats reporting." msgstr "" -#: ../../../CHANGELOG.md:4177 +#: ../../../CHANGELOG.md:4784 msgid "2018-08-29" msgstr "" -#: ../../../CHANGELOG.md:4179 +#: ../../../CHANGELOG.md:4786 msgid "Changing the way SSL certificates are retrieved" msgstr "" -#: ../../../CHANGELOG.md:4181 +#: ../../../CHANGELOG.md:4788 msgid "We've been using [acmetool](https://github.com/hlandau/acme) (with the [willwill/acme-docker](https://hub.docker.com/r/willwill/acme-docker/) Docker image) until now." msgstr "" -#: ../../../CHANGELOG.md:4183 +#: ../../../CHANGELOG.md:4790 msgid "Due to the Docker image being deprecated, and things looking bleak for acmetool's support of the newer ACME v2 API endpoint, we've switched to using [certbot](https://certbot.eff.org/) (with the [certbot/certbot](https://hub.docker.com/r/certbot/certbot/) Docker image)." msgstr "" -#: ../../../CHANGELOG.md:4185 +#: ../../../CHANGELOG.md:4792 msgid "Simply re-running the playbook will retrieve new certificates (via certbot) for you. To ensure you don't leave any old files behind, though, you'd better do this:" msgstr "" -#: ../../../CHANGELOG.md:4187 +#: ../../../CHANGELOG.md:4794 msgid "`systemctl stop 'matrix*'`" msgstr "" -#: ../../../CHANGELOG.md:4188 +#: ../../../CHANGELOG.md:4795 msgid "stop your custom webserver, if you're running one (only affects you if you've installed with `matrix_nginx_proxy_enabled: false`)" msgstr "" -#: ../../../CHANGELOG.md:4189 +#: ../../../CHANGELOG.md:4796 msgid "`mv /matrix/ssl /matrix/ssl-acmetool-delete-later`" msgstr "" -#: ../../../CHANGELOG.md:4190 +#: ../../../CHANGELOG.md:4797 msgid "re-run the playbook's [installation](docs/installing.md)" msgstr "" -#: ../../../CHANGELOG.md:4191 +#: ../../../CHANGELOG.md:4798 msgid "possibly delete `/matrix/ssl-acmetool-delete-later`" msgstr "" -#: ../../../CHANGELOG.md:4194 +#: ../../../CHANGELOG.md:4801 msgid "2018-08-21" msgstr "" -#: ../../../CHANGELOG.md:4196 +#: ../../../CHANGELOG.md:4803 msgid "Matrix Corporal support" msgstr "" -#: ../../../CHANGELOG.md:4198 +#: ../../../CHANGELOG.md:4805 msgid "The playbook can now install and configure [matrix-corporal](https://github.com/devture/matrix-corporal) for you." msgstr "" -#: ../../../CHANGELOG.md:4200 +#: ../../../CHANGELOG.md:4807 msgid "Additional details are available in [Setting up Matrix Corporal](docs/configuring-playbook-matrix-corporal.md)." msgstr "" -#: ../../../CHANGELOG.md:4203 +#: ../../../CHANGELOG.md:4810 msgid "2018-08-20" msgstr "" -#: ../../../CHANGELOG.md:4205 +#: ../../../CHANGELOG.md:4812 msgid "Matrix Synapse rate limit control variables" msgstr "" -#: ../../../CHANGELOG.md:4207 +#: ../../../CHANGELOG.md:4814 msgid "The following new variables can now be configured to control Matrix Synapse's rate-limiting (default values are shown below)." msgstr "" -#: ../../../CHANGELOG.md:4214 +#: ../../../CHANGELOG.md:4821 msgid "Shared Secret Auth support via matrix-synapse-shared-secret-auth" msgstr "" -#: ../../../CHANGELOG.md:4216 +#: ../../../CHANGELOG.md:4823 msgid "The playbook can now install and configure [matrix-synapse-shared-secret-auth](https://github.com/devture/matrix-synapse-shared-secret-auth) for you." msgstr "" -#: ../../../CHANGELOG.md:4218 +#: ../../../CHANGELOG.md:4825 msgid "Additional details are available in [Setting up the Shared Secret Auth password provider module](docs/configuring-playbook-shared-secret-auth.md)." msgstr "" -#: ../../../CHANGELOG.md:4221 +#: ../../../CHANGELOG.md:4828 msgid "2018-08-17" msgstr "" -#: ../../../CHANGELOG.md:4223 +#: ../../../CHANGELOG.md:4830 msgid "REST auth support via matrix-synapse-rest-auth" msgstr "" -#: ../../../CHANGELOG.md:4225 +#: ../../../CHANGELOG.md:4832 msgid "The playbook can now install and configure [matrix-synapse-rest-auth](https://github.com/kamax-io/matrix-synapse-rest-auth) for you." msgstr "" -#: ../../../CHANGELOG.md:4227 +#: ../../../CHANGELOG.md:4834 msgid "Additional details are available in [Setting up the REST authentication password provider module](docs/configuring-playbook-rest-auth.md)." msgstr "" -#: ../../../CHANGELOG.md:4229 +#: ../../../CHANGELOG.md:4836 msgid "Compression improvements" msgstr "" -#: ../../../CHANGELOG.md:4231 +#: ../../../CHANGELOG.md:4838 msgid "Shifted Matrix Synapse compression from happening in the Matrix Synapse, to happening in the nginx proxy that's in front of it." msgstr "" -#: ../../../CHANGELOG.md:4234 +#: ../../../CHANGELOG.md:4841 msgid "Additionally, `riot-web` also gets compressed now (in the nginx proxy), which drops the initial page load's size from 5.31MB to 1.86MB." msgstr "" -#: ../../../CHANGELOG.md:4237 +#: ../../../CHANGELOG.md:4844 msgid "Disabling some unnecessary Synapse services" msgstr "" -#: ../../../CHANGELOG.md:4239 +#: ../../../CHANGELOG.md:4846 msgid "The following services are not necessary, so they have been disabled:" msgstr "" -#: ../../../CHANGELOG.md:4240 +#: ../../../CHANGELOG.md:4847 msgid "on the federation port (8448): the `client` service" msgstr "" -#: ../../../CHANGELOG.md:4241 +#: ../../../CHANGELOG.md:4848 msgid "on the http port (8008, exposed over 443): the old Angular `webclient` and the `federation` service" msgstr "" -#: ../../../CHANGELOG.md:4243 +#: ../../../CHANGELOG.md:4850 msgid "Federation runs only on the federation port (8448) now. The Client APIs run only on the http port (8008) now." msgstr "" -#: ../../../CHANGELOG.md:4246 +#: ../../../CHANGELOG.md:4853 msgid "2018-08-15" msgstr "" -#: ../../../CHANGELOG.md:4248 +#: ../../../CHANGELOG.md:4855 msgid "mxisd Identity Server support" msgstr "" -#: ../../../CHANGELOG.md:4250 +#: ../../../CHANGELOG.md:4857 msgid "The playbook now sets up an [mxisd](https://github.com/kamax-io/mxisd) Identity Server for you by default. Additional details are available in [Setting up ma1sd Identity Server](docs/configuring-playbook-mxisd.md)." msgstr "" -#: ../../../CHANGELOG.md:4253 +#: ../../../CHANGELOG.md:4860 msgid "2018-08-14" msgstr "" -#: ../../../CHANGELOG.md:4255 +#: ../../../CHANGELOG.md:4862 msgid "Email-sending support" msgstr "" -#: ../../../CHANGELOG.md:4257 +#: ../../../CHANGELOG.md:4864 msgid "The playbook now configures an email-sending service (postfix) by default. Additional details are available in [Adjusting email-sending settings](docs/configuring-playbook-email.md)." msgstr "" -#: ../../../CHANGELOG.md:4259 +#: ../../../CHANGELOG.md:4866 msgid "With this, Matrix Synapse is able to send email notifications for missed messages, etc." msgstr "" -#: ../../../CHANGELOG.md:4262 +#: ../../../CHANGELOG.md:4869 msgid "2018-08-08" msgstr "" -#: ../../../CHANGELOG.md:4268 +#: ../../../CHANGELOG.md:4875 msgid "from `matrix_max_upload_size_mb` to `matrix_synapse_max_upload_size_mb`" msgstr "" -#: ../../../CHANGELOG.md:4269 +#: ../../../CHANGELOG.md:4876 msgid "from `matrix_max_log_file_size_mb` to `matrix_synapse_max_log_file_size_mb`" msgstr "" -#: ../../../CHANGELOG.md:4270 +#: ../../../CHANGELOG.md:4877 msgid "from `matrix_max_log_files_count` to `matrix_synapse_max_log_files_count`" msgstr "" -#: ../../../CHANGELOG.md:4271 +#: ../../../CHANGELOG.md:4878 msgid "from `docker_matrix_image` to `matrix_docker_image_synapse`" msgstr "" -#: ../../../CHANGELOG.md:4272 +#: ../../../CHANGELOG.md:4879 msgid "from `docker_nginx_image` to `matrix_docker_image_nginx`" msgstr "" -#: ../../../CHANGELOG.md:4273 +#: ../../../CHANGELOG.md:4880 msgid "from `docker_riot_image` to `matrix_docker_image_riot`" msgstr "" -#: ../../../CHANGELOG.md:4274 +#: ../../../CHANGELOG.md:4881 msgid "from `docker_goofys_image` to `matrix_docker_image_goofys`" msgstr "" -#: ../../../CHANGELOG.md:4275 +#: ../../../CHANGELOG.md:4882 msgid "from `docker_coturn_image` to `matrix_docker_image_coturn`" msgstr "" -#: ../../../CHANGELOG.md:4277 +#: ../../../CHANGELOG.md:4884 msgid "If you're overriding any of them in your `vars.yml` file, you'd need to change to the new names." msgstr "" -#: ../../../CHANGELOG.md:4279 +#: ../../../CHANGELOG.md:4886 msgid "Renaming Ansible playbook tag" msgstr "" -#: ../../../CHANGELOG.md:4281 +#: ../../../CHANGELOG.md:4888 msgid "The command for executing the whole playbook has changed. The `setup-main` tag got renamed to `setup-all`." msgstr "" -#: ../../../CHANGELOG.md:4283 +#: ../../../CHANGELOG.md:4890 msgid "Docker container linking" msgstr "" -#: ../../../CHANGELOG.md:4285 +#: ../../../CHANGELOG.md:4892 msgid "Changed the way the Docker containers are linked together. The ones that need to communicate with others operate in a `matrix` network now and not in the default bridge network." msgstr "" diff --git a/i18n/translation-templates/README.pot b/i18n/translation-templates/README.pot index f227a234d..28f4ee198 100644 --- a/i18n/translation-templates/README.pot +++ b/i18n/translation-templates/README.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-13 05:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,7 +41,7 @@ msgid "🎯 Purpose" msgstr "" #: ../../../README.md:7 -msgid "This [Ansible](https://www.ansible.com/) playbook is meant to help you run your own [Matrix](http://matrix.org/) homeserver, along with the [various services](#supported-services) related to that." +msgid "This [Ansible](https://www.ansible.com/) playbook is meant to help you run your own [Matrix](http://matrix.org/) homeserver, along with the [various services](#-supported-services) related to that." msgstr "" #: ../../../README.md:9 @@ -188,6 +188,18 @@ msgstr "" msgid "[Link](docs/configuring-playbook-continuwuity.md)" msgstr "" +#: ../../../README.md:0 +msgid "[Tuwunel](https://matrix-construct.github.io/tuwunel/)" +msgstr "" + +#: ../../../README.md:0 +msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Tuwunel is the official successor to conduwuit." +msgstr "" + +#: ../../../README.md:0 +msgid "[Link](docs/configuring-playbook-tuwunel.md)" +msgstr "" + #: ../../../README.md:0 msgid "[Dendrite](https://github.com/element-hq/dendrite)" msgstr "" @@ -200,11 +212,11 @@ msgstr "" msgid "[Link](docs/configuring-playbook-dendrite.md)" msgstr "" -#: ../../../README.md:58 +#: ../../../README.md:59 msgid "Clients" msgstr "" -#: ../../../README.md:60 +#: ../../../README.md:61 msgid "Web clients for Matrix that you can host on your own domains." msgstr "" @@ -244,6 +256,14 @@ msgstr "" msgid "[Link](docs/configuring-playbook-client-cinny.md)" msgstr "" +#: ../../../README.md:0 +msgid "[Sable](https://github.com/SableClient/Sable)" +msgstr "" + +#: ../../../README.md:0 +msgid "[Link](docs/configuring-playbook-client-sable.md)" +msgstr "" + #: ../../../README.md:0 msgid "[SchildiChat Web](https://schildi.chat/)" msgstr "" @@ -268,36 +288,36 @@ msgstr "" msgid "[Link](docs/configuring-playbook-client-fluffychat-web.md)" msgstr "" -#: ../../../README.md:70 -msgid "Server Components" +#: ../../../README.md:0 +msgid "[Commet](https://github.com/commetchat/commet)" msgstr "" -#: ../../../README.md:72 -msgid "Services that run on the server to make the various parts of your installation work." +#: ../../../README.md:0 +msgid "Matrix web client" msgstr "" #: ../../../README.md:0 -msgid "[PostgreSQL](https://www.postgresql.org/)" +msgid "[Link](docs/configuring-playbook-client-commet.md)" msgstr "" -#: ../../../README.md:0 -msgid "Database for Synapse. [Using an external PostgreSQL server](docs/configuring-playbook-external-postgres.md) is also possible." +#: ../../../README.md:73 +msgid "Server Components" msgstr "" -#: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-external-postgres.md)" +#: ../../../README.md:75 +msgid "Services that run on the server to make the various parts of your installation work." msgstr "" #: ../../../README.md:0 -msgid "[coturn](https://github.com/coturn/coturn)" +msgid "[PostgreSQL](https://www.postgresql.org/)" msgstr "" #: ../../../README.md:0 -msgid "STUN/TURN server for WebRTC audio/video calls" +msgid "Database for Synapse. [Using an external PostgreSQL server](docs/configuring-playbook-external-postgres.md) is also possible." msgstr "" #: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-turn.md)" +msgid "[Link](docs/configuring-playbook-external-postgres.md)" msgstr "" #: ../../../README.md:0 @@ -337,46 +357,46 @@ msgid "[Link](docs/configuring-playbook-email.md)" msgstr "" #: ../../../README.md:0 -msgid "[ddclient](https://github.com/linuxserver/docker-ddclient)" +msgid "[coturn](https://github.com/coturn/coturn)" msgstr "" #: ../../../README.md:0 -msgid "Dynamic DNS" +msgid "STUN/TURN server for WebRTC audio/video calls" msgstr "" #: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-dynamic-dns.md)" +msgid "[Link](docs/configuring-playbook-turn.md)" msgstr "" #: ../../../README.md:0 -msgid "[LiveKit Server](https://github.com/livekit/livekit)" +msgid "[ddclient](https://github.com/linuxserver/docker-ddclient)" msgstr "" #: ../../../README.md:0 -msgid "WebRTC server for audio/video calls" +msgid "Dynamic DNS" msgstr "" #: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-livekit-server.md)" +msgid "[Link](docs/configuring-playbook-dynamic-dns.md)" msgstr "" #: ../../../README.md:0 -msgid "[Livekit JWT Service](https://github.com/livekit/livekit-jwt-service)" +msgid "Matrix RTC stack" msgstr "" #: ../../../README.md:0 -msgid "JWT service for integrating [Element Call](./configuring-playbook-element-call.md) with [LiveKit Server](./configuring-playbook-livekit-server.md)" +msgid "Supporting components ([LiveKit Server](docs/configuring-playbook-livekit-server.md) and [LiveKit JWT Service](docs/configuring-playbook-livekit-jwt-service.md)) for in-app audio/video calls for Matrix clients" msgstr "" #: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-livekit-jwt-service.md)" +msgid "[Link](docs/configuring-playbook-matrix-rtc.md)" msgstr "" -#: ../../../README.md:85 +#: ../../../README.md:87 msgid "Authentication" msgstr "" -#: ../../../README.md:87 +#: ../../../README.md:89 msgid "Extend and modify how users are authenticated on your homeserver." msgstr "" @@ -416,30 +436,6 @@ msgstr "" msgid "[Link](docs/configuring-playbook-ldap-auth.md)" msgstr "" -#: ../../../README.md:0 -msgid "[matrix-ldap-registration-proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy) (advanced)" -msgstr "" - -#: ../../../README.md:0 -msgid "Proxy that handles Matrix registration requests and forwards them to LDAP" -msgstr "" - -#: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-matrix-ldap-registration-proxy.md)" -msgstr "" - -#: ../../../README.md:0 -msgid "[matrix-registration](https://github.com/ZerataX/matrix-registration)" -msgstr "" - -#: ../../../README.md:0 -msgid "Simple python application to have a token based Matrix registration" -msgstr "" - -#: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-matrix-registration.md)" -msgstr "" - #: ../../../README.md:0 msgid "[Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service)" msgstr "" @@ -560,6 +556,30 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bridge-mautrix-gmessages.md)" msgstr "" +#: ../../../README.md:0 +msgid "[mautrix-gvoice](https://github.com/mautrix/gvoice)" +msgstr "" + +#: ../../../README.md:0 +msgid "Bridge to [Google Voice](https://voice.google.com/)" +msgstr "" + +#: ../../../README.md:0 +msgid "[Link](docs/configuring-playbook-bridge-mautrix-gvoice.md)" +msgstr "" + +#: ../../../README.md:0 +msgid "[mautrix-linkedin](https://github.com/mautrix/linkedin)" +msgstr "" + +#: ../../../README.md:0 +msgid "Bridge to [LinkedIn](https://www.linkedin.com/)" +msgstr "" + +#: ../../../README.md:0 +msgid "[Link](docs/configuring-playbook-bridge-mautrix-linkedin.md)" +msgstr "" + #: ../../../README.md:0 msgid "[mautrix-whatsapp](https://github.com/mautrix/whatsapp)" msgstr "" @@ -584,6 +604,18 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bridge-mautrix-wsproxy.md)" msgstr "" +#: ../../../README.md:0 +msgid "[matrix-rustpush-bridge](https://github.com/jasonlaguidice/imessage)" +msgstr "" + +#: ../../../README.md:0 +msgid "Bridge to [iMessage](https://support.apple.com/messages) via Apple Push Notification service" +msgstr "" + +#: ../../../README.md:0 +msgid "[Link](docs/configuring-playbook-bridge-rustpush.md)" +msgstr "" + #: ../../../README.md:0 msgid "[mautrix-bluesky](https://github.com/mautrix/bluesky)" msgstr "" @@ -621,7 +653,7 @@ msgid "[Link](docs/configuring-playbook-bridge-mautrix-googlechat.md)" msgstr "" #: ../../../README.md:0 -msgid "[mautrix-meta](https://github.com/mautrix/instagram)" +msgid "[mautrix-meta](https://github.com/mautrix/meta)" msgstr "" #: ../../../README.md:0 @@ -645,15 +677,15 @@ msgid "[Link](docs/configuring-playbook-bridge-mautrix-signal.md)" msgstr "" #: ../../../README.md:0 -msgid "[beeper-linkedin](https://github.com/beeper/linkedin)" +msgid "[beeper-line](https://github.com/beeper/line)" msgstr "" #: ../../../README.md:0 -msgid "Bridge to [LinkedIn](https://www.linkedin.com/)" +msgid "Bridge to [LINE](https://line.me/)" msgstr "" #: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-bridge-beeper-linkedin.md)" +msgid "[Link](docs/configuring-playbook-bridge-beeper-line.md)" msgstr "" #: ../../../README.md:0 @@ -668,18 +700,6 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bridge-appservice-irc.md)" msgstr "" -#: ../../../README.md:0 -msgid "[matrix-appservice-kakaotalk](https://src.miscworks.net/fair/matrix-appservice-kakaotalk)" -msgstr "" - -#: ../../../README.md:0 -msgid "Bridge to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG)" -msgstr "" - -#: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-bridge-appservice-kakaotalk.md)" -msgstr "" - #: ../../../README.md:0 msgid "[matrix-appservice-discord](https://github.com/matrix-org/matrix-appservice-discord)" msgstr "" @@ -692,14 +712,6 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bridge-appservice-discord.md)" msgstr "" -#: ../../../README.md:0 -msgid "[matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack)" -msgstr "" - -#: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-bridge-appservice-slack.md)" -msgstr "" - #: ../../../README.md:0 msgid "[matrix-hookshot](https://github.com/matrix-org/matrix-hookshot)" msgstr "" @@ -760,6 +772,18 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bridge-heisenbridge.md)" msgstr "" +#: ../../../README.md:0 +msgid "[meshtastic-matrix-relay](https://github.com/jeremiah-k/meshtastic-matrix-relay)" +msgstr "" + +#: ../../../README.md:0 +msgid "Bridge to [Meshtastic](https://meshtastic.org/) mesh networks" +msgstr "" + +#: ../../../README.md:0 +msgid "[Link](docs/configuring-playbook-bridge-meshtastic-relay.md)" +msgstr "" + #: ../../../README.md:0 msgid "[mx-puppet-groupme](https://gitlab.com/xangelix-pub/matrix/mx-puppet-groupme)" msgstr "" @@ -796,11 +820,11 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bridge-postmoogle.md)" msgstr "" -#: ../../../README.md:140 +#: ../../../README.md:142 msgid "Bots" msgstr "" -#: ../../../README.md:142 +#: ../../../README.md:144 msgid "Bots provide various additional functionality to your installation." msgstr "" @@ -828,18 +852,6 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bot-matrix-reminder-bot.md)" msgstr "" -#: ../../../README.md:0 -msgid "[matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot)" -msgstr "" - -#: ../../../README.md:0 -msgid "Bot for invitations by creating and managing registration tokens" -msgstr "" - -#: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-bot-matrix-registration-bot.md)" -msgstr "" - #: ../../../README.md:0 msgid "[maubot](https://github.com/maubot/maubot)" msgstr "" @@ -888,6 +900,18 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bot-draupnir.md) (for [appservice mode](docs/configuring-playbook-appservice-draupnir-for-all.md))" msgstr "" +#: ../../../README.md:0 +msgid "[Meowlnir](https://github.com/maunium/meowlnir)" +msgstr "" + +#: ../../../README.md:0 +msgid "Moderation tool for Matrix, running in appservice mode" +msgstr "" + +#: ../../../README.md:0 +msgid "[Link](docs/configuring-playbook-bot-meowlnir.md)" +msgstr "" + #: ../../../README.md:0 msgid "[Buscarron](https://github.com/etkecc/buscarron)" msgstr "" @@ -900,11 +924,11 @@ msgstr "" msgid "[Link](docs/configuring-playbook-bot-buscarron.md)" msgstr "" -#: ../../../README.md:155 +#: ../../../README.md:157 msgid "Administration" msgstr "" -#: ../../../README.md:157 +#: ../../../README.md:159 msgid "Services that help you in administrating and monitoring your Matrix installation." msgstr "" @@ -933,15 +957,15 @@ msgid "[Link](docs/configuring-playbook-matrix-authentication-service.md)" msgstr "" #: ../../../README.md:0 -msgid "[synapse-admin](https://github.com/etkecc/synapse-admin)" +msgid "[Ketesa](https://github.com/etkecc/ketesa)" msgstr "" #: ../../../README.md:0 -msgid "Web UI tool for administrating users and rooms on your Matrix server" +msgid "Fully-featured web UI for administrating your Matrix homeserver — users, rooms, media, sessions, and more" msgstr "" #: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-synapse-admin.md)" +msgid "[Link](docs/configuring-playbook-ketesa.md)" msgstr "" #: ../../../README.md:0 @@ -992,26 +1016,14 @@ msgstr "" msgid "[Link](docs/configuring-playbook-synapse-usage-exporter.md)" msgstr "" -#: ../../../README.md:169 +#: ../../../README.md:171 msgid "Misc" msgstr "" -#: ../../../README.md:171 +#: ../../../README.md:173 msgid "Various services that don't fit any other categories." msgstr "" -#: ../../../README.md:0 -msgid "[synapse_auto_accept_invite](https://github.com/matrix-org/synapse-auto-accept-invite)" -msgstr "" - -#: ../../../README.md:0 -msgid "Synapse module to automatically accept invites" -msgstr "" - -#: ../../../README.md:0 -msgid "[Link](docs/configuring-playbook-synapse-auto-accept-invite.md)" -msgstr "" - #: ../../../README.md:0 msgid "[synapse_auto_compressor](https://github.com/matrix-org/rust-synapse-compress-state/#automated-tool-synapse_auto_compressor)" msgstr "" @@ -1132,54 +1144,54 @@ msgstr "" msgid "[Link](docs/configuring-playbook-element-call.md)" msgstr "" -#: ../../../README.md:187 +#: ../../../README.md:188 msgid "🆕 Changes" msgstr "" -#: ../../../README.md:189 +#: ../../../README.md:190 msgid "This playbook evolves over time, sometimes with backward-incompatible changes." msgstr "" -#: ../../../README.md:191 +#: ../../../README.md:192 msgid "When updating the playbook, refer to [the changelog](CHANGELOG.md) to catch up with what's new." msgstr "" -#: ../../../README.md:193 +#: ../../../README.md:194 msgid "🆘 Support" msgstr "" -#: ../../../README.md:195 +#: ../../../README.md:196 msgid "Matrix room: [#matrix-docker-ansible-deploy:devture.com](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com)" msgstr "" -#: ../../../README.md:197 +#: ../../../README.md:198 msgid "IRC channel: `#matrix-docker-ansible-deploy` on the [Libera Chat](https://libera.chat/) IRC network (irc.libera.chat:6697)" msgstr "" -#: ../../../README.md:199 +#: ../../../README.md:200 msgid "GitHub issues: [spantaleev/matrix-docker-ansible-deploy/issues](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues)" msgstr "" -#: ../../../README.md:201 +#: ../../../README.md:202 msgid "🌐 Translation" msgstr "" -#: ../../../README.md:203 +#: ../../../README.md:204 msgid "See the [i18n/README.md](i18n/README.md) file for more information about translation." msgstr "" -#: ../../../README.md:205 +#: ../../../README.md:206 msgid "Translations are still work in progress." msgstr "" -#: ../../../README.md:207 +#: ../../../README.md:208 msgid "🤝 Related" msgstr "" -#: ../../../README.md:209 +#: ../../../README.md:210 msgid "You may also be interested in [mash-playbook](https://github.com/mother-of-all-self-hosting/mash-playbook) - another Ansible playbook for self-hosting non-Matrix services (see its [List of supported services](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md))." msgstr "" -#: ../../../README.md:211 +#: ../../../README.md:212 msgid "mash-playbook also makes use of [Traefik](./docs/configuring-playbook-traefik.md) as its reverse-proxy, so with minor [interoperability adjustments](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/interoperability.md), you can make matrix-docker-ansible-deploy and mash-playbook co-exist and host Matrix and non-Matrix services on the same server." msgstr "" diff --git a/i18n/translation-templates/docs/README.pot b/i18n/translation-templates/docs/README.pot index b48138be7..1c5415f71 100644 --- a/i18n/translation-templates/docs/README.pot +++ b/i18n/translation-templates/docs/README.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-18 04:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -133,37 +133,45 @@ msgid "[Alternative architectures](alternative-architectures.md)" msgstr "" #: ../../../docs/README.md:79 -msgid "[Container images used by the playbook](container-images.md)" +msgid "[Configuring Synology DSM](configuring-playbook-synology.md)" msgstr "" #: ../../../docs/README.md:81 -msgid "[Obtaining an Access Token](obtaining-access-tokens.md)" +msgid "[Container images used by the playbook](container-images.md)" msgstr "" #: ../../../docs/README.md:83 -msgid "[Playbook tags](playbook-tags.md)" +msgid "[Obtaining an Access Token](obtaining-access-tokens.md)" msgstr "" #: ../../../docs/README.md:85 -msgid "[Registering users](registering-users.md)" +msgid "[Playbook tags](playbook-tags.md)" msgstr "" #: ../../../docs/README.md:87 -msgid "[Running `just` commands](just.md)" +msgid "[Registering users](registering-users.md)" msgstr "" #: ../../../docs/README.md:89 -msgid "[Self-building](self-building.md)" +msgid "[Running `just` commands](just.md)" msgstr "" #: ../../../docs/README.md:91 -msgid "[Uninstalling](uninstalling.md)" +msgid "[Self-building](self-building.md)" msgstr "" #: ../../../docs/README.md:93 -msgid "[Updating users passwords](updating-users-passwords.md)" +msgid "[Style guide for playbook developers](style-guide.md)" msgstr "" #: ../../../docs/README.md:95 +msgid "[Uninstalling](uninstalling.md)" +msgstr "" + +#: ../../../docs/README.md:97 +msgid "[Updating users passwords](updating-users-passwords.md)" +msgstr "" + +#: ../../../docs/README.md:99 msgid "[Using Ansible for the playbook](ansible.md)" msgstr "" diff --git a/i18n/translation-templates/docs/ansible.pot b/i18n/translation-templates/docs/ansible.pot index 95709ee3e..90bb05940 100644 --- a/i18n/translation-templates/docs/ansible.pot +++ b/i18n/translation-templates/docs/ansible.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-01 17:14+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -48,8 +48,8 @@ msgstr "" msgid "If your distro ships with an Ansible version older than this, you may run into issues. Consider [Upgrading Ansible](#upgrading-ansible) or [using Ansible via Docker](#using-ansible-via-docker)." msgstr "" -#: ../../../docs/ansible.md:27 -msgid "[!WARNING] One reason for the version requirement being as such is that the playbook by default installs Docker for you using [this Docker role](https://github.com/geerlingguy/ansible-role-docker) which [has a hard requirement on Ansible v2.15.1](https://github.com/geerlingguy/ansible-role-docker/commit/7f44a1d9ad8132819ea9852918bca5dab8757cd0). If you install Docker yourself another way, you can tell the playbook to skip running this role (by adding `matrix_playbook_docker_installation_enabled: false` to your `vars.yml` configuration). It may then be possible to get the playbook running on an older version of Ansible. Still, this is a complication and your mileage may vary. We recommend [upgrading Ansible](#upgrading-ansible) instead of going into uncharted territory." +#: ../../../docs/ansible.md:28 +msgid "One reason for the version requirement being as such is that the playbook by default installs Docker for you using [this Docker role](https://github.com/geerlingguy/ansible-role-docker) which [has a hard requirement on Ansible v2.15.1](https://github.com/geerlingguy/ansible-role-docker/commit/7f44a1d9ad8132819ea9852918bca5dab8757cd0). If you install Docker yourself another way, you can tell the playbook to skip running this role (by adding `matrix_playbook_docker_installation_enabled: false` to your `vars.yml` configuration). It may then be possible to get the playbook running on an older version of Ansible. Still, this is a complication and your mileage may vary. We recommend [upgrading Ansible](#upgrading-ansible) instead of going into uncharted territory." msgstr "" #: ../../../docs/ansible.md:30 @@ -77,116 +77,144 @@ msgid "**Note**: Both of the above methods are a bad way to run system software msgstr "" #: ../../../docs/ansible.md:42 -msgid "Using Ansible via Docker" +msgid "SSH host key and passphrase prompts" msgstr "" #: ../../../docs/ansible.md:44 -msgid "Alternatively, you can run Ansible inside a Docker container (powered by the [ghcr.io/devture/ansible](https://github.com/devture/docker-ansible/pkgs/container/ansible) Docker image)." +msgid "If Ansible fails with `Host key verification failed` (or a similar `Data could not be sent to remote host` error) without asking you to confirm the SSH host key of your server, you're likely on Ansible 2.21 or later." msgstr "" #: ../../../docs/ansible.md:46 -msgid "This ensures that:" +msgid "Since Ansible 2.21, forked workers call `setsid()` and thus lose the controlling terminal. SSH cannot open `/dev/tty` anymore, so it can no longer ask you to confirm an unknown host key or prompt you for the passphrase of an SSH key." msgstr "" #: ../../../docs/ansible.md:48 +msgid "The simplest fix is to connect to the server once (e.g. `ssh root@matrix.example.com`) and confirm the host key. Ansible runs after that will find it in your `known_hosts` file." +msgstr "" + +#: ../../../docs/ansible.md:50 +msgid "Alternatively, run Ansible with the `ANSIBLE_WORKER_SESSION_ISOLATION=False` environment variable to get these prompts back (e.g. `ANSIBLE_WORKER_SESSION_ISOLATION=False just install-all`)." +msgstr "" + +#: ../../../docs/ansible.md:52 +msgid "**Note**: this does not affect you if you're [using Ansible via Docker](#using-ansible-via-docker), because our Docker image already disables session isolation for you." +msgstr "" + +#: ../../../docs/ansible.md:54 +msgid "Using Ansible via Docker" +msgstr "" + +#: ../../../docs/ansible.md:56 +msgid "Alternatively, you can run Ansible inside a Docker container (powered by the [ghcr.io/devture/ansible](https://github.com/devture/docker-ansible/pkgs/container/ansible) Docker image)." +msgstr "" + +#: ../../../docs/ansible.md:58 +msgid "This ensures that:" +msgstr "" + +#: ../../../docs/ansible.md:60 msgid "you're using a very recent Ansible version, which is less likely to be incompatible with the playbook" msgstr "" -#: ../../../docs/ansible.md:49 +#: ../../../docs/ansible.md:61 msgid "you also get access to the [agru](https://github.com/etkecc/agru) tool for quicker Ansible role installation (when running `just roles`) compared to `ansible-galaxy`" msgstr "" -#: ../../../docs/ansible.md:51 +#: ../../../docs/ansible.md:63 msgid "You can either [run Ansible in a container on the Matrix server itself](#running-ansible-in-a-container-on-the-matrix-server-itself) or [run Ansible in a container on another computer (not the Matrix server)](#running-ansible-in-a-container-on-another-computer-not-the-matrix-server)." msgstr "" -#: ../../../docs/ansible.md:53 +#: ../../../docs/ansible.md:65 +msgid "💡 If you use [Visual Studio Code](https://code.visualstudio.com/) or [GitHub Codespaces](https://github.com/features/codespaces), the playbook also ships a [dev container](https://containers.dev/) configuration (see the `.devcontainer/` directory) based on this same Ansible Docker image, which can prepare such a containerized Ansible environment for you automatically." +msgstr "" + +#: ../../../docs/ansible.md:67 msgid "Running Ansible in a container on the Matrix server itself" msgstr "" -#: ../../../docs/ansible.md:55 +#: ../../../docs/ansible.md:69 msgid "To run Ansible in a (Docker) container on the Matrix server itself, you need to have a working Docker installation. Docker is normally installed by the playbook, so this may be a bit of a chicken and egg problem. To solve it:" msgstr "" -#: ../../../docs/ansible.md:57 +#: ../../../docs/ansible.md:71 msgid "you **either** need to install Docker manually first. Follow [the upstream instructions](https://docs.docker.com/engine/install/) for your distribution and consider setting `matrix_playbook_docker_installation_enabled: false` in your `vars.yml` file, to prevent the playbook from installing Docker" msgstr "" -#: ../../../docs/ansible.md:58 +#: ../../../docs/ansible.md:72 msgid "**or** you need to run the playbook in another way (e.g. [Running Ansible in a container on another computer (not the Matrix server)](#running-ansible-in-a-container-on-another-computer-not-the-matrix-server)) at least the first time around" msgstr "" -#: ../../../docs/ansible.md:60 +#: ../../../docs/ansible.md:74 msgid "Once you have a working Docker installation on the server, **clone the playbook** somewhere on the server and configure it as per usual (`inventory/hosts`, `inventory/host_vars/…`, etc.), as described in [configuring the playbook](configuring-playbook.md)." msgstr "" -#: ../../../docs/ansible.md:62 +#: ../../../docs/ansible.md:76 msgid "You would then need to add `ansible_connection=community.docker.nsenter` to the host line in `inventory/hosts`. This tells Ansible to connect to the \"remote\" machine by switching Linux namespaces with [nsenter](https://man7.org/linux/man-pages/man1/nsenter.1.html), instead of using SSH." msgstr "" -#: ../../../docs/ansible.md:64 +#: ../../../docs/ansible.md:78 msgid "Alternatively, you can leave your `inventory/hosts` as is and specify the connection type in **each** `ansible-playbook` call you do later, like this: `just install-all --connection=community.docker.nsenter` (or `ansible-playbook --connection=community.docker.nsenter …`)." msgstr "" -#: ../../../docs/ansible.md:66 -#: ../../../docs/ansible.md:88 +#: ../../../docs/ansible.md:80 +#: ../../../docs/ansible.md:102 msgid "Run this from the playbook's directory:" msgstr "" -#: ../../../docs/ansible.md:80 -#: ../../../docs/ansible.md:103 +#: ../../../docs/ansible.md:94 +#: ../../../docs/ansible.md:117 msgid "Once you execute the above command, you'll be dropped into a `/work` directory inside a Docker container. The `/work` directory contains the playbook's code." msgstr "" -#: ../../../docs/ansible.md:82 -#: ../../../docs/ansible.md:105 +#: ../../../docs/ansible.md:96 +#: ../../../docs/ansible.md:119 msgid "First, consider running `git config --global --add safe.directory /work` to [resolve directory ownership issues](#resolve-directory-ownership-issues)." msgstr "" -#: ../../../docs/ansible.md:84 +#: ../../../docs/ansible.md:98 msgid "Finally, you can execute `just` or `ansible-playbook …` (e.g. `ansible-playbook --connection=community.docker.nsenter …`) commands as per normal now." msgstr "" -#: ../../../docs/ansible.md:86 +#: ../../../docs/ansible.md:100 msgid "Running Ansible in a container on another computer (not the Matrix server)" msgstr "" -#: ../../../docs/ansible.md:101 +#: ../../../docs/ansible.md:115 msgid "The above command tries to mount an SSH key (`$HOME/.ssh/id_ed25519`) into the container (at `/root/.ssh/id_ed25519`). If your SSH key is at a different path (not in `$HOME/.ssh/id_ed25519`), adjust that part." msgstr "" -#: ../../../docs/ansible.md:107 +#: ../../../docs/ansible.md:121 msgid "Finally, you execute `just` or `ansible-playbook …` commands as per normal now." msgstr "" -#: ../../../docs/ansible.md:109 +#: ../../../docs/ansible.md:123 msgid "If you don't use SSH keys for authentication" msgstr "" -#: ../../../docs/ansible.md:111 +#: ../../../docs/ansible.md:125 msgid "If you don't use SSH keys for authentication, simply remove that whole line (`--mount type=bind,src$HOME/.ssh/id_ed25519,dst=/root/.ssh/id_ed25519,ro`)." msgstr "" -#: ../../../docs/ansible.md:113 +#: ../../../docs/ansible.md:127 msgid "To authenticate at your server using a password, you need to add a package. So, when you are in the shell of the ansible docker container (the previously used `docker run -it …` command), run:" msgstr "" -#: ../../../docs/ansible.md:119 +#: ../../../docs/ansible.md:133 msgid "Then, to be asked for the password whenever running an `ansible-playbook` command add `--ask-pass` to the arguments of the command." msgstr "" -#: ../../../docs/ansible.md:121 +#: ../../../docs/ansible.md:135 msgid "Resolve directory ownership issues" msgstr "" -#: ../../../docs/ansible.md:123 +#: ../../../docs/ansible.md:137 msgid "Because you're `root` in the container running Ansible and this likely differs from the owner (your regular user account) of the playbook directory outside of the container, certain playbook features which use `git` locally may report warnings such as:" msgstr "" -#: ../../../docs/ansible.md:125 +#: ../../../docs/ansible.md:139 msgid "fatal: unsafe repository ('/work' is owned by someone else) To add an exception for this directory, call: git config --global --add safe.directory /work" msgstr "" -#: ../../../docs/ansible.md:129 +#: ../../../docs/ansible.md:143 msgid "These errors can be resolved by making `git` trust the playbook directory by running `git config --global --add safe.directory /work`" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-captcha.pot b/i18n/translation-templates/docs/configuring-captcha.pot index c9eb868f4..74cae6b2e 100644 --- a/i18n/translation-templates/docs/configuring-captcha.pot +++ b/i18n/translation-templates/docs/configuring-captcha.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -33,43 +33,59 @@ msgid "The captcha mechanism used is Google's [ReCaptcha](https://www.google.com msgstr "" #: ../../../docs/configuring-captcha.md:18 -msgid "ReCaptcha" +msgid "If you are using [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md), captcha is configured there instead (it handles registration), and [Cloudflare Turnstile](https://www.cloudflare.com/application-services/products/turnstile/) is supported as well. See [Matrix Authentication Service](#matrix-authentication-service) below." msgstr "" #: ../../../docs/configuring-captcha.md:20 -#: ../../../docs/configuring-captcha.md:46 -msgid "Getting keys" +msgid "ReCaptcha" msgstr "" #: ../../../docs/configuring-captcha.md:22 #: ../../../docs/configuring-captcha.md:48 -msgid "Requires a site/secret key pair from:" +msgid "Getting keys" msgstr "" #: ../../../docs/configuring-captcha.md:24 -msgid "" +#: ../../../docs/configuring-captcha.md:50 +msgid "Requires a site/secret key pair from:" msgstr "" #: ../../../docs/configuring-captcha.md:26 -msgid "Must be a reCAPTCHA **v2** key using the \"I'm not a robot\" Checkbox option" +msgid "" msgstr "" #: ../../../docs/configuring-captcha.md:28 -msgid "Setting ReCaptcha keys" +msgid "Must be a reCAPTCHA **v2** key using the \"I'm not a robot\" Checkbox option" msgstr "" #: ../../../docs/configuring-captcha.md:30 +msgid "Setting ReCaptcha keys" +msgstr "" + +#: ../../../docs/configuring-captcha.md:32 msgid "Once registered as above, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-captcha.md:44 +#: ../../../docs/configuring-captcha.md:46 msgid "hCaptcha" msgstr "" -#: ../../../docs/configuring-captcha.md:50 +#: ../../../docs/configuring-captcha.md:52 msgid "" msgstr "" -#: ../../../docs/configuring-captcha.md:52 +#: ../../../docs/configuring-captcha.md:54 msgid "Setting hCaptcha keys" msgstr "" + +#: ../../../docs/configuring-captcha.md:67 +msgid "Matrix Authentication Service" +msgstr "" + +#: ../../../docs/configuring-captcha.md:69 +msgid "When [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) is enabled, registration and other account operations are handled by it, so captcha protection is configured there (the Synapse and Dendrite settings above do not apply)." +msgstr "" + +#: ../../../docs/configuring-captcha.md:71 +msgid "Matrix Authentication Service supports [ReCaptcha v2](http://www.google.com/recaptcha/admin), [Cloudflare Turnstile](https://www.cloudflare.com/application-services/products/turnstile/) and [hCaptcha](https://dashboard.hcaptcha.com/sites/new). Obtain a site/secret key pair from your chosen service, then add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-ipv6.pot b/i18n/translation-templates/docs/configuring-ipv6.pot index 737fe341c..e45f9bebd 100644 --- a/i18n/translation-templates/docs/configuring-ipv6.pot +++ b/i18n/translation-templates/docs/configuring-ipv6.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -96,8 +96,8 @@ msgstr "" msgid "traffic destined for the IPv6 address of the server will be forwarded to the containers that handle (and publish) that specific port" msgstr "" -#: ../../../docs/configuring-ipv6.md:59 -msgid "[!WARNING] Without enabling this and assuming you have IPv6 `AAAA` DNS records pointing to the server (see [Configuring DNS records for IPv6](#configuring-dns-records-for-ipv6)), IPv6 traffic will still be handled, but NAT64 will be used instead of NAT66. As such, containers will only have an IPv4 address and all IPv6 traffic that reaches them will seem to originate from a local IP. Containers also won't be able to make outgoing (even cross-container) IPv6 requests." +#: ../../../docs/configuring-ipv6.md:60 +msgid "Without enabling this and assuming you have IPv6 `AAAA` DNS records pointing to the server (see [Configuring DNS records for IPv6](#configuring-dns-records-for-ipv6)), IPv6 traffic will still be handled, but NAT64 will be used instead of NAT66. As such, containers will only have an IPv4 address and all IPv6 traffic that reaches them will seem to originate from a local IP. Containers also won't be able to make outgoing (even cross-container) IPv6 requests." msgstr "" #: ../../../docs/configuring-ipv6.md:63 diff --git a/i18n/translation-templates/docs/configuring-playbook-alertmanager-receiver.pot b/i18n/translation-templates/docs/configuring-playbook-alertmanager-receiver.pot index 21aea6890..a006a3f39 100644 --- a/i18n/translation-templates/docs/configuring-playbook-alertmanager-receiver.pot +++ b/i18n/translation-templates/docs/configuring-playbook-alertmanager-receiver.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -64,8 +64,8 @@ msgstr "" msgid "The bot requires an access token to be able to connect to your homeserver. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." msgstr "" -#: ../../../docs/configuring-playbook-alertmanager-receiver.md:37 -msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." +#: ../../../docs/configuring-playbook-alertmanager-receiver.md:38 +msgid "Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" #: ../../../docs/configuring-playbook-alertmanager-receiver.md:40 diff --git a/i18n/translation-templates/docs/configuring-playbook-appservice-draupnir-for-all.pot b/i18n/translation-templates/docs/configuring-playbook-appservice-draupnir-for-all.pot index e10976945..e740dc2cb 100644 --- a/i18n/translation-templates/docs/configuring-playbook-appservice-draupnir-for-all.pot +++ b/i18n/translation-templates/docs/configuring-playbook-appservice-draupnir-for-all.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,167 +16,215 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:8 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:9 msgid "Setting up Draupnir for All/D4A (optional)" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:10 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:11 msgid "The playbook can install and configure the [Draupnir](https://github.com/the-draupnir-project/Draupnir) moderation tool for you in appservice mode." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:12 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:13 msgid "Appservice mode can be used together with the regular [Draupnir bot](configuring-playbook-bot-draupnir.md) or independently. Details about the differences between the 2 modes are described below." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:14 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:15 msgid "Draupnir Appservice mode compared to Draupnir bot mode" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:16 -msgid "The administrative functions for managing the appservice are alpha quality and very limited. However, the experience of using an appservice-provisioned Draupnir is on par with the experience of using Draupnir from bot mode except in the case of avatar customisation as described later on in this document." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:17 +msgid "The administrative functions for managing the appservice are alpha quality and very limited. However, the experience of using an appservice-provisioned Draupnir is on par with the experience of using Draupnir from bot mode." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:18 -msgid "Draupnir for all is the way to go if you need more than 1 Draupnir instance, but you don't need access to Synapse Admin features as they are not accessible through Draupnir for All (Even though the commands do show up in help)." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:19 +msgid "Draupnir for all is the way to go if you need more than 1 Draupnir instance, but you don't need access to Synapse Admin features as they are not accessible through Draupnir for All." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:20 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:21 msgid "Draupnir for all in the playbook is rate-limit-exempt automatically as its appservice configuration file does not specify any rate limits." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:22 -msgid "Normal Draupnir does come with the benefit of access to Synapse Admin features. You are also able to more easily customise your normal Draupnir than D4A as D4A even on the branch with the Avatar command (To be Upstreamed to Mainline Draupnir) that command is clunky as it requires the use of things like Element Web devtools. In normal Draupnir this is a quick operation where you login to Draupnir with a normal client and set Avatar and Display name normally." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:23 +msgid "Normal Draupnir does come with the benefit of access to Synapse Admin features. You are also able to more easily customise your normal Draupnir than D4A as the avatar command is clunky as it requires the use of things like Element Web devtools. In normal Draupnir this can be done while logged in to the Draupnir account with a normal client and set Avatar and Display name normally." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:24 -msgid "Draupnir for all does not support external tooling like [MRU](https://mru.rory.gay) as it can't access Draupnir's user account." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:25 +msgid "Draupnir for all only has limited support for external tooling like [MRU](https://mru.rory.gay) as it can't access Draupnir's user account." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:26 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:27 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:28 -msgid "Create a main management room" +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:29 +msgid "Prerequisites for Zero Touch Deployment (recommended)" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:30 -msgid "The playbook does not create a management room for your Main Draupnir. You **need to create the room manually** before setting up the bot." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:31 +msgid "As of Draupnir 3.1.0, Zero Touch Deployment of Draupnir Appservice Mode (Draupnir for all) requires you to supply the following:" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:32 -msgid "Note that the room must be unencrypted." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:33 +msgid "MXID of the first person who gets invited to the admin room that the bot creates for you." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:34 -msgid "The management room has to be given an alias, and your bot has to be invited to the room." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:35 +msgid "That is all. The appservice manages everything on its own after you provide it with an MXID to invite." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:36 -msgid "This management room is used to control who has access to your D4A deployment. The room stores this data inside of the control room state so your bot must have sufficient powerlevel to send custom state events. This is default 50 or moderator as Element clients call this powerlevel." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:37 +msgid "If proceeding with Zero Touch Deployment, skip ahead to [Adjusting the playbook configuration](#adjusting-the-playbook-configuration)." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:38 -msgid "[!WARNING] Anyone in this room can control the bot so it is important that you only invite trusted users to this room." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:39 +msgid "Create an admin room (optional)" msgstr "" #: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:41 -msgid "Adjusting the playbook configuration" +msgid "The playbook does not create an admin room for your Draupnir, but the appservice itself can do this for you. Alternatively, you **can create the room manually** before setting up the bot." msgstr "" #: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:43 -msgid "Add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file. Make sure to replace `MANAGEMENT_ROOM_ALIAS_HERE`." +msgid "Note that the room must be unencrypted." +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:45 +msgid "The admin room has to be given an alias, and your bot has to be invited to the room." +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:47 +msgid "This admin room is used to control who has access to your D4A deployment. The room stores this data in the control room state, so your bot must have sufficient power level to send custom state events. This is `50` by default (moderator, as Element clients call this power level)." +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:50 +msgid "Anyone in this room can control the bot so it is important that you only invite trusted users to this room." +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:52 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:54 +msgid "When using Zero Touch Deployment, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file. Make sure to replace `INITIAL_MANAGER_MXID_HERE` with the MXID of the user who should be invited to the admin room first." +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:64 +msgid "If opting out of Zero Touch Deployment, use the following configuration block instead. Make sure to replace `MANAGEMENT_ROOM_ALIAS_HERE` with the alias of the admin room you have created earlier." +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:72 +msgid "Running both bot mode and appservice mode" +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:74 +msgid "When running both [bot mode](./configuring-playbook-bot-draupnir.md) and appservice mode, the playbook will force-restart the bot if running a non-release tag like `latest` or `main` or a development build. This is due to the conditional restart logic not being able to reliably tell when an update happened." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:51 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:78 +msgid "Conditional restarts work correctly for all tags when running only one of these two operating modes." +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:80 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:53 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:82 msgid "There are some additional things you may wish to configure about the component." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:55 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:84 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:57 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:86 msgid "`roles/custom/matrix-appservice-draupnir-for-all/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_appservice_draupnir_for_all_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:59 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:88 msgid "For example, to change Draupnir's `protectAllJoinedRooms` option to `true`, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:73 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:102 msgid "You can refer to the upstream [documentation](https://github.com/the-draupnir-project/Draupnir) for more configuration documentation." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:75 -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:90 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:104 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:119 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:77 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:106 msgid "The playbook ships a full copy of the example config that does transfer to provisioned Draupnirs in the production-bots.yaml.j2 file in the template directory of the role." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:79 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:108 msgid "Config extension does not affect the appservices config as this config is not extensible in current Draupnir anyway. It instead touches the config passed to the Draupnirs that your Appservice creates. So the example above (`protectAllJoinedRooms: true`) makes all provisioned Draupnirs protect all joined rooms." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:81 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:110 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:83 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:112 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:92 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:121 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:94 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:123 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:96 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:125 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:98 -msgid "If you made it through all the steps above and your main control room was joined by a user called `@draupnir-main:example.com` you have successfully installed Draupnir for All and can now start using it." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:127 +msgid "If you made it through all the steps above and your main control room was joined by a user called `@draupnir-main:example.com`, you have successfully installed Draupnir for All and can now start using it." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:100 -msgid "The installation of Draupnir for all in this playbook is very much Alpha quality. Usage-wise, Draupnir for all is almost identical to Draupnir bot mode." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:129 +msgid "If using Zero Touch Deployment, the flow is reversed and the success signal is the initial manager account being invited to the admin room." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:102 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:131 +msgid "Draupnir for all installation via this playbook is very much Alpha quality. Usage-wise, Draupnir for all is almost identical to Draupnir bot mode, except that protections requiring homeserver admin access are not available, and the config file is shared between all bots so legacy protections like wordlist share a single global config." +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:133 msgid "Granting Users the ability to use D4A" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:104 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:135 msgid "Draupnir for all includes several security measures like that it only allows users that are on its allow list to ask for a bot. To add a user to this list we have 2 primary options. Using the chat to tell Draupnir to do this for us or if you want to automatically do it by sending `m.policy.rule.user` events that target the subject you want to allow provisioning for with the `org.matrix.mjolnir.allow` recommendation. Using the chat is recommended." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:106 -msgid "The bot requires a powerlevel of 50 in the management room to control who is allowed to use the bot. The bot does currently not say anything if this is true or false. (This is considered a bug and is documented in issue [#297](https://github.com/the-draupnir-project/Draupnir/issues/297))" +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:137 +msgid "The bot requires a power level of 50 in the management room to control who is allowed to use the bot. The bot does currently not say anything if this is true or false. (This is considered a bug and is documented in issue [#297](https://github.com/the-draupnir-project/Draupnir/issues/297).) This issue is largely mitigated by the Zero Touch Deployment workflows introduced in Draupnir 3.1.0." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:108 -msgid "To allow users or whole homeservers you type /plain !admin allow `target` and target can be either a MXID or a wildcard like `@*:example.com` to allow all users on example.com to register. We use /plain to force the client to not attempt to mess with this command as it can break Wildcard commands especially." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:139 +msgid "To allow users or whole homeservers you type /plain !admin allow `target` and target can be either a MXID or a wildcard like `@*:example.com` to allow all users on example.com to provision a bot. We use /plain to force the client to not attempt to mess with this command as it can break Wildcard commands especially." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:110 +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:141 msgid "How to provision a D4A once you are allowed to" msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:112 -msgid "To provision a D4A, you need to start a chat with `@draupnir-main:example.com`. The bot will reject this invite and you will shortly get invited to the Draupnir control room for your newly provisioned Draupnir. From here its just a normal Draupnir experience." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:143 +msgid "Once someone is allowed to provision a bot, simply provision them one with `!admin provision MXID`." +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:145 +msgid "Self-service provisioning is disabled as a security measure because it is currently bugged. Force-provisioning (with `!admin provision`) bypasses this disabled status." +msgstr "" + +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:147 +msgid "Note that you should always make sure there is an allow entry matching whoever is provisioned, because once self-service is fixed, the bot of anyone who is not allowed to provision a bot will refuse to start." msgstr "" -#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:114 -msgid "Congratulations if you made it all the way here because you now have a fully working Draupnir for all deployment." +#: ../../../docs/configuring-playbook-appservice-draupnir-for-all.md:149 +msgid "Congratulations if you made it all the way here, because you now have a fully working Draupnir for all deployment." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bot-baibot.pot b/i18n/translation-templates/docs/configuring-playbook-bot-baibot.pot index 45ad5a2d6..a23153aaa 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bot-baibot.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bot-baibot.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-06-29 17:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -25,7 +25,7 @@ msgid "🤖 [baibot](https://github.com/etkecc/baibot) (pronounced bye-bot) is a msgstr "" #: ../../../docs/configuring-playbook-bot-baibot.md:17 -msgid "It supports [OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/) models, as many well as other [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md)." +msgid "It supports many [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md), including the privacy-first [Venice](#venice) we recommend, [OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/) models, and more." msgstr "" #: ../../../docs/configuring-playbook-bot-baibot.md:19 @@ -80,369 +80,424 @@ msgstr "" msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:78 +#: ../../../docs/configuring-playbook-bot-baibot.md:42 +msgid "Authentication can be configured in one of two mutually-exclusive ways:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:44 +msgid "**Password authentication** (`matrix_bot_baibot_config_user_password`) - recommended for most playbook-managed setups, because it integrates with automatic user creation flow used by the playbook, and auto-creates the bot account" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:45 +msgid "**Access-token authentication** (`matrix_bot_baibot_config_user_access_token` + `matrix_bot_baibot_config_user_device_id`) - useful for specific [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md)/OIDC setups where password authentication is not available or not desired" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:47 +msgid "Even when [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) is enabled, password authentication is still typically the best fit for baibot if you're using a playbook-managed bot account." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:49 +msgid "For upstream details, see baibot's [🔐 Authentication](https://github.com/etkecc/baibot/blob/main/docs/configuration/authentication.md) documentation." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:97 msgid "As mentioned above, **this may not be enough**. Continue with the configuration sections below." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:80 +#: ../../../docs/configuring-playbook-bot-baibot.md:99 msgid "👮‍♂️ Administrator configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:82 -#: ../../../docs/configuring-playbook-bot-baibot.md:106 +#: ../../../docs/configuring-playbook-bot-baibot.md:101 +#: ../../../docs/configuring-playbook-bot-baibot.md:125 msgid "This is an addition to the [base configuration](#base-configuration)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:84 +#: ../../../docs/configuring-playbook-bot-baibot.md:103 msgid "To specify who is considered a bot [👮‍♂️ Administrator](https://github.com/etkecc/baibot/blob/main/docs/access.md#administrators), you either need to specify `matrix_bot_baibot_config_access_admin_patterns` or `matrix_admin`. The latter is a single variable which affects all bridges and bots." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:86 +#: ../../../docs/configuring-playbook-bot-baibot.md:105 msgid "If `matrix_admin` is already configured in your `vars.yml` configuration, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:88 -#: ../../../docs/configuring-playbook-bot-baibot.md:117 +#: ../../../docs/configuring-playbook-bot-baibot.md:107 +#: ../../../docs/configuring-playbook-bot-baibot.md:136 msgid "**If necessary**, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:102 +#: ../../../docs/configuring-playbook-bot-baibot.md:121 msgid "👥 Initial users configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:104 +#: ../../../docs/configuring-playbook-bot-baibot.md:123 msgid "By default, **all users on your homeserver are considered allowed users**. If that's OK, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:108 +#: ../../../docs/configuring-playbook-bot-baibot.md:127 msgid "To specify who is considered a bot [👥 User](https://github.com/etkecc/baibot/blob/main/docs/access.md#user), you may:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:110 +#: ../../../docs/configuring-playbook-bot-baibot.md:129 msgid "define an **initial** value for `matrix_bot_baibot_config_initial_global_config_user_patterns` Ansible variable, as shown below" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:111 +#: ../../../docs/configuring-playbook-bot-baibot.md:130 msgid "configure the list at runtime via the bot's `!bai access set-users SPACE_SEPARATED_PATTERNS` command" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:113 +#: ../../../docs/configuring-playbook-bot-baibot.md:132 msgid "Configuring `matrix_bot_baibot_config_initial_global_config_user_patterns` is optional, but it can be useful to pre-configure the bot with a list of users who should have access to the bot's features." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:115 +#: ../../../docs/configuring-playbook-bot-baibot.md:134 msgid "**Note**: Once initially configured, the allowed users list **cannot be managed via Ansible anymore**. It can only be managed subsequently via bot commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:129 +#: ../../../docs/configuring-playbook-bot-baibot.md:148 msgid "🤖 Configuring agents via Ansible" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:131 +#: ../../../docs/configuring-playbook-bot-baibot.md:150 msgid "You are **not required** to define agents [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration) via Ansible. **To get started quickly**, you can **skip this section and define agents at runtime via chat commands** (following the bot's guidance)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:133 +#: ../../../docs/configuring-playbook-bot-baibot.md:152 msgid "Privileged users (like the [👮‍♂️ Administrator](#️-administrator-configuration), but potentially others too — see the upstream [🔒 access](https://github.com/etkecc/baibot/blob/main/docs/access.md) documentation) can **define agents dynamically at any time** via chat commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:135 +#: ../../../docs/configuring-playbook-bot-baibot.md:154 msgid "The Ansible role includes preset variables for easily enabling some [🤖 agents](https://github.com/etkecc/baibot/blob/main/docs/agents.md) on various [☁️ providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md) (e.g. OpenAI, etc)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:137 +#: ../../../docs/configuring-playbook-bot-baibot.md:156 msgid "Besides the presets, the Ansible role also includes support for configuring additional statically-defined agents via the `matrix_bot_baibot_config_agents_static_definitions_custom` Ansible variable." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:139 +#: ../../../docs/configuring-playbook-bot-baibot.md:158 msgid "Agents defined statically and those created dynamically (via chat) are named differently, so **conflict cannot arise**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:141 +#: ../../../docs/configuring-playbook-bot-baibot.md:160 msgid "Depending on your propensity for [GitOps](https://en.wikipedia.org/wiki/DevOps#GitOps), you may prefer to define agents statically via Ansible, or you may wish to do it dynamically via chat." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:143 -msgid "Before proceeding, we recommend reading the upstream documentation on [How to choose a provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#how-to-choose-a-provider). In short, it's probably best to go with [OpenAI](#openai)." +#: ../../../docs/configuring-playbook-bot-baibot.md:162 +msgid "Before proceeding, we recommend reading the upstream documentation on [How to choose a provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#how-to-choose-a-provider) for a side-by-side of what each one can do. In short: we recommend [Venice](#venice), the most capable provider baibot supports and the only one that keeps no logs and trains on nothing. If you'd rather start with the most widely-used option, [OpenAI](#openai) is a solid, well-supported choice too." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:145 -msgid "Anthropic" +#: ../../../docs/configuring-playbook-bot-baibot.md:164 +msgid "Venice" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:147 -msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [Anthropic provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#anthropic) with the help of the playbook's preset variables." +#: ../../../docs/configuring-playbook-bot-baibot.md:166 +msgid "[Venice](https://venice.ai/chat?ref=kpXDe6) _(ref link with a $10 bonus for you)_ is the provider we recommend. It's the most capable one baibot supports, and the only one that pairs that full feature set with real privacy: inference runs on Venice's own GPUs or on zero-data-retention partner hardware, so your prompts and replies are stored nowhere and never used for training. It serves both frontier proprietary models and the latest open-source ones." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:168 +msgid "Venice also leaves the content policy to you instead of imposing its own. Its models answer without the reflexive refusals some hosted services apply, and both text and image generation can handle adult or otherwise sensitive subjects when you need them to. Image generation ships a `safe_mode` that blurs adult content by default; you can turn it off (see the sample config). This pairs naturally with the privacy above: a bot you can speak to candidly, that keeps nothing." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:170 +msgid "Unlike the [OpenAI Compatible](#openai-compatible) provider (which can also point at Venice, but drops images and can't reach its audio or native image endpoints), this is a first-class integration that exposes Venice's full parameter set: text-generation with vision, file inputs, prompt caching and native web search, plus speech-to-text, text-to-speech, and image generation and editing." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:172 +msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [Venice provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#venice) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:149 -#: ../../../docs/configuring-playbook-bot-baibot.md:173 -#: ../../../docs/configuring-playbook-bot-baibot.md:204 -#: ../../../docs/configuring-playbook-bot-baibot.md:232 +#: ../../../docs/configuring-playbook-bot-baibot.md:174 +#: ../../../docs/configuring-playbook-bot-baibot.md:199 +#: ../../../docs/configuring-playbook-bot-baibot.md:223 +#: ../../../docs/configuring-playbook-bot-baibot.md:254 +#: ../../../docs/configuring-playbook-bot-baibot.md:282 msgid "Here's an example **addition** to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:165 -#: ../../../docs/configuring-playbook-bot-baibot.md:196 -#: ../../../docs/configuring-playbook-bot-baibot.md:222 -#: ../../../docs/configuring-playbook-bot-baibot.md:256 +#: ../../../docs/configuring-playbook-bot-baibot.md:187 +msgid "Because this is a [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agent, it will be given a `static/` ID prefix and will be named `static/venice`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:189 +msgid "Every Venice knob (sampling, caching, reasoning, web-search behavior, voice and image controls) has a matching `matrix_bot_baibot_config_agents_static_definitions_venice_config_*` variable. The [fully-commented sample config](https://github.com/etkecc/baibot/blob/main/docs/sample-provider-configs/venice.yml) explains every one of them." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:191 +#: ../../../docs/configuring-playbook-bot-baibot.md:215 +#: ../../../docs/configuring-playbook-bot-baibot.md:246 +#: ../../../docs/configuring-playbook-bot-baibot.md:272 +#: ../../../docs/configuring-playbook-bot-baibot.md:306 msgid "If you'd like to use more than one model, take a look at the [Configuring additional agents (without a preset)](#configuring-additional-agents-without-a-preset) section below." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:167 -#: ../../../docs/configuring-playbook-bot-baibot.md:198 -#: ../../../docs/configuring-playbook-bot-baibot.md:224 -#: ../../../docs/configuring-playbook-bot-baibot.md:258 +#: ../../../docs/configuring-playbook-bot-baibot.md:193 +#: ../../../docs/configuring-playbook-bot-baibot.md:217 +#: ../../../docs/configuring-playbook-bot-baibot.md:248 +#: ../../../docs/configuring-playbook-bot-baibot.md:274 +#: ../../../docs/configuring-playbook-bot-baibot.md:308 msgid "💡 You may also wish to use this new agent for [🤝 Configuring initial default handlers](#-configuring-initial-default-handlers)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:169 +#: ../../../docs/configuring-playbook-bot-baibot.md:195 +msgid "Anthropic" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:197 +msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [Anthropic provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#anthropic) with the help of the playbook's preset variables." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:219 msgid "Groq" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:171 +#: ../../../docs/configuring-playbook-bot-baibot.md:221 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [Groq provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#groq) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:194 +#: ../../../docs/configuring-playbook-bot-baibot.md:244 msgid "Because this is a [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agent, it will be given a `static/` ID prefix and will be named `static/groq`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:200 +#: ../../../docs/configuring-playbook-bot-baibot.md:250 msgid "Mistral" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:202 +#: ../../../docs/configuring-playbook-bot-baibot.md:252 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [🇫🇷 Mistral provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#mistral) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:220 +#: ../../../docs/configuring-playbook-bot-baibot.md:270 msgid "Because this is a [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agent, it will be given a `static/` ID prefix and will be named `static/mistral`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:226 +#: ../../../docs/configuring-playbook-bot-baibot.md:276 msgid "OpenAI" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:228 +#: ../../../docs/configuring-playbook-bot-baibot.md:278 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [OpenAI provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openai) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:230 +#: ../../../docs/configuring-playbook-bot-baibot.md:280 msgid "The OpenAI provider is **only meant to be used with OpenAI's official API** and compatibility with other services (which do not fully adhere to the OpenAI API spec completely) is limited. **If you're targeting an OpenAI-compatible service**, use the [OpenAI Compatible](#openai-compatible) provider instead." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:254 +#: ../../../docs/configuring-playbook-bot-baibot.md:304 msgid "Because this is a [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agent, it will be given a `static/` ID prefix and will be named `static/openai`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:260 +#: ../../../docs/configuring-playbook-bot-baibot.md:310 msgid "OpenAI Compatible" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:262 +#: ../../../docs/configuring-playbook-bot-baibot.md:312 msgid "You can statically-define a single [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md) instance powered by the [OpenAI Compatible provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openai-compatible) with the help of the playbook's preset variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:264 +#: ../../../docs/configuring-playbook-bot-baibot.md:314 msgid "This provider allows you to use OpenAI-compatible API services like [OpenRouter](https://github.com/etkecc/baibot/blob/main/docs/providers.md#openrouter), [Together AI](https://github.com/etkecc/baibot/blob/main/docs/providers.md#together-ai), etc." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:266 +#: ../../../docs/configuring-playbook-bot-baibot.md:316 msgid "Some of these popular services already have **shortcut** providers (see [supported providers](https://github.com/etkecc/baibot/blob/main/docs/providers.md#supported-providers) leading to this one behind the scenes — this make it easier to get started." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:268 +#: ../../../docs/configuring-playbook-bot-baibot.md:318 msgid "As of this moment, the playbook does not include presets for any of these services, so you'll need to [Configuring additional agents (without a preset)](#configuring-additional-agents-without-a-preset)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:270 +#: ../../../docs/configuring-playbook-bot-baibot.md:320 msgid "Configuring additional agents (without a preset)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:272 +#: ../../../docs/configuring-playbook-bot-baibot.md:322 msgid "The Ansible role may be lacking preset variables for some [☁️ provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md), or you may wish to statically-define an agent on the same provider twice (or more) with different configuration." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:274 +#: ../../../docs/configuring-playbook-bot-baibot.md:324 msgid "It's possible to inject your own agent configuration using the `matrix_bot_baibot_config_agents_static_definitions_custom` Ansible variable." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:276 +#: ../../../docs/configuring-playbook-bot-baibot.md:326 msgid "You can also define providers at runtime, by chatting with the bot, so using Ansible is not a requirement." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:278 +#: ../../../docs/configuring-playbook-bot-baibot.md:328 msgid "Below is an an **example** demonstrating **statically-defining agents via Ansible without using presets**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:317 +#: ../../../docs/configuring-playbook-bot-baibot.md:367 msgid "Because these are [statically](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md#static-configuration)-defined agents, they will be given a `static/` ID prefix and will be named `static/my-openai-gpt-3.5-turbo-agent` and `static/my-ollama-agent`, respectively." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:319 +#: ../../../docs/configuring-playbook-bot-baibot.md:369 msgid "💡 To figure out what to put in the `config` section, refer to the [☁️ provider](https://github.com/etkecc/baibot/blob/main/docs/providers.md) page, which contains **sample configuration YAML for each provider**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:321 +#: ../../../docs/configuring-playbook-bot-baibot.md:371 msgid "As with any [🤖 agent](https://github.com/etkecc/baibot/blob/main/docs/agents.md), defining them means they exist. To actually make use of them, they need to be configured as handlers globally or in a specific room — see [Mixing & matching models](https://github.com/etkecc/baibot/blob/main/docs/features.md#mixing--matching-models)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:323 +#: ../../../docs/configuring-playbook-bot-baibot.md:373 msgid "💡 You may also wish to use these new agents for [🤝 Configuring initial default handlers](#-configuring-initial-default-handlers)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:325 +#: ../../../docs/configuring-playbook-bot-baibot.md:375 msgid "🤝 Configuring initial default handlers" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:327 +#: ../../../docs/configuring-playbook-bot-baibot.md:377 msgid "This section is only useful if you're [🤖 Configuring agents via Ansible](#-configuring-agents-via-ansible), as it lets you put these agents to use as soon as the bot starts (by adjusting the bot's **initial global configuration**)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:329 +#: ../../../docs/configuring-playbook-bot-baibot.md:379 msgid "If you're not configuring agents via Ansible, you can skip this section." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:331 +#: ../../../docs/configuring-playbook-bot-baibot.md:381 msgid "This section is only useful the first time around. **Once initially configured the global configuration cannot be managed Ansible**, but only via bot commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:333 +#: ../../../docs/configuring-playbook-bot-baibot.md:383 msgid "baibot supports [various purposes](https://github.com/etkecc/baibot/blob/main/docs/features.md):" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:335 +#: ../../../docs/configuring-playbook-bot-baibot.md:385 msgid "[💬 text-generation](https://github.com/etkecc/baibot/blob/main/docs/features.md#-text-generation): communicating with you via text" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:337 +#: ../../../docs/configuring-playbook-bot-baibot.md:387 msgid "[🦻 speech-to-text](https://github.com/etkecc/baibot/blob/main/docs/features.md#-speech-to-text): turning your voice messages into text" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:339 +#: ../../../docs/configuring-playbook-bot-baibot.md:389 msgid "[🗣️ text-to-speech](https://github.com/etkecc/baibot/blob/main/docs/features.md#-text-to-speech): turning bot or users text messages into voice messages" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:341 +#: ../../../docs/configuring-playbook-bot-baibot.md:391 msgid "[🖌️ image-generation](https://github.com/etkecc/baibot/blob/main/docs/features.md#-image-generation): generating images based on instructions" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:343 +#: ../../../docs/configuring-playbook-bot-baibot.md:393 msgid "❓ catch-all: special purposes, indicating use as a fallback (when no specific handler is configured)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:345 +#: ../../../docs/configuring-playbook-bot-baibot.md:395 msgid "[Mixing & matching models](https://github.com/etkecc/baibot/blob/main/docs/features.md#mixing--matching-models) is made possible by the bot's ability to have different [🤝 handlers](https://github.com/etkecc/baibot/blob/main/docs/configuration/handlers.md) configured for different purposes." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:347 +#: ../../../docs/configuring-playbook-bot-baibot.md:397 msgid "This configuration can be done as a global fallback, or per-room. Both of these [🛠️ configurations](https://github.com/etkecc/baibot/blob/main/docs/configuration/README.md) are managed at runtime (viat chat), but **the global configuration can have some initial defaults configured via Ansible**." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:349 +#: ../../../docs/configuring-playbook-bot-baibot.md:399 msgid "You can configure the **initial values** for these via Ansible, via the `matrix_bot_baibot_config_initial_global_config_handler_*` variables." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:351 +#: ../../../docs/configuring-playbook-bot-baibot.md:401 msgid "Example **additional** `vars.yml` configuration:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:368 +#: ../../../docs/configuring-playbook-bot-baibot.md:418 msgid "**Note**: these are initial defaults for the bot's global configuration. As such, changing any of these values subsequently has no effect on the bot's behavior. **Once initially configured the global configuration cannot be managed Ansible**, but only via bot commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:370 +#: ../../../docs/configuring-playbook-bot-baibot.md:420 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:372 +#: ../../../docs/configuring-playbook-bot-baibot.md:422 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:374 +#: ../../../docs/configuring-playbook-bot-baibot.md:424 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:376 +#: ../../../docs/configuring-playbook-bot-baibot.md:426 msgid "`roles/custom/matrix-bot-baibot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:377 +#: ../../../docs/configuring-playbook-bot-baibot.md:427 msgid "`roles/custom/matrix-bot-baibot/templates/config.yaml.j2` for the bot's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_baibot_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:379 +#: ../../../docs/configuring-playbook-bot-baibot.md:429 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:381 +#: ../../../docs/configuring-playbook-bot-baibot.md:431 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:388 +#: ../../../docs/configuring-playbook-bot-baibot.md:438 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:390 -msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." +#: ../../../docs/configuring-playbook-bot-baibot.md:440 +msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account when password authentication is used." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:392 +#: ../../../docs/configuring-playbook-bot-baibot.md:442 +msgid "If you're using access-token authentication, the bot account must already exist and the configured token + device ID must match that account. This mode is mainly for MAS/OIDC setups where password-based bot login is not suitable." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-baibot.md:444 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:394 +#: ../../../docs/configuring-playbook-bot-baibot.md:446 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:396 -msgid "If you change the bot password (`matrix_bot_baibot_config_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_baibot_config_user_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-baibot.md:448 +msgid "If you change the bot password (`matrix_bot_baibot_config_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_baibot_config_user_password` to let the bot know its new password. (This note applies to password authentication mode.)" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:398 +#: ../../../docs/configuring-playbook-bot-baibot.md:450 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:400 +#: ../../../docs/configuring-playbook-bot-baibot.md:452 msgid "To use the bot, invite it to any existing Matrix room (`/invite @baibot:example.com` where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:402 +#: ../../../docs/configuring-playbook-bot-baibot.md:454 msgid "If you're an allowed bot [👥 user](https://github.com/etkecc/baibot/blob/main/docs/access.md#user) (see [👥 Initial users configuration](#-initial-users-configuration)), the bot will accept your invitation and join the room." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:404 +#: ../../../docs/configuring-playbook-bot-baibot.md:456 msgid "After joining, the bot will introduce itself and show information about the [✨ features](https://github.com/etkecc/baibot/blob/main/docs/features.md) that are enabled for it." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:406 +#: ../../../docs/configuring-playbook-bot-baibot.md:458 msgid "If you've [🤖 configured one or more agents via Ansible](#-configuring-agents-via-ansible) and have [🤝 configured initial default handlers](#configuring-initial-default-handlers), the bot will immediately be able to make use of these agents for this new room. Otherwise, you will need to configure agents and/or handlers via chat commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:408 +#: ../../../docs/configuring-playbook-bot-baibot.md:460 msgid "Send `!bai help` to the bot in the room to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:410 +#: ../../../docs/configuring-playbook-bot-baibot.md:462 msgid "You can also refer to the upstream [baibot](https://github.com/etkecc/baibot) project's documentation." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:412 +#: ../../../docs/configuring-playbook-bot-baibot.md:464 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:414 +#: ../../../docs/configuring-playbook-bot-baibot.md:466 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-baibot`." msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:416 +#: ../../../docs/configuring-playbook-bot-baibot.md:468 msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:418 +#: ../../../docs/configuring-playbook-bot-baibot.md:470 msgid "The default logging level for this service is `info`. If you want to increase the verbosity to `debug` (or even `trace`), add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" -#: ../../../docs/configuring-playbook-bot-baibot.md:432 +#: ../../../docs/configuring-playbook-bot-baibot.md:484 msgid "**Alternatively**, you can use a single variable to set the logging level for all of the above (bot + all libraries):" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bot-buscarron.pot b/i18n/translation-templates/docs/configuring-playbook-bot-buscarron.pot index 40217a6e4..cf3ece3a3 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bot-buscarron.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bot-buscarron.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -113,7 +113,7 @@ msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x f msgstr "" #: ../../../docs/configuring-playbook-bot-buscarron.md:92 -msgid "If you change the bot password (`matrix_bot_buscarron_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_buscarron_password` to let the bot know its new password." +msgid "If you change the bot password (`matrix_bot_buscarron_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_buscarron_password` to let the bot know its new password." msgstr "" #: ../../../docs/configuring-playbook-bot-buscarron.md:94 diff --git a/i18n/translation-templates/docs/configuring-playbook-bot-draupnir.pot b/i18n/translation-templates/docs/configuring-playbook-bot-draupnir.pot index 6c7526f37..885f1aa5f 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bot-draupnir.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bot-draupnir.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-16 16:15+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,419 +16,507 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../docs/configuring-playbook-bot-draupnir.md:10 +#: ../../../docs/configuring-playbook-bot-draupnir.md:11 msgid "Setting up Draupnir (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:12 +#: ../../../docs/configuring-playbook-bot-draupnir.md:13 msgid "The playbook can install and configure the [Draupnir](https://github.com/the-draupnir-project/Draupnir) moderation bot for you." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:14 +#: ../../../docs/configuring-playbook-bot-draupnir.md:15 msgid "See the project's [documentation](https://the-draupnir-project.github.io/draupnir-documentation/) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:16 +#: ../../../docs/configuring-playbook-bot-draupnir.md:17 msgid "This documentation page is about installing Draupnir in bot mode. As an alternative, you can run a multi-instance Draupnir deployment by installing [Draupnir in appservice mode](./configuring-playbook-appservice-draupnir-for-all.md) (called Draupnir-for-all) instead." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:18 -msgid "If your migrating from [Mjolnir](configuring-playbook-bot-mjolnir.md), skip to [this section](#migrating-from-mjolnir-only-required-if-migrating)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:19 +msgid "**Note**: you can also use the [Meowlnir](configuring-playbook-bot-meowlnir.md) or [Mjolnir](configuring-playbook-bot-mjolnir.md) bots, which speak the same [policy list](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists) protocol." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:20 +#: ../../../docs/configuring-playbook-bot-draupnir.md:21 +msgid "When migrating from [Mjolnir](configuring-playbook-bot-mjolnir.md), skip to [this section](#migrating-from-mjolnir-only-required-if-migrating)." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:23 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:22 -msgid "Create a management room" +#: ../../../docs/configuring-playbook-bot-draupnir.md:25 +msgid "Prerequisites for Zero Touch Deployment (recommended)" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:27 +msgid "As of Draupnir 3.1.0, Zero Touch Deployment of Draupnir bot mode requires you to supply the following:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:29 +msgid "MXID of the first person who gets invited to the management room that the bot creates for you." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:30 +msgid "A permanent access token for authentication. Instructions for obtaining one can be found at [obtain an access token via curl](obtaining-access-tokens.md#obtain-an-access-token-via-curl)." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:31 +msgid "A user account for Draupnir." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:33 +msgid "Zero Touch Deployment is the officially preferred installation method for new deployments of Draupnir as of 3.1.0." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:24 +#: ../../../docs/configuring-playbook-bot-draupnir.md:35 +msgid "Create a management room (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:37 msgid "Using your own account, create a new invite only room that you will use to manage the bot. This is the room where you will see the status of the bot and where you will send commands to the bot, such as the command to ban a user from another room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:26 -msgid "[!WARNING] Anyone in this room can control the bot so it is important that you only invite trusted users to this room." +#: ../../../docs/configuring-playbook-bot-draupnir.md:40 +msgid "Anyone in this room can control the bot so it is important that you only invite trusted users to this room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:29 +#: ../../../docs/configuring-playbook-bot-draupnir.md:42 +msgid "The bot also needs at least a Moderator power level (50) in this room. This power level is granted in a [later step](#create-and-invite-the-bot-to-the-management-room-only-when-using-native-login-without-zero-touch-deployment), after the bot gets invited to the room." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:44 msgid "It is possible to make the management room encrypted (E2EE). If doing so, then you need to enable the native E2EE support (see [below](#native-e2ee-support))." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:31 +#: ../../../docs/configuring-playbook-bot-draupnir.md:46 +msgid "E2EE support for the management room is mutually exclusive with Zero Touch Deployment of Draupnir." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:48 msgid "Once you have created the room you need to copy the room ID so you can specify it on your `inventory/host_vars/matrix.example.com/vars.yml` file. In Element Web you can check the ID by going to the room's settings and clicking \"Advanced\". The room ID will look something like `!qporfwt:example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:33 +#: ../../../docs/configuring-playbook-bot-draupnir.md:50 msgid "End-to-End Encryption support" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:35 +#: ../../../docs/configuring-playbook-bot-draupnir.md:52 msgid "Decide whether you want to support having an encrypted management room or not. Draupnir can still protect encrypted rooms without encryption support enabled." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:37 +#: ../../../docs/configuring-playbook-bot-draupnir.md:54 msgid "Refer to Draupnir's [documentation](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#protecting-encrypted-rooms) for more details about why you might want to care about encryption support for protected rooms." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:39 +#: ../../../docs/configuring-playbook-bot-draupnir.md:56 msgid "Disable Pantalaimon for Draupnir (since v2.0.0; optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:41 +#: ../../../docs/configuring-playbook-bot-draupnir.md:58 msgid "It is known that running Draupnir along with Pantalaimon breaks all workflows that involve answering prompts with reactions." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:43 +#: ../../../docs/configuring-playbook-bot-draupnir.md:60 msgid "If you are updating Draupnir from v1.x.x and have enabled Pantalaimon for it, you can disable Pantalaimon in favor of the native E2EE support. To disable Pantalaimon, remove the configuration `matrix_bot_draupnir_pantalaimon_use: true` from your `vars.yml` file." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:45 +#: ../../../docs/configuring-playbook-bot-draupnir.md:62 msgid "**Note**: because the management room is still encrypted, disabling it without enabling the native E2EE support will break the management room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:47 +#: ../../../docs/configuring-playbook-bot-draupnir.md:64 msgid "Native E2EE support" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:49 +#: ../../../docs/configuring-playbook-bot-draupnir.md:66 msgid "To enable the native E2EE support, you need to obtain an access token for Draupnir and set it on your `vars.yml` file." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:51 +#: ../../../docs/configuring-playbook-bot-draupnir.md:68 msgid "Note that native E2EE requires a clean access token that has not touched E2EE so curl is recommended as a method to obtain it. **The access token obtained via Element Web does not work with it**. Refer to the documentation on [how to obtain an access token via curl](obtaining-access-tokens.md#obtain-an-access-token-via-curl)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:53 +#: ../../../docs/configuring-playbook-bot-draupnir.md:70 msgid "To enable the native E2EE support, add the following configuration to your `vars.yml` file. Make sure to replace `CLEAN_ACCESS_TOKEN_HERE` with the access token you obtained just now." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:64 +#: ../../../docs/configuring-playbook-bot-draupnir.md:81 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:66 -msgid "To enable the bot, add the following configuration to your `vars.yml` file. Make sure to replace `MANAGEMENT_ROOM_ID_HERE` with the one of the room which you have created earlier." +#: ../../../docs/configuring-playbook-bot-draupnir.md:83 +msgid "Configuration for Zero Touch Deployment (recommended)" msgstr "" #: ../../../docs/configuring-playbook-bot-draupnir.md:85 -msgid "Create and invite the bot to the management room" +msgid "To enable the bot using Zero Touch Deployment, add the following configuration to your `vars.yml` file. Make sure to replace `INITIAL_MANAGER_MXID_HERE` with the MXID of the user who should be invited to the management room first, and `CLEAN_ACCESS_TOKEN_HERE` with the access token you obtained." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:99 +msgid "Configuration without Zero Touch Deployment" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:101 +msgid "If you'd prefer to have the bot manage its own login at the cost of having to create the management room manually, you can use native login with the configuration block below. Make sure to replace `MANAGEMENT_ROOM_ID_HERE` with the ID of the management room you have created earlier." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:120 +msgid "Running both bot mode and appservice mode" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:122 +msgid "When running both bot mode and [appservice mode (Draupnir for all)](./configuring-playbook-appservice-draupnir-for-all.md), the playbook will force-restart the bot if running a non-release tag like `latest` or `main` or a development build. This is due to the conditional restart logic not being able to reliably tell when an update happened." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:126 +msgid "Conditional restarts work correctly for all tags when running only one of these two operating modes." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:87 +#: ../../../docs/configuring-playbook-bot-draupnir.md:128 +msgid "Create and invite the bot to the management room (only when using native login without Zero Touch Deployment)" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:130 msgid "Before proceeding to the next step, run the playbook with the following command to create the bot user." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:93 +#: ../../../docs/configuring-playbook-bot-draupnir.md:136 msgid "**Note**: the `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:95 +#: ../../../docs/configuring-playbook-bot-draupnir.md:138 msgid "Then, invite the bot (`@bot.draupnir:example.com`) to its management room which you have created earlier." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:97 +#: ../../../docs/configuring-playbook-bot-draupnir.md:140 +msgid "After the bot joins, give it at least a Moderator power level (50) in the management room." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:143 +msgid "Draupnir stores each protection's settings as custom state events in the management room, and sending those requires a power level of 50 by default. A bot without this power level cannot save any protection settings. The failure is easy to miss and has nasty consequences: the `PolicyChangeNotification` protection, unable to remember its notifications room, will create a brand new one on every restart of the bot (and the playbook restarts it on every installation run), littering your server with abandoned rooms." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:145 +msgid "This is not a concern for Zero Touch Deployment, where the bot creates the management room itself and has full control over it." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:147 +msgid "Creating a user account for the bot (when using Zero Touch Deployment)" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:149 +msgid "Since Zero Touch Deployment is not validated with native login, you will need to create the user account manually." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:151 +msgid "Refer to [registering users](registering-users.md) for documentation on how to configure the user account." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:153 msgid "Make sure the account is free from rate limiting (optional, recommended)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:99 +#: ../../../docs/configuring-playbook-bot-draupnir.md:155 msgid "If your homeserver's implementation is Synapse, you will need to prevent it from rate limiting the bot's account. **This is a highly recommended step. If you do not configure it, Draupnir performance will be degraded.**" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:101 +#: ../../../docs/configuring-playbook-bot-draupnir.md:157 msgid "This can be done using Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users). They can be accessed both externally and internally." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:103 +#: ../../../docs/configuring-playbook-bot-draupnir.md:159 msgid "**Note**: access to the APIs is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, doing so is not recommended for additional security. See [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:105 -msgid "The APIs can also be accessed via [Synapse Admin](https://github.com/etkecc/synapse-admin), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md)." +#: ../../../docs/configuring-playbook-bot-draupnir.md:161 +msgid "The APIs can also be accessed via [Ketesa](https://github.com/etkecc/ketesa), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:107 +#: ../../../docs/configuring-playbook-bot-draupnir.md:163 msgid "Add the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:109 -msgid "To expose the APIs publicly, add the following configuration to your `vars.yml` file:" +#: ../../../docs/configuring-playbook-bot-draupnir.md:165 +msgid "This is automatically done if Ketesa is enabled. Otherwise, to expose the APIs publicly, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:115 +#: ../../../docs/configuring-playbook-bot-draupnir.md:171 msgid "Obtain an access token for admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:117 +#: ../../../docs/configuring-playbook-bot-draupnir.md:173 msgid "Manual access to Synapse's Admin APIs requires an access token for a homeserver admin account. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:119 -msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." +#: ../../../docs/configuring-playbook-bot-draupnir.md:176 +msgid "Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:122 +#: ../../../docs/configuring-playbook-bot-draupnir.md:178 msgid "Run the `curl` command" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:124 +#: ../../../docs/configuring-playbook-bot-draupnir.md:180 msgid "To disable rate limiting, run the following command on systems that ship curl. Before running it, make sure to replace:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:126 +#: ../../../docs/configuring-playbook-bot-draupnir.md:182 msgid "`ADMIN_ACCESS_TOKEN_HERE` with the access token of the admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:127 +#: ../../../docs/configuring-playbook-bot-draupnir.md:183 msgid "`example.com` with your base domain" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:128 +#: ../../../docs/configuring-playbook-bot-draupnir.md:184 msgid "`@bot.draupnir:example.com` with the MXID of your Draupnir bot user" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:134 -#: ../../../docs/configuring-playbook-bot-draupnir.md:207 +#: ../../../docs/configuring-playbook-bot-draupnir.md:190 +#: ../../../docs/configuring-playbook-bot-draupnir.md:265 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:135 +#: ../../../docs/configuring-playbook-bot-draupnir.md:192 msgid "This does not work on outdated Windows 10 as curl is not available there." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:136 +#: ../../../docs/configuring-playbook-bot-draupnir.md:193 msgid "Even if the APIs are not exposed to the internet, you should still be able to run the command on the homeserver locally." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:138 +#: ../../../docs/configuring-playbook-bot-draupnir.md:195 msgid "Abuse Reports" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:140 +#: ../../../docs/configuring-playbook-bot-draupnir.md:197 msgid "Draupnir can receive reports in the management room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:142 +#: ../../../docs/configuring-playbook-bot-draupnir.md:199 msgid "The bot can intercept the report API endpoint of the client-server API, which requires integration with the reverse proxy in front of the homeserver. If you are using Traefik, this playbook can set this up for you:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:148 +#: ../../../docs/configuring-playbook-bot-draupnir.md:205 msgid "Enabling synapse-http-antispam support" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:150 +#: ../../../docs/configuring-playbook-bot-draupnir.md:207 msgid "Certain protections in Draupnir require the [synapse-http-antispam](https://github.com/maunium/synapse-http-antispam) module and a Synapse homeserver plus homeserver admin status to function. This module can be enabled in the playbook via setting `matrix_bot_draupnir_config_web_synapseHTTPAntispam_enabled` to `true` and making sure that Draupnir admin API access is enabled." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:160 -msgid "These protections need to be manually activated and consulting the [enabling protections](#enabling-built-in-protections) guide can be helpful or consulting upstream documentation." +#: ../../../docs/configuring-playbook-bot-draupnir.md:217 +msgid "These protections need to be manually activated. Consulting the [enabling protections](#enabling-built-in-protections) guide and/or upstream documentation can be helpful." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-draupnir.md:219 +msgid "The other method polls a Synapse Admin API endpoint, hence it is available only if using Synapse and if the Draupnir user is an admin. To enable it, set `pollReports: true` in your `vars.yml` file as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:168 +#: ../../../docs/configuring-playbook-bot-draupnir.md:226 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:170 +#: ../../../docs/configuring-playbook-bot-draupnir.md:228 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:172 +#: ../../../docs/configuring-playbook-bot-draupnir.md:230 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:174 +#: ../../../docs/configuring-playbook-bot-draupnir.md:232 msgid "`roles/custom/matrix-bot-draupnir/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_draupnir_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:176 +#: ../../../docs/configuring-playbook-bot-draupnir.md:234 msgid "For example, to change Draupnir's `acceptInvitesFromSpace` option to `!qporfwt:example.com`, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:190 +#: ../../../docs/configuring-playbook-bot-draupnir.md:248 msgid "Migrating from Mjolnir (Only required if migrating)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:192 +#: ../../../docs/configuring-playbook-bot-draupnir.md:250 msgid "Replace your `matrix_bot_mjolnir` config with `matrix_bot_draupnir` config. Also disable Mjolnir if you're doing migration." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:194 +#: ../../../docs/configuring-playbook-bot-draupnir.md:252 msgid "Note that Draupnir supports E2EE natively, so you can enable it instead of Pantalaimon. It is recommended to consult the instruction [here](#native-e2ee-support)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:196 +#: ../../../docs/configuring-playbook-bot-draupnir.md:254 msgid "That is all you need to do due to that Draupnir can complete migration on its own." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:198 +#: ../../../docs/configuring-playbook-bot-draupnir.md:256 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:200 +#: ../../../docs/configuring-playbook-bot-draupnir.md:258 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:209 +#: ../../../docs/configuring-playbook-bot-draupnir.md:267 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:211 +#: ../../../docs/configuring-playbook-bot-draupnir.md:269 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:213 +#: ../../../docs/configuring-playbook-bot-draupnir.md:271 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:215 -msgid "If you change the bot password (`matrix_bot_draupnir_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_draupnir_password` to let the bot know its new password." +#: ../../../docs/configuring-playbook-bot-draupnir.md:273 +msgid "If you change the bot password (`matrix_bot_draupnir_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_draupnir_password` to let the bot know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:217 +#: ../../../docs/configuring-playbook-bot-draupnir.md:275 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:219 +#: ../../../docs/configuring-playbook-bot-draupnir.md:277 msgid "You can refer to the upstream [documentation](https://the-draupnir-project.github.io/draupnir-documentation/) for additional ways to use and configure Draupnir and for a more detailed usage guide." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:221 +#: ../../../docs/configuring-playbook-bot-draupnir.md:279 msgid "Below is a **non-exhaustive quick-start guide** for the impatient." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:223 +#: ../../../docs/configuring-playbook-bot-draupnir.md:281 msgid "Making Draupnir join and protect a room" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:225 +#: ../../../docs/configuring-playbook-bot-draupnir.md:283 msgid "Draupnir can be told to self-join public rooms, but it's better to follow this flow which works well for all kinds of rooms:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:227 +#: ../../../docs/configuring-playbook-bot-draupnir.md:285 msgid "Invite the bot to the room manually ([inviting Draupnir to rooms](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#inviting-draupnir-to-rooms)). Before joining, the bot *may* ask for confirmation in the Management Room" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:229 +#: ../../../docs/configuring-playbook-bot-draupnir.md:287 msgid "[Give the bot permissions to do its job](#giving-draupnir-permissions-to-do-its-job)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:231 +#: ../../../docs/configuring-playbook-bot-draupnir.md:289 msgid "Tell it to protect the room (using the [rooms command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#using-the-draupnir-rooms-command)) by sending the following command to the Management Room: `!draupnir rooms add !qporfwt:example.com`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:233 +#: ../../../docs/configuring-playbook-bot-draupnir.md:291 msgid "To have Draupnir provide useful room protection, you need do to a bit more work (at least the first time around). You may wish to [Subscribe to a public policy list](#subscribing-to-a-public-policy-list), [Create your own own policy and rules](#creating-your-own-policy-lists-and-rules) and [Enabling built-in protections](#enabling-built-in-protections)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:235 +#: ../../../docs/configuring-playbook-bot-draupnir.md:293 msgid "Giving Draupnir permissions to do its job" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:237 +#: ../../../docs/configuring-playbook-bot-draupnir.md:295 msgid "For Draupnir to do its job, you need to [give it permissions](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-protected-rooms#giving-draupnir-permissions) in rooms it's protecting. This involves **giving it an Administrator power level**." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:239 +#: ../../../docs/configuring-playbook-bot-draupnir.md:297 msgid "**We recommend setting this power level as soon as the bot joins your room** (and before you create new rules), so that it can apply rules as soon as they are available. If the bot is under-privileged, it may fail to apply protections and may not retry for a while (or until your restart it)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:241 +#: ../../../docs/configuring-playbook-bot-draupnir.md:299 msgid "Subscribing to a public policy list" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:243 +#: ../../../docs/configuring-playbook-bot-draupnir.md:301 msgid "We recommend **subscribing to a public [policy list](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists)** using the [watch command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-policy-lists#using-draupnirs-watch-command-to-subscribe-to-policy-rooms)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:245 +#: ../../../docs/configuring-playbook-bot-draupnir.md:303 msgid "Policy lists are maintained in Matrix rooms. Popular ones maintained in the public are:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:247 +#: ../../../docs/configuring-playbook-bot-draupnir.md:305 msgid "`#community-moderation-effort-bl:neko.dev`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:248 +#: ../../../docs/configuring-playbook-bot-draupnir.md:306 msgid "`#huginn-muninn-active-threats:feline.support`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:250 +#: ../../../docs/configuring-playbook-bot-draupnir.md:308 msgid "You can tell Draupnir to subscribe to each of these by sending the following command to the Management Room: `!draupnir watch POLICY_LIST_ADDRESS_HERE` (e.g. `!draupnir watch #community-moderation-effort-bl:neko.dev`)" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:252 +#: ../../../docs/configuring-playbook-bot-draupnir.md:310 msgid "Creating your own policy lists and rules" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:254 +#: ../../../docs/configuring-playbook-bot-draupnir.md:312 msgid "We also recommend **creating your own policy lists** with the [list create](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-policy-lists#using-draupnirs-list-create-command-to-create-a-policy-room) command." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:256 +#: ../../../docs/configuring-playbook-bot-draupnir.md:314 msgid "You can do so by sending the following command to the Management Room: `!draupnir list create my-bans my-bans-bl`. This will create a policy list having a name (shortcode) of `my-bans` and stored in a public `#my-bans-bl:example.com` room on your server. As soon as you run this command, the bot will invite you to the policy list room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:258 +#: ../../../docs/configuring-playbook-bot-draupnir.md:316 msgid "A policy list does nothing by itself, so the next step is **adding some rules to your policy list**. Policies target a so-called `entity` (one of: `user`, `room` or `server`). These entities are mentioned on the [policy lists](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists) documentation page and in the Matrix Spec [here](https://spec.matrix.org/v1.11/client-server-api/#mban-recommendation)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:260 +#: ../../../docs/configuring-playbook-bot-draupnir.md:318 msgid "The simplest and most useful entity to target is `user`. Below are a few examples using the [ban command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#the-ban-command) and targeting users." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:262 +#: ../../../docs/configuring-playbook-bot-draupnir.md:320 msgid "To create rules, you run commands in the Management Room (**not** in the policy list room)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:264 +#: ../../../docs/configuring-playbook-bot-draupnir.md:322 msgid "(ban a single user on a given homeserver): `!draupnir ban @charles:example.com my-bans Rude to others`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:265 +#: ../../../docs/configuring-playbook-bot-draupnir.md:323 msgid "(ban all users on a given homeserver by using a [wildcard](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#wildcards)): `!draupnir ban @*:example.org my-bans Spam server, all users are fake`" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:267 +#: ../../../docs/configuring-playbook-bot-draupnir.md:325 msgid "As a result of running these commands, you may observe:" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:269 +#: ../../../docs/configuring-playbook-bot-draupnir.md:327 msgid "Draupnir creating `m.policy.rule.user` state events in the `#my-bans-bl:example.com` room on your server" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:270 +#: ../../../docs/configuring-playbook-bot-draupnir.md:328 msgid "applying these rules against all rooms that Draupnir is an Administrator in" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:272 +#: ../../../docs/configuring-playbook-bot-draupnir.md:330 msgid "You can undo bans with the [unban command](https://the-draupnir-project.github.io/draupnir-documentation/moderator/managing-users#the-unban-command)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:274 +#: ../../../docs/configuring-playbook-bot-draupnir.md:332 msgid "Enabling built-in protections" msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:276 +#: ../../../docs/configuring-playbook-bot-draupnir.md:334 msgid "You can also **turn on various built-in [protections](https://the-draupnir-project.github.io/draupnir-documentation/protections)** like `JoinWaveShortCircuitProtection` (\"If X amount of users join in Y time, set the room to invite-only\")." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:278 +#: ../../../docs/configuring-playbook-bot-draupnir.md:336 msgid "To **see which protections are available and which are enabled**, send a `!draupnir protections` command to the Management Room." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:280 +#: ../../../docs/configuring-playbook-bot-draupnir.md:338 msgid "To [**see the configuration options for a given protection**](https://the-draupnir-project.github.io/draupnir-documentation/protections/configuring-protections#displaying-the-protection-settings), send a `!draupnir protections show PROTECTION_NAME` (e.g. `!draupnir protections show JoinWaveShortCircuitProtection`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:282 +#: ../../../docs/configuring-playbook-bot-draupnir.md:340 msgid "To [**set a specific option for a given protection**](https://the-draupnir-project.github.io/draupnir-documentation/protections/configuring-protections#changing-protection-settings), send a command like this: `!draupnir protections config set PROTECTION_NAME OPTION VALUE` (e.g. `!draupnir protections config set JoinWaveShortCircuitProtection timescaleMinutes 30`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:284 +#: ../../../docs/configuring-playbook-bot-draupnir.md:342 msgid "To [**enable a given protection**](https://the-draupnir-project.github.io/draupnir-documentation/protections/block-invitations-on-server-protection#enabling-the-protection), send a command like this: `!draupnir protections enable PROTECTION_NAME` (e.g. `!draupnir protections enable JoinWaveShortCircuitProtection`)." msgstr "" -#: ../../../docs/configuring-playbook-bot-draupnir.md:286 +#: ../../../docs/configuring-playbook-bot-draupnir.md:344 msgid "To **disable a given protection**, send a command like this: `!draupnir protections disable PROTECTION_NAME` (e.g. `!draupnir protections disable JoinWaveShortCircuitProtection`)." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bot-go-neb.pot b/i18n/translation-templates/docs/configuring-playbook-bot-go-neb.pot index 4ff10a5e1..5eed8edc8 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bot-go-neb.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bot-go-neb.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-23 05:22+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,158 +16,22 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../docs/configuring-playbook-bot-go-neb.md:11 -msgid "Setting up Go-NEB (optional, unmaintained)" +#: ../../../docs/configuring-playbook-bot-go-neb.md:12 +msgid "Setting up Go-NEB (optional, removed)" msgstr "" -#: ../../../docs/configuring-playbook-bot-go-neb.md:13 -msgid "**Note**: [Go-NEB](https://github.com/matrix-org/go-neb) is now an archived (**unmaintained**) project. We recommend not bothering with installing it. While not a 1:1 replacement, the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md). Consider using that bot instead of this one." +#: ../../../docs/configuring-playbook-bot-go-neb.md:14 +msgid "🪦 The playbook used to be able to install and configure [Go-NEB](https://github.com/matrix-org/go-neb), but no longer includes this component as it has been discontinued." msgstr "" -#: ../../../docs/configuring-playbook-bot-go-neb.md:15 -msgid "The playbook can install and configure [Go-NEB](https://github.com/matrix-org/go-neb) for you." +#: ../../../docs/configuring-playbook-bot-go-neb.md:16 +msgid "While not a 1:1 replacement, the bot's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-go-neb.md:17 -msgid "Go-NEB is a Matrix bot written in Go. It is the successor to Matrix-NEB, the original Matrix bot written in Python." +#: ../../../docs/configuring-playbook-bot-go-neb.md:18 +msgid "Uninstalling Go-NEB manually" msgstr "" -#: ../../../docs/configuring-playbook-bot-go-neb.md:19 -msgid "See the project's [documentation](https://github.com/matrix-org/go-neb/blob/master/README.md) to learn what it does and why it might be useful to you." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:21 -msgid "Prerequisites" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:23 -msgid "Register the bot account" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:25 -msgid "The playbook does not automatically create users for you. You **need to register the bot user manually** before setting up the bot." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:27 -msgid "Generate a strong password for the bot. You can create one with a command like `pwgen -s 64 1`." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:29 -msgid "You can use the playbook to [register a new user](registering-users.md):" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:35 -msgid "Obtain an access token" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:37 -msgid "The bot requires an access token to be able to connect to your homeserver. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:39 -msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:42 -msgid "Adjusting DNS records" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:44 -msgid "By default, this playbook installs Go-NEB on the `goneb.` subdomain (`goneb.example.com`) and requires you to create a CNAME record for `goneb`, which targets `matrix.example.com`." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:46 -msgid "When setting, replace `example.com` with your own." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:48 -msgid "Adjusting the playbook configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:50 -msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file. Make sure to replace `ACCESS_TOKEN_FOR_GONEB_HERE` and `ACCESS_TOKEN_FOR_ANOTHER_GONEB_HERE` with the ones created [above](#obtain-an-access-token)." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:214 -msgid "Adjusting the Go-NEB URL (optional)" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:216 -msgid "By tweaking the `matrix_bot_go_neb_hostname` and `matrix_bot_go_neb_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:218 -msgid "Example additional configuration for your `vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:229 -msgid "After changing the domain, **you may need to adjust your DNS** records to point the Go-NEB domain to the Matrix server." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:231 -msgid "If you've decided to reuse the `matrix.` domain, you won't need to do any extra DNS configuration." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:233 -msgid "Extending the configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:235 -msgid "There are some additional things you may wish to configure about the bot." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:237 -msgid "Take a look at:" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:239 -msgid "`roles/custom/matrix-bot-go-neb/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:240 -msgid "`roles/custom/matrix-bot-go-neb/templates/config.yaml.j2` for the bot's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_go_neb_configuration_extension_yaml` variable" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:242 -msgid "Installing" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:244 -msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:251 -msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:253 -msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:255 -msgid "Usage" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:257 -msgid "To use the bot, invite it to any existing Matrix room (`/invite @bot.go-neb:example.com` where `example.com` is your base domain, not the `matrix.` domain). Make sure you are granted with the sufficient permission if you are not the room owner." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:259 -msgid "Basic usage is like this: `!echo hi` or `!imgur puppies` or `!giphy matrix`" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:261 -msgid "If you enabled the github_cmd service, send `!github help` to the bot in the room to see the available commands." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:263 -msgid "You can also refer to the upstream [Documentation](https://github.com/matrix-org/go-neb)." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:265 -msgid "Troubleshooting" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-go-neb.md:267 -msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-go-neb`." +#: ../../../docs/configuring-playbook-bot-go-neb.md:20 +msgid "If you still have the Go-NEB component installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bot-honoroit.pot b/i18n/translation-templates/docs/configuring-playbook-bot-honoroit.pot index f3e5e721d..e39060913 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bot-honoroit.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bot-honoroit.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -113,7 +113,7 @@ msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x f msgstr "" #: ../../../docs/configuring-playbook-bot-honoroit.md:81 -msgid "If you change the bot password (`matrix_bot_honoroit_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_honoroit_password` to let the bot know its new password." +msgid "If you change the bot password (`matrix_bot_honoroit_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_honoroit_password` to let the bot know its new password." msgstr "" #: ../../../docs/configuring-playbook-bot-honoroit.md:83 diff --git a/i18n/translation-templates/docs/configuring-playbook-bot-matrix-registration-bot.pot b/i18n/translation-templates/docs/configuring-playbook-bot-matrix-registration-bot.pot index 82ca81a49..9a8ed5a42 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bot-matrix-registration-bot.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bot-matrix-registration-bot.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-12 11:50+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,118 +16,18 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:13 -msgid "Setting up matrix-registration-bot (optional)" +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:22 +msgid "Setting up matrix-registration-bot (optional, removed)" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:15 -msgid "The playbook can install and configure [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot) for you." +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:24 +msgid "🪦 The playbook used to be able to install and configure [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot), but no longer includes this component, as it has been unmaintained." msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:17 -msgid "The bot allows you to easily **create and manage registration tokens** aka. invitation codes. It can be used for an invitation-based server, where you invite someone by sending them a registration token (tokens look like this: `rbalQ0zkaDSRQCOp`). They can register as per normal but have to provide a valid registration token in the final step of the registration process." +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:26 +msgid "Uninstalling the component manually" msgstr "" -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:19 -msgid "See the project's [documentation](https://github.com/moan0s/matrix-registration-bot/blob/master/README.md) to learn what it does and why it might be useful to you." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:21 -msgid "Adjusting the playbook configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:23 -msgid "To enable the bot, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:46 -msgid "The bot account will be created automatically." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:48 -msgid "Extending the configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:50 -msgid "There are some additional things you may wish to configure about the bot." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:52 -msgid "Take a look at:" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:54 -msgid "`roles/custom/matrix-bot-matrix-registration-bot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:55 -msgid "`roles/custom/matrix-bot-matrix-registration-bot/templates/config.yaml.j2` for the bridge's default configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:57 -msgid "Installing" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:59 -msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:66 -msgid "**Notes**:" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:68 -msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:70 -msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:72 -msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:74 -msgid "If you change the bot password (`matrix_bot_matrix_registration_bot_bot_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_matrix_registration_bot_bot_password` to let the bot know its new password." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:76 -msgid "Usage" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:78 -msgid "To use the bot, start a chat with `@bot.matrix-registration-bot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:80 -msgid "Send `help` to the bot to see the available commands." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:82 -msgid "You can also refer to the upstream [Usage documentation](https://github.com/moan0s/matrix-registration-bot#supported-commands)." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:84 -msgid "If you have any questions, or if you need help setting it up, read the [troubleshooting guide](https://github.com/moan0s/matrix-registration-bot/blob/main/docs/troubleshooting.md) or join [#matrix-registration-bot:hyteck.de](https://matrix.to/#/#matrix-registration-bot:hyteck.de)." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:86 -msgid "To clean the cache (session & encryption data) after you changed the bot's username, changed the login method from access_token to password etc… you can use:" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:92 -msgid "Troubleshooting" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:94 -msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-matrix-registration-bot`." -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:96 -msgid "Increase logging verbosity" -msgstr "" - -#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:98 -msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +#: ../../../docs/configuring-playbook-bot-matrix-registration-bot.md:28 +msgid "If you still have matrix-registration-bot installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bot-matrix-reminder-bot.pot b/i18n/translation-templates/docs/configuring-playbook-bot-matrix-reminder-bot.pot index 1ebc7031f..efb610d47 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bot-matrix-reminder-bot.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bot-matrix-reminder-bot.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -85,7 +85,7 @@ msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x f msgstr "" #: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:60 -msgid "If you change the bot password (`matrix_bot_matrix_reminder_bot_matrix_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_matrix_reminder_bot_matrix_user_password` to let the bot know its new password." +msgid "If you change the bot password (`matrix_bot_matrix_reminder_bot_matrix_user_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_matrix_reminder_bot_matrix_user_password` to let the bot know its new password." msgstr "" #: ../../../docs/configuring-playbook-bot-matrix-reminder-bot.md:62 diff --git a/i18n/translation-templates/docs/configuring-playbook-bot-maubot.pot b/i18n/translation-templates/docs/configuring-playbook-bot-maubot.pot index a9f8d01cc..b9baa3209 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bot-maubot.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bot-maubot.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -138,7 +138,7 @@ msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x f msgstr "" #: ../../../docs/configuring-playbook-bot-maubot.md:106 -msgid "If you change the bot password (`matrix_bot_maubot_initial_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_maubot_initial_password` to let the bot know its new password." +msgid "If you change the bot password (`matrix_bot_maubot_initial_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_maubot_initial_password` to let the bot know its new password." msgstr "" #: ../../../docs/configuring-playbook-bot-maubot.md:108 @@ -177,8 +177,8 @@ msgstr "" msgid "Alternatively, you can refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md). Be aware that you'd better use the **Obtain an access token via curl** method (not **Obtain an access token via Element Web**) as the latter will causes issues to your bot in encrypted rooms. Read [more](https://docs.mau.fi/maubot/usage/basic.html#creating-clients)." msgstr "" -#: ../../../docs/configuring-playbook-bot-maubot.md:123 -msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." +#: ../../../docs/configuring-playbook-bot-maubot.md:124 +msgid "Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" #: ../../../docs/configuring-playbook-bot-maubot.md:126 diff --git a/i18n/translation-templates/docs/configuring-playbook-bot-meowlnir.pot b/i18n/translation-templates/docs/configuring-playbook-bot-meowlnir.pot new file mode 100644 index 000000000..453d4c965 --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-bot-meowlnir.pot @@ -0,0 +1,581 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-08-13 05:03+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:7 +msgid "Setting up Meowlnir (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:9 +msgid "The playbook can install and configure the [Meowlnir](https://github.com/maunium/meowlnir) moderation bot for you." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:11 +msgid "See the project's [documentation](https://docs.mau.fi/meowlnir/) to learn what it does and why it might be useful to you." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:13 +msgid "Meowlnir is an alternative to [Draupnir](configuring-playbook-bot-draupnir.md) and [Mjolnir](configuring-playbook-bot-mjolnir.md). It speaks the same [policy list](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists) protocol, so it can subscribe to the same community ban lists, but it differs from them in a few ways that may matter to you:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:15 +msgid "It runs as an **appservice** and hosts **multiple bots**, each with its own management room. They live in Meowlnir's database, not its configuration file, but you still [declare them in your `vars.yml` file](#declaring-bots)." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:16 +msgid "It can **override a policy coming from a list you do not control**, via unban policies combined with the ordering of your watched lists. See [Overriding a policy from someone else's list](#overriding-a-policy-from-someone-elses-list)." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:17 +msgid "It is written in Go and is optimized for Synapse, using its database and admin APIs directly." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:19 +msgid "Meowlnir and Draupnir can run side by side, but not usefully in the *same* room: whichever bot you are migrating away from still watches the same community lists, so it re-applies the very bans your unban policies remove. Migrate room by room. See [Trialling Meowlnir alongside another bot](#trialling-meowlnir-alongside-another-bot)." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:21 +msgid "Prerequisites" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:23 +msgid "Postgres" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:25 +msgid "Meowlnir stores its state in a Postgres database. The playbook creates one for you automatically when using the integrated Postgres server." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:27 +msgid "Adjusting DNS records" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:29 +msgid "**No DNS changes are necessary.** Meowlnir is reached by the homeserver over the container network, and the paths it optionally serves publicly (abuse reports and the policy server) are routed on your existing `matrix.example.com` domain." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:31 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:33 +msgid "To enable Meowlnir, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:39 +msgid "Declaring bots" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:41 +msgid "That gets the service running, but Meowlnir does nothing until it has at least one bot. Declare the ones you want and the playbook creates them for you:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "Field" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "Required" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "Notes" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "`username`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "yes" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "The localpart of the bot's Matrix user. Awkward to change later, so choose it carefully." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "`displayname`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "The name shown in rooms. Safe to change at any time." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "`avatar_url`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "An `mxc://` URI, or `\"\"` for no avatar." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "`management_room_auto_create`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "Whether the playbook creates the bot's management room. Mutually exclusive with a non-empty `management_rooms`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "`management_rooms`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "Rooms you have created yourself, `[]` when auto-creating. See [Supplying your own management room](#supplying-your-own-management-room)." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "`initial_managers`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "no" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:0 +msgid "Who to invite to an auto-created room. Defaults to the instance-wide list below." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:67 +msgid "Usernames have to start with `meowlnir_` (the value of `matrix_bot_meowlnir_user_prefix`), so that bots fall inside the user namespace the homeserver lets Meowlnir operate." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:69 +msgid "Changing `displayname` or `avatar_url` and re-running updates the bot in place. The comparison is against Meowlnir's own record, so profile edits made directly from a Matrix client are not reverted." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:71 +msgid "Initial managers" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:73 +msgid "With `management_room_auto_create: true`, the playbook creates each bot's management room and invites its initial managers to it. You only need to accept the room invitation." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:75 +msgid "`matrix_admin` is a single playbook variable which affects all bridges and bots, so setting it is usually a better move than setting anything specific to this role — **if it is already configured in your `vars.yml` file, there is nothing to do here**. If neither `matrix_admin` nor `matrix_bot_meowlnir_initial_managers` are set, the playbook would tell you about it." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:77 +msgid "A per-bot `initial_managers` replaces the instance-wide list. Declaring it empty means nobody, which fails the run for a bot relying on `management_room_auto_create`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:79 +msgid "The list is consulted only while the room is being created. Adding a name to it later invites nobody, because the room already exists — invite and promote further moderators from inside the room instead, as described in [Who can command a bot](#who-can-command-a-bot)." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:81 +msgid "Rooms the playbook creates" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:83 +msgid "The bot creates the room with the `trusted_private_chat` preset, which gives every invitee the standing to command it. This is an additional room creator on room versions supporting [MSC4289](https://github.com/matrix-org/matrix-spec-proposals/pull/4289) (like v12) and power level 100 on older room versions. Creator status cannot be revoked subsequently." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:85 +msgid "The room's encryption follows `matrix_bot_meowlnir_config_encryption_enable`, and its name and topic come from `matrix_bot_meowlnir_management_room_name` and `matrix_bot_meowlnir_management_room_topic`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:87 +msgid "Supplying your own management room" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:89 +msgid "If you would rather own the room outright, create it yourself and declare it instead. The bot is then merely an administrator in a room you created:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:102 +msgid "An empty, invite-only room is fine. The order matters, because **each step depends on the one before it**:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:104 +msgid "Declare the room and run the playbook. Do not invite the bot beforehand." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:105 +msgid "The playbook creates the bot and tells Meowlnir about the room. Meowlnir would try to join right away, but will fail for invite-only rooms (a harmless error in the log)." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:106 +msgid "Invite the bot. It accepts the invitation, because the room is already marked as a management room for it." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:107 +msgid "Give it power level 50 or more (ideally 100), so that it can store its protected rooms and watched lists there." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:109 +msgid "Meowlnir supports several management rooms per bot, and `encrypted` is set per room. Marking a room encrypted only means something when [End-to-End Encryption support](#end-to-end-encryption-support) is switched on, which it is not by default." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:111 +msgid "Who can command a bot" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:113 +msgid "**Management room membership alone is not enough**, which is different from what [Draupnir](configuring-playbook-bot-draupnir.md) does, where everyone in the management room can issue commands." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:115 +msgid "Meowlnir decides who may drive a bot from power levels in its management room: anyone who can send the `fi.mau.meowlnir.watched_lists` state event (power level 50 by default), plus the room's creators." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:117 +msgid "Bots which are no longer declared" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:119 +msgid "The bot list (`matrix_bot_meowlnir_bots_custom`) is authoritative. Removing entries from there will make the playbook unregister them with the Meowlnir instance." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:121 +msgid "Removal only adjusts Meowlnir's own records. A removed bot's Matrix user remains activated and stays in the rooms it had joined. A removed management room leaves the room and the bot's membership in it intact - it's just that Meowlnir stops taking commands there." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:123 +msgid "Removal happens under the same `ensure-matrix-users-created` tag that creates bots. It's one Ansible tag for \"synchronizing the bots state\" (creation, changes, and removal)." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:125 +msgid "To turn removal off entirely, set `matrix_bot_meowlnir_bots_pruning_enabled: false`. As a safety measure, the playbook refuses to prune when *no* bots are declared at all; override that with `matrix_bot_meowlnir_bots_pruning_on_empty_roster_enabled: true`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:127 +msgid "Trialling Meowlnir alongside another bot" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:129 +msgid "Meowlnir has a dry-run mode in which it does everything except take moderation actions:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:136 +msgid "Dry run does not cover the [synapse-http-antispam](#enabling-synapse-http-antispam-support) integration. It suppresses actions Meowlnir takes itself (bans, server ACLs, rejecting pending invites), but the verdicts it hands back to Synapse still block invites and joins. Leave that integration off while trialling." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:138 +msgid "Do not expect dry run to preview what Meowlnir would do in rooms another policy-list bot already moderates. Meowlnir only acts on users who are *in* a room, and the other bot has already removed everyone its lists match, so the preview comes out empty. Dry run also skips the power level check described under [Protecting a room](#protecting-a-room), so it will not surface a permissions problem either." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:140 +msgid "Abuse reports" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:142 +msgid "Meowlnir can intercept the report endpoints of the client-server API, so that abuse reports are delivered to a management room. This requires integration with the reverse proxy in front of the homeserver, which the playbook sets up for you when using Traefik:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:151 +msgid "Only the `v3` report endpoints are routed to Meowlnir. Requests to the legacy `r0` endpoints continue to reach the homeserver, because Meowlnir does not serve them." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:153 +msgid "Enabling synapse-http-antispam support" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:155 +msgid "Meowlnir can block invites and joins before they happen. This requires the [synapse-http-antispam](https://github.com/maunium/synapse-http-antispam) module, which the playbook can enable for you:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:165 +msgid "The playbook wires the module up to a single consumer, so this cannot be enabled at the same time as `matrix_bot_draupnir_config_web_synapseHTTPAntispam_enabled`. The playbook fails the run if both are enabled." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:167 +msgid "With the module in place, you can also block invitations to specific users outright, which is useful for accounts that attract spam:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:174 +msgid "Such an invitation can still be let through case by case with the `!allow-invite` command." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:176 +msgid "End-to-End Encryption support" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:178 +msgid "To let Meowlnir's bots participate in encrypted rooms:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:184 +msgid "When using Synapse, the playbook turns on the experimental features this depends on (`msc2409_to_device_messages_enabled` and `msc3202_transaction_extensions`) for you." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:186 +msgid "Policy server (MSC4284)" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:188 +msgid "Meowlnir can act as a [policy server](https://github.com/matrix-org/matrix-spec-proposals/pull/4284), letting rooms ask it to vet events before they are accepted:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:194 +msgid "This exposes `/_matrix/policy` on your Matrix federation endpoint, so that other servers participating in a room can reach it." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:196 +msgid "That only stands the policy server up, though — no room is put behind it until you say so from the management room:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:202 +msgid "Given no room, `enable` applies to every protected room. Rooms which are not protected are skipped, with `Skipped ... as it is not a protected room`, so [protect a room](#protecting-a-room) before enabling it here. `!policyserver` on its own reports whether the policy server is available and prints its public key, and `!policyserver disable` reverses the change." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:204 +msgid "The playbook derives a stable signing key for you from `matrix_homeserver_generic_secret_key`. If you would rather use an independently generated one, produce it with the command below and set it as `matrix_bot_meowlnir_config_policy_server_signing_key`:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:210 +msgid "Synapse admin API access (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:212 +msgid "A few of Meowlnir's features go through Synapse's admin API, not the client-server API — suspending or deactivating users, and deleting rooms during a takedown. Those calls require the caller to be a Synapse **server admin**, which bots are not by default, so they come back as `M_FORBIDDEN` (\"You are not a server admin\"). Nothing else is affected: bans, server ACLs, protecting rooms and watching policy lists all go through the client-server API, where a sufficient power level is the only requirement." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:214 +msgid "To grant that access, point each bot at a token belonging to a server admin:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:221 +msgid "The key is the bot the token is used for; the token itself belongs to an administrator account, not to the bot." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:223 +msgid "If you have more than one management room, note that room bans are only processed in the one named by `matrix_bot_meowlnir_config_meowlnir_room_ban_room`, and ignored elsewhere." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:225 +msgid "Where the token comes from depends on how your homeserver authenticates. Ordinarily you [obtain an access token](obtaining-access-tokens.md) for an account which is a Synapse server admin. When [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) is enabled, Synapse no longer decides who is an admin, so the token has to be issued by MAS with admin privileges:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:231 +msgid "Note that bot users are created by the appservice and are not known to Matrix Authentication Service, so the token cannot be issued for the bot itself — use an administrator account." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:233 +msgid "Access to the Synapse database (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:235 +msgid "Some room takedown features rely on Meowlnir reading room IDs directly from the Synapse database. Upstream expects a user with read-only permissions, which the playbook does not create. Enabling the integration below hands Meowlnir the same credentials Synapse itself uses, which also grant write access:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:241 +msgid "If you would rather not do that, create a read-only Postgres user yourself and point Meowlnir at it with `matrix_bot_meowlnir_synapse_database_uri`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:243 +msgid "Adopting an existing Meowlnir installation" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:245 +msgid "If you already run Meowlnir outside the playbook and want to bring it under this role, two things need attention before the first run." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:247 +msgid "Your bots exist in Meowlnir's database but not in your `vars.yml` file, and [pruning](#bots-which-are-no-longer-declared) is on by default, so the first run would remove them. Declare them in `matrix_bot_meowlnir_bots_custom` — with `management_room_auto_create: false` and their existing rooms under `management_rooms` — or set `matrix_bot_meowlnir_bots_pruning_enabled: false`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:249 +msgid "If the installation uses encryption, also copy the `pickle_key` from its old configuration file into `matrix_bot_meowlnir_config_encryption_pickle_key`. The crypto store cannot be read with a different key than it was written with, so leaving the playbook's default in place costs your bots their existing encryption sessions." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:251 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:253 +msgid "There are some additional things you may wish to configure about the bot." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:255 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:257 +msgid "`roles/custom/matrix-bot-meowlnir/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_meowlnir_configuration_extension_yaml` variable" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:260 +msgid "Do not set any of Meowlnir's secrets to the literal value `generate`. Meowlnir re-runs its configuration upgrader on every start, so a `generate` placeholder would produce a brand new secret on every restart. The playbook derives stable values for you, and fails the run if it finds a `generate` placeholder." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:262 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:264 +msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:270 +msgid "With `management_room_auto_create`, you then have an invitation waiting for you — accept it and start sending commands. If you supplied the management room yourself, carry on from step 3 of [Supplying your own management room](#supplying-your-own-management-room): invite the bot, then give it power level 50 or more." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:272 +msgid "**Notes**:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:274 +msgid "The `ensure-matrix-users-created` tag is what creates the bots declared in `matrix_bot_meowlnir_bots_custom`, registers their management rooms, and removes the ones you no longer declare. It deliberately does not run as part of `setup-all`, so that installing onto a server whose database you are about to restore from a backup does not write anything." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:276 +msgid "Re-running is safe and idempotent, so adding a bot later is a matter of extending the list and running the same command again." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:278 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:280 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:282 +msgid "You can refer to the upstream [documentation](https://docs.mau.fi/meowlnir/) for a more detailed usage guide." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:284 +msgid "Below is a **non-exhaustive quick-start guide** for the impatient." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:286 +msgid "Inspecting and driving Meowlnir directly" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:288 +msgid "The playbook drives Meowlnir's management API for you based on `matrix_bot_meowlnir_bots_custom`, which is the recommended way. For anything it does not cover, helper scripts are installed under `/matrix/meowlnir/bin`, which find the management secret and reach the API inside the container:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:301 +msgid "`meowlnir-create-management-room` prints the new room's ID, which you then register with `meowlnir-api PUT /_meowlnir/v1/management_room/`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:303 +msgid "See the upstream [bot creation documentation](https://docs.mau.fi/meowlnir/bot-create.html) for the full set of endpoints. Bear in mind that bots you create this way are not declared in your `vars.yml` file, so the next playbook run will remove them again (see [Bots which are no longer declared](#bots-which-are-no-longer-declared))." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:305 +msgid "If you have enabled encryption, each bot also needs verifying once. That step is left manual because it returns a recovery key you need to store somewhere safe:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:311 +msgid "Protecting a room" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:313 +msgid "Invite the bot to a room, give it a power level high enough to act (see below), and then tell it to protect the room by sending this command to its management room:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:319 +msgid "Meowlnir refuses to protect a room unless its power level reaches that room's own `ban` and `redact` levels (50 in a default room). That is only enough for user bans, though: writing `m.room.server_acl` usually requires 100, and without it the server rules in your watched lists have no effect — which is most of what a list like [CME](https://matrix.to/#/%23community-moderation-effort-bl:neko.dev) carries. **Give the bot power level 100** unless you only care about user bans." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:321 +msgid "Set the power level *before* protecting the room. Meowlnir re-sends server ACLs when it starts and when a watched list changes, but not when its own power level goes up subsequently, so raising it afterwards leaves the room without ACLs until you restart the bot (`systemctl restart matrix-bot-meowlnir` or via the playbook's Ansible `start` tag)." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:323 +msgid "Subscribing to a policy list" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:325 +msgid "Policy lists are maintained in Matrix rooms. Popular public ones are:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:327 +msgid "`#community-moderation-effort-bl:neko.dev`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:328 +msgid "`#huginn-muninn-active-threats:feline.support`" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:330 +msgid "Subscribe to one by sending the following command to the management room:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:336 +msgid "The last argument is a shortcode, which you use to refer to the list in later commands." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:338 +msgid "Overriding a policy from someone else's list" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:340 +msgid "This is the main capability Meowlnir has that Draupnir does not." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:342 +msgid "When several watched lists carry a policy for the same user, **the first match wins**, and \"first\" means the order in which the lists are watched. So to be able to override a community list's ban, your own list has to come before it." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:344 +msgid "`!lists subscribe` appends, which makes subscription order the precedence order. Subscribe to your own list first, and to community lists afterwards:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:352 +msgid "If you have already subscribed in the wrong order, fixing it means editing the `fi.mau.meowlnir.watched_lists` state event in the management room by hand. Newer Meowlnir releases (than `v0.2606.0`) add `!lists subscribe … --insert-before `, which will make reordering a single command." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:354 +msgid "You can then publish an unban policy into your own list, which takes precedence over the community list's ban:" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:361 +msgid "Unlike `!ban`, the `!add-unban` command does not treat its reason as a trailing argument, so a reason containing spaces is discarded. Use a single word (or hyphenate) until that is fixed upstream." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:364 +msgid "An unban policy stops a ban from being **re-applied**; it does not undo one that is already in place unless Meowlnir applied it itself and still has it on record. A ban placed by a human moderator, or by the Draupnir or Mjolnir you are migrating away from, stays. Unban such a user once by hand — from then on the policy keeps them unbanned, while you remain subscribed to the list that banned them." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:366 +msgid "Use `!match @alice:example.com` to see which policies currently apply to a user and which list each came from." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:369 +msgid "Unban policies use a Meowlnir-specific recommendation (`fi.mau.meowlnir.unban`) which is not part of the Matrix specification. If you publish your policy list for other people to subscribe to, subscribers running Draupnir or Mjolnir will ignore your unban policies." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:371 +msgid "There is also a blunter, server-wide escape hatch for policies that are too wide to tolerate at all — `matrix_bot_meowlnir_config_meowlnir_hacky_rule_filter_custom`, which makes Meowlnir ignore any policy matching the listed entities." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:373 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:375 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by running a command like `journalctl -fu matrix-bot-meowlnir`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:377 +msgid "If bots appear to do nothing, check that they have an Administrator power level in the rooms they are meant to protect, and that the room has been added with `!rooms protect`." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:379 +msgid "If commands in a management room get no reply at all, check the bot's power level *there* too — it needs at least 50 to record its own configuration." +msgstr "" + +#: ../../../docs/configuring-playbook-bot-meowlnir.md:381 +msgid "A bare `!lists` returns nothing in a management room which has never had a policy list. That is an upstream bug and it clears as soon as you subscribe to one; `!lists subscribe` works from the start." +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bot-mjolnir.pot b/i18n/translation-templates/docs/configuring-playbook-bot-mjolnir.pot index a270d871b..bb903e444 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bot-mjolnir.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bot-mjolnir.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-13 05:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -29,251 +29,255 @@ msgid "See the project's [documentation](https://github.com/matrix-org/mjolnir/b msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:18 -msgid "Prerequisites" +msgid "**Note**: you can also use the [Draupnir](configuring-playbook-bot-draupnir.md) or [Meowlnir](configuring-playbook-bot-meowlnir.md) bots, which speak the same [policy list](https://the-draupnir-project.github.io/draupnir-documentation/concepts/policy-lists) protocol." msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:20 -msgid "Register the bot account" +msgid "Prerequisites" msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:22 -msgid "The playbook does not automatically create users for you. You **need to register the bot user manually** before setting up the bot." +msgid "Register the bot account" msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:24 -msgid "Generate a strong password for the bot. You can create one with a command like `pwgen -s 64 1`." +msgid "The playbook does not automatically create users for you. You **need to register the bot user manually** before setting up the bot." msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:26 -msgid "You can use the playbook to [register a new user](registering-users.md):" +msgid "Generate a strong password for the bot. You can create one with a command like `pwgen -s 64 1`." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:32 -msgid "If you would like Mjolnir to be able to deactivate users, move aliases, shutdown rooms, etc then it must be a server admin so you need to change `admin=no` to `admin=yes` in the command above." +#: ../../../docs/configuring-playbook-bot-mjolnir.md:28 +msgid "You can use the playbook to [register a new user](registering-users.md):" msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:34 -msgid "Obtain an access token" +msgid "If you would like Mjolnir to be able to deactivate users, move aliases, shutdown rooms, etc then it must be a server admin so you need to change `admin=no` to `admin=yes` in the command above." msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:36 -msgid "The bot requires an access token to be able to connect to your homeserver. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." +msgid "Obtain an access token" msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:38 -#: ../../../docs/configuring-playbook-bot-mjolnir.md:63 -msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." +msgid "The bot requires an access token to be able to connect to your homeserver. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:41 -msgid "Make sure the account is free from rate limiting" +#: ../../../docs/configuring-playbook-bot-mjolnir.md:66 +msgid "Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:43 -msgid "If your homeserver's implementation is Synapse, you will need to prevent it from rate limiting the bot's account. **This is a required step. If you do not configure it, Mjolnir will crash.**" +msgid "Make sure the account is free from rate limiting" msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:45 -msgid "This can be done using Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users). They can be accessed both externally and internally." +msgid "If your homeserver's implementation is Synapse, you will need to prevent it from rate limiting the bot's account. **This is a required step. If you do not configure it, Mjolnir will crash.**" msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:47 -msgid "**Note**: access to the APIs is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, doing so is not recommended for additional security. See [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints)." +msgid "This can be done using Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users). They can be accessed both externally and internally." msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:49 -msgid "The APIs can also be accessed via [Synapse Admin](https://github.com/etkecc/synapse-admin), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md)." +msgid "**Note**: access to the APIs is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, doing so is not recommended for additional security. See [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints)." msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:51 -msgid "Add the configuration" +msgid "The APIs can also be accessed via [Ketesa](https://github.com/etkecc/ketesa), a web UI tool you can use to administrate users, rooms, media, etc. on your Matrix server. The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md)." msgstr "" #: ../../../docs/configuring-playbook-bot-mjolnir.md:53 +msgid "Add the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bot-mjolnir.md:55 msgid "To expose the APIs publicly, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:59 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:61 msgid "Obtain an access token for admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:61 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:63 msgid "Manual access to Synapse's Admin APIs requires an access token for a homeserver admin account. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md). If you have made Mjolnir an admin, you can just use the Mjolnir token." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:66 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:68 msgid "Run the `curl` command" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:68 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:70 msgid "To disable rate limiting, run the following command on systems that ship curl. Before running it, make sure to replace:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:70 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:72 msgid "`ADMIN_ACCESS_TOKEN_HERE` with the access token of the admin account" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:71 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:73 msgid "`example.com` with your base domain" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:72 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:74 msgid "`@bot.mjolnir:example.com` with the MXID of your Mjolnir bot user" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:78 -#: ../../../docs/configuring-playbook-bot-mjolnir.md:195 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:80 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:197 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:79 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:81 msgid "This does not work on outdated Windows 10 as curl is not available there." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:80 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:82 msgid "Even if the APIs are not exposed to the internet, you should still be able to run the command on the homeserver locally." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:82 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:84 msgid "Create a management room" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:84 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:86 msgid "Using your own account, create a new invite only room that you will use to manage the bot. This is the room where you will see the status of the bot and where you will send commands to the bot, such as the command to ban a user from another room." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:86 -msgid "[!WARNING] Anyone in this room can control the bot so it is important that you only invite trusted users to this room." +#: ../../../docs/configuring-playbook-bot-mjolnir.md:89 +msgid "Anyone in this room can control the bot so it is important that you only invite trusted users to this room." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:89 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:91 msgid "It is possible to make the management room encrypted (E2EE). If doing so, then you MUST enable and use Pantalaimon (see [below](#configuration-with-e2ee-support))." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:91 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:93 msgid "Once you have created the room you need to copy the room ID so you can specify it on your `vars.yml` file. In Element Web you can check the ID by going to the room's settings and clicking \"Advanced\". The room ID will look something like `!qporfwt:example.com`." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:93 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:95 msgid "Finally invite the `@bot.mjolnir:example.com` account you created earlier into the room." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:95 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:97 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:97 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:99 msgid "To enable the bot, add the following configuration to your `vars.yml` file. Make sure to replace `MANAGEMENT_ROOM_ID_HERE` with the one of the room which you have created just now." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:106 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:108 msgid "End-to-End Encryption support" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:108 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:110 msgid "Decide whether you want Mjolnir to be capable of operating in end-to-end encrypted (E2EE) rooms. This includes the management room and the moderated rooms." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:110 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:112 msgid "To support E2EE, Mjolnir needs to [use Pantalaimon](configuring-playbook-pantalaimon.md)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:112 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:114 msgid "Configuration with E2EE support" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:114 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:116 msgid "When using Pantalaimon, Mjolnir will log in to its bot account itself through Pantalaimon, so configure its username and password." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:116 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:118 msgid "Add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:130 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:132 msgid "The playbook's `group_vars` will configure other required settings. If using this role separately without the playbook, you also need to configure the two URLs that Mjolnir uses to reach the homeserver, one through Pantalaimon and one \"raw\". This example is taken from the playbook's `group_vars`:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:142 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:144 msgid "Configuration without E2EE support" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:144 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:146 msgid "When NOT using Pantalaimon, Mjolnir does not log in by itself and you must give it an access token for its bot account." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:146 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:148 msgid "Add the following configuration to your `vars.yml` file. Make sure to replace `ACCESS_TOKEN_HERE` with the one created [above](#obtain-an-access-token)." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:152 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:154 msgid "Adding Mjolnir synapse antispam module (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:154 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:156 msgid "To enable Mjolnir synapse antispam module, add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:164 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:166 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:166 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:168 msgid "There are some additional things you may wish to configure about the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:168 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:170 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:170 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:172 msgid "`roles/custom/matrix-bot-mjolnir/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bot_mjolnir_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:172 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:174 msgid "For example, to change Mjolnir's `recordIgnoredInvites` option to `true`, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:186 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:188 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:188 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:190 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:197 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:199 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:199 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:201 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:201 -msgid "If you change the Pantalaimon's password (`matrix_bot_mjolnir_pantalaimon_password` in your `vars.yml` file) subsequently, its credentials on the homeserver won't be updated automatically. If you'd like to change the password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_mjolnir_pantalaimon_password` to let Pantalaimon know its new password." +#: ../../../docs/configuring-playbook-bot-mjolnir.md:203 +msgid "If you change the Pantalaimon's password (`matrix_bot_mjolnir_pantalaimon_password` in your `vars.yml` file) subsequently, its credentials on the homeserver won't be updated automatically. If you'd like to change the password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bot_mjolnir_pantalaimon_password` to let Pantalaimon know its new password." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:203 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:205 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:205 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:207 msgid "You can refer to the upstream [documentation](https://github.com/matrix-org/mjolnir) for additional ways to use and configure Mjolnir. Check out their [quickstart guide](https://github.com/matrix-org/mjolnir#quickstart-guide) for some basic commands you can give to the bot." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:207 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:209 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:209 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:211 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-bot-mjolnir`." msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:211 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:213 msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bot-mjolnir.md:213 +#: ../../../docs/configuring-playbook-bot-mjolnir.md:215 msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-discord.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-discord.pot index 350509cdb..2bc306f62 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-discord.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-discord.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -73,7 +73,7 @@ msgid "`roles/custom/matrix-bridge-appservice-discord/defaults/main.yml` for som msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-discord.md:47 -msgid "`roles/custom/matrix-bridge-appservice-discord/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_appservice_discord_configuration_extension_yaml` variable" +msgid "`roles/custom/matrix-bridge-appservice-discord/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_appservice_discord_configuration_extension_yaml` variable" msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-discord.md:49 @@ -150,7 +150,7 @@ msgid "To get started with Portal Bridging:" msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-discord.md:101 -msgid "To invite the bot to Discord, retrieve the invite link from the `{{ matrix_appservice_discord_config_path }}/invite_link` file on the server (this defaults to `/matrix/appservice-discord/config/invite_link`). You need to peek at the file on the server via SSH, etc., because it's not available via HTTP(S)." +msgid "To invite the bot to Discord, retrieve the invite link from the `{{ matrix_bridge_appservice_discord_config_path }}/invite_link` file on the server (this defaults to `/matrix/appservice-discord/config/invite_link`). You need to peek at the file on the server via SSH, etc., because it's not available via HTTP(S)." msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-discord.md:102 diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-irc.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-irc.pot index 1cf6a7212..6d7984ff5 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-irc.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-irc.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -57,7 +57,7 @@ msgid "`roles/custom/matrix-bridge-appservice-irc/defaults/main.yml` for some va msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-irc.md:79 -msgid "`roles/custom/matrix-bridge-appservice-irc/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_appservice_irc_configuration_extension_yaml` variable" +msgid "`roles/custom/matrix-bridge-appservice-irc/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_appservice_irc_configuration_extension_yaml` variable" msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-irc.md:81 diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-kakaotalk.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-kakaotalk.pot index 6d243690e..d70b5846d 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-kakaotalk.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-kakaotalk.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,109 +17,21 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:10 -msgid "Setting up Appservice Kakaotalk bridging (optional)" +msgid "Setting up Appservice Kakaotalk bridging (optional, removed)" msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:12 -msgid "The playbook can install and configure [matrix-appservice-kakaotalk](https://src.miscworks.net/fair/matrix-appservice-kakaotalk) for you, for bridging to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG). This bridge is based on [node-kakao](https://github.com/storycraft/node-kakao) (now unmaintained) and some [mautrix-facebook](https://github.com/mautrix/facebook) code." +msgid "🪦 The playbook used to be able to install and configure [matrix-appservice-kakaotalk](https://src.miscworks.net/fair/matrix-appservice-kakaotalk) (a bridge to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG)), but no longer includes this component." msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:14 -msgid "See the project's [documentation](https://src.miscworks.net/fair/matrix-appservice-kakaotalk/src/branch/master/README.md) to learn what it does and why it might be useful to you." +msgid "The bridge could only be installed by self-building its source code, and its upstream repository has become unreachable, which makes installation impossible. The bridge was also based on the now-unmaintained [node-kakao](https://github.com/storycraft/node-kakao) library, and there have been reports that using it may get your Kakaotalk account banned." msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:16 -msgid "[!WARNING] There have been recent reports (~2022-09-16) that **using this bridge may get your account banned**." +msgid "Uninstalling the component manually" msgstr "" -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:19 -msgid "Prerequisite (optional)" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:21 -msgid "Enable Shared Secret Auth" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:23 -msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) for this playbook." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:25 -msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:27 -msgid "**Note**: double puppeting with the Shared Secret Auth works at the time of writing, but is deprecated and will stop working in the future." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:29 -msgid "Adjusting the playbook configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:31 -msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:37 -msgid "Extending the configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:39 -msgid "There are some additional things you may wish to configure about the bridge." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:41 -msgid "Take a look at:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:43 -msgid "`roles/custom/matrix-bridge-appservice-kakaotalk/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:44 -msgid "`roles/custom/matrix-bridge-appservice-kakaotalk/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_appservice_kakaotalk_configuration_extension_yaml` variable" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:46 -msgid "Installing" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:48 -msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:55 -msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:57 -msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:59 -msgid "Usage" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:61 -msgid "To use the bridge, you need to start a chat with `@kakaotalkbot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:63 -msgid "You then need to send `login --save EMAIL_OR_PHONE_NUMBER` to the bridge bot to enable bridging for your Kakaotalk account. The `--save` flag may be omitted, if you'd rather not save your password." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:65 -msgid "Troubleshooting" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:67 -msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-appservice-kakaotalk`." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:69 -msgid "Increase logging verbosity" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:71 -msgid "The default logging level for this component is `WARNING`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +#: ../../../docs/configuring-playbook-bridge-appservice-kakaotalk.md:18 +msgid "If you still have matrix-appservice-kakaotalk installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-slack.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-slack.pot index 1079798b2..151bc3b98 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-slack.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-appservice-slack.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-15 09:10+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,242 +16,22 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:12 -msgid "Setting up Appservice Slack bridging (optional)" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:14 -msgid "**Notes**:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:15 -msgid "Bridging to [Slack](https://slack.com) can also happen via the [mautrix-slack](configuring-playbook-bridge-mautrix-slack.md) bridge supported by the playbook." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:16 -msgid "Currently (as of November, 2024) **this component is not available for new installation unless you have already created a classic Slack application** (which the bridge makes use of in order to enable bridging between Slack and Matrix), because the creation of classic Slack applications has been discontinued since June 4 2024. The author of the bridge claims [here](https://github.com/matrix-org/matrix-appservice-slack/issues/789#issuecomment-2172947787) that he plans to support the modern Slack application and until then \"the best (and only) option for new installations is to use the webhook bridging\"." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:18 -msgid "The playbook can install and configure [matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) for you." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:20 -msgid "See the project's [documentation](https://github.com/matrix-org/matrix-appservice-slack/blob/master/README.md) to learn what it does and why it might be useful to you." -msgstr "" - #: ../../../docs/configuring-playbook-bridge-appservice-slack.md:22 -msgid "Prerequisites" +msgid "Setting up Appservice Slack bridging (optional, removed)" msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-slack.md:24 -msgid "Create a Classic Slack App" +msgid "🪦 The playbook used to be able to install and configure [matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack), but no longer includes this component, as it had been unavailable for new installation since 2024, and was finally abandoned because the public Matrix.org Slack bridge has been decommissioned on January 14th, 2026." msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-slack.md:26 -msgid "First, you need to create a Classic Slack App [here](https://api.slack.com/apps?new_classic_app=1)." +msgid "**Note**: Bridging to [Slack](https://slack.com) can also happen via the [mautrix-slack](configuring-playbook-bridge-mautrix-slack.md) bridge supported by the playbook." msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-slack.md:28 -msgid "Name the app \"matrixbot\" (or anything else you'll remember). Select the team/workspace this app will belong to. Click on bot users and add a new bot user. We will use this account to bridge the the rooms." +msgid "Uninstalling the component manually" msgstr "" #: ../../../docs/configuring-playbook-bridge-appservice-slack.md:30 -msgid "Then, click on Event Subscriptions and enable them and use the request url: `https://matrix.example.com/appservice-slack`." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:32 -msgid "Add the following events as `Bot User Events` and save:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:34 -msgid "team_domain_change" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:35 -msgid "message.channels" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:36 -msgid "message.groups (if you want to bridge private channels)" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:37 -msgid "reaction_added" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:38 -msgid "reaction_removed" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:40 -msgid "Next, click on \"OAuth & Permissions\" and add the following scopes:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:42 -msgid "chat:write:bot" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:43 -msgid "users:read" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:44 -msgid "reactions:write" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:45 -msgid "files:write:user (if you want to bridge files)" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:47 -msgid "**Note**: In order to make Slack files visible to Matrix users, this bridge will make Slack files visible to anyone with the url (including files in private channels). This is different than the current behavior in Slack, which only allows authenticated access to media posted in private channels. See MSC701 for details." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:49 -msgid "Click on \"Install App\" and \"Install App to Workspace\". Note the access tokens shown. You will need the Bot User OAuth Access Token and if you want to bridge files, the OAuth Access Token whenever you link a room." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:51 -msgid "Create an administration control room on Matrix" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:53 -msgid "Create a new Matrix room to act as the administration control room." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:55 -msgid "Note its internal room ID. This can be done in Element Web by sending a message, opening the options for that message and choosing \"view source\". The room ID will be displayed near the top." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:57 -msgid "Adjusting the playbook configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:59 -msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:75 -msgid "Extending the configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:77 -msgid "There are some additional things you may wish to configure about the bridge." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:79 -msgid "Take a look at:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:81 -msgid "`roles/custom/matrix-bridge-appservice-slack/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:82 -msgid "`roles/custom/matrix-bridge-appservice-slack/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_appservice_slack_configuration_extension_yaml` variable" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:84 -msgid "For example, to change the bot's username from `slackbot`, add the following configuration to your `vars.yml` file. Replace `examplebot` with your own." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:91 -msgid "Installing" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:93 -msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:100 -msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:102 -msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:104 -msgid "Usage" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:106 -msgid "To use the bridge, you need to send `/invite @slackbot:example.com` to invite the bridge bot user into the admin room." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:108 -msgid "If Team Sync is not enabled, for each channel you would like to bridge, perform the following steps:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:110 -msgid "Create a Matrix room in the usual manner for your client. Take a note of its Matrix room ID — it will look something like `!qporfwt:example.com`." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:111 -msgid "Invite the bot user to both the Slack and Matrix channels you would like to bridge using `/invite @matrixbot` for Slack and `/invite @slackbot:example.com` for Matrix." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:112 -msgid "Determine the \"channel ID\" that Slack uses to identify the channel. You can see it when you open a given Slack channel in a browser. The URL reads like this: `https://app.slack.com/client/XXX//details/`." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:113 -msgid "Issue a link command in the administration control room with these collected values as arguments:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:115 -msgid "with file bridging:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:121 -msgid "without file bridging:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:127 -msgid "These arguments can be shortened to single-letter forms:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:133 -msgid "Unlinking" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:135 -msgid "Channels can be unlinked again by sending this:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:141 -msgid "Unlinking doesn't only disconnect the bridge, but also makes the slackbot leave the bridged Matrix room. So in case you want to re-link later, don't forget to re-invite the slackbot into this room again." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:143 -msgid "Troubleshooting" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:145 -msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-appservice-slack`." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:147 -msgid "Linking: \"Room is now pending-name\"" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:149 -msgid "This typically means that you haven't used the correct Slack channel ID. Unlink the room and recheck 'Determine the \"channel ID\"' from above." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:151 -msgid "Messages work from Matrix to Slack, but not the other way around" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:153 -msgid "Check the logs, and if you find the message like below, unlink your room, reinvite the bot and re-link it again." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:155 -msgid "`WARN SlackEventHandler Ignoring message from unrecognised Slack channel ID : %s (%s) `" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-appservice-slack.md:157 -msgid "This may particularly hit you, if you tried to unsuccessfully link your room multiple times without unlinking it after each failed attempt." +msgid "If you still have matrix-appservice-slack installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-beeper-line.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-beeper-line.pot new file mode 100644 index 000000000..8eb1201d1 --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-beeper-line.pot @@ -0,0 +1,153 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-08-01 17:14+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:7 +msgid "Setting up Beeper LINE bridging (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:9 +msgid "Refer to the common guide for configuring mautrix bridges: [Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:11 +msgid "The playbook can install and configure [beeper-line](https://github.com/beeper/line) for you, for bridging to [LINE](https://line.me/)." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:13 +msgid "See the project's [documentation](https://github.com/beeper/line/blob/main/README.md) to learn what it does and which features it supports." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:15 +msgid "Prerequisites" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:17 +msgid "Prepare your LINE account" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:19 +msgid "The bridge logs in with the email address configured in your LINE account. If your account does not have an email address, set one in the LINE mobile app under **Settings** → **Account** → **Email address** before trying to log in." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:21 +msgid "The bridge identifies itself to LINE as a Chrome Extension client. LINE only permits one active Chrome Extension session, so the bridge and the real LINE Chrome Extension cannot be used at the same time. Logging in with either one invalidates the other session." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:23 +msgid "Enable Appservice Double Puppet (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:25 +msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) for this playbook." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:27 +msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the common mautrix bridge guide for details." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:29 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:31 +msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:37 +msgid "Using another container image" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:39 +msgid "Upstream does not publish container images publicly, as its CI only pushes them to Beeper's private registry. The playbook therefore uses [`docker.io/crispyduck/beeper-line`](https://hub.docker.com/r/crispyduck/beeper-line) by default, which is a community-maintained image built from the upstream source." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:41 +msgid "That image is only available for the amd64 architecture. On other architectures, the playbook self-builds the image from source automatically." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:43 +msgid "To use an image that you have built and published elsewhere, override the complete image name:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:50 +msgid "The role can also build the bridge directly from a Git repository on the Matrix server:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:58 +msgid "Self-building requires more time and resources on the server than pulling a prebuilt image." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:60 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:62 +msgid "There are additional things you may wish to configure about the bridge." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:64 +msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the common mautrix bridge guide for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [relay mode](configuring-playbook-bridge-mautrix-bridges.md#enable-relay-mode-optional), and the [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional)." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:66 +msgid "When following the common guide, replace `_mautrix_SERVICENAME_` in variable names with `_beeper_line_`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:68 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:70 +msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:76 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:78 +msgid "`just install-all` is useful for maintaining your setup quickly when its components remain unchanged. If you adjust your `vars.yml` to remove other components, run `just setup-all` so those components are uninstalled." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:80 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:82 +msgid "To use the bridge, start a chat with `@linebot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:84 +msgid "Send `login` and enter your LINE email address and password when prompted. The bridge then shows you a PIN code, which you need to enter into the LINE app on your mobile device to approve the new session." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:86 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:88 +msgid "As with all other services, you can find the logs in systemd-journald by logging in to the server with SSH and running:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:94 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-line.md:96 +msgid "The default logging level for this component is `warn`. To increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-beeper-linkedin.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-beeper-linkedin.pot index a921f29be..6f087c930 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-beeper-linkedin.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-beeper-linkedin.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-01 17:14+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,109 +17,113 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:11 -msgid "Setting up Beeper Linkedin bridging (optional)" +msgid "Setting up Beeper Linkedin bridging (optional, unmaintained)" msgstr "" #: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:13 -msgid "The playbook can install and configure [beeper-linkedin](https://github.com/beeper/linkedin) for you, for bridging to [LinkedIn](https://www.linkedin.com/) Messaging. This bridge is based on the mautrix-python framework and can be configured in a similar way to the mautrix bridges." +msgid "**Note**: this bridge is unmaintained. Its [upstream repository](https://github.com/beeper/linkedin) has been archived and has not seen a change since March 2025. For bridging to LinkedIn, consider using the [mautrix-linkedin](configuring-playbook-bridge-mautrix-linkedin.md) bridge instead, which is actively maintained and also supported by the playbook." msgstr "" #: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:15 -msgid "See the project's [documentation](https://github.com/beeper/linkedin/blob/master/README.md) to learn what it does and why it might be useful to you." +msgid "The playbook can install and configure [beeper-linkedin](https://github.com/beeper/linkedin) for you, for bridging to [LinkedIn](https://www.linkedin.com/) Messaging. This bridge is based on the mautrix-python framework and can be configured in a similar way to the mautrix bridges." msgstr "" #: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:17 -msgid "Prerequisite" +msgid "See the project's [documentation](https://github.com/beeper/linkedin/blob/master/README.md) to learn what it does and why it might be useful to you." msgstr "" #: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:19 -msgid "Enable Appservice Double Puppet or Shared Secret Auth (optional)" +msgid "Prerequisite" msgstr "" #: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:21 -msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) or [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) service for this playbook." +msgid "Enable Appservice Double Puppet or Shared Secret Auth (optional)" msgstr "" #: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:23 -msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting." +msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) or [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) service for this playbook." msgstr "" #: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:25 -msgid "**Note**: double puppeting with the Shared Secret Auth works at the time of writing, but is deprecated and will stop working in the future." +msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting." msgstr "" #: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:27 -msgid "Adjusting the playbook configuration" +msgid "**Note**: double puppeting with the Shared Secret Auth works at the time of writing, but is deprecated and will stop working in the future." msgstr "" #: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:29 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:31 msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:35 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:37 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:37 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:39 msgid "There are some additional things you may wish to configure about the bridge." msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:39 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:41 msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [relay mode](configuring-playbook-bridge-mautrix-bridges.md#enable-relay-mode-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc." msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:41 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:43 msgid "**Note**: when following the guide to configure the bridge, make sure to replace `_mautrix_SERVICENAME_` in the variable names with `_beeper_linkedin_`." msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:43 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:45 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:45 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:47 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:52 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:54 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:54 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:56 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:56 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:58 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:58 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:60 msgid "To use the bridge, you need to start a chat with `@linkedinbot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:60 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:62 msgid "You then need to send `login YOUR_LINKEDIN_EMAIL_ADDRESS` to the bridge bot to enable bridging for your LinkedIn account." msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:62 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:64 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:64 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:66 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-beeper-linkedin`." msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:66 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:68 msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:68 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:70 msgid "The default logging level for this component is `WARNING`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:74 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:76 msgid "Bridge asking for 2FA even if you don't have 2FA enabled" msgstr "" -#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:76 +#: ../../../docs/configuring-playbook-bridge-beeper-linkedin.md:78 msgid "If you don't have 2FA enabled and are logging in from a strange IP for the first time, LinkedIn will send an email with a one-time code. You can use this code to authorize the bridge session. In my experience, once the IP is authorized, you will not be asked again." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-heisenbridge.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-heisenbridge.pot index b097927be..fde0fccd6 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-heisenbridge.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-heisenbridge.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -57,7 +57,7 @@ msgid "Adjusting the Heisenbridge URL (optional)" msgstr "" #: ../../../docs/configuring-playbook-bridge-heisenbridge.md:40 -msgid "By tweaking the `matrix_heisenbridge_hostname` and `matrix_heisenbridge_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." +msgid "By tweaking the `matrix_bridge_heisenbridge_hostname` and `matrix_bridge_heisenbridge_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." msgstr "" #: ../../../docs/configuring-playbook-bridge-heisenbridge.md:42 diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-hookshot.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-hookshot.pot index 5fe26bdfd..c6b3fcef6 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-hookshot.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-hookshot.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-13 05:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -56,95 +56,99 @@ msgstr "" msgid "Add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file. Make sure to replace `GITHUB_PRIVATE_KEY_HERE` with the one created [above](#download-github-app-private-key)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:43 -msgid "For each of the services (GitHub, GitLab, Jira, Figma, and generic webhooks) fill in the respective variables `matrix_hookshot_service_*` listed in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml) as required." +#: ../../../docs/configuring-playbook-bridge-hookshot.md:44 +msgid "End-to-bridge encryption requires the homeserver to support (and have enabled) [MSC2409](https://github.com/matrix-org/matrix-spec-proposals/pull/2409) and [MSC3202](https://github.com/matrix-org/matrix-spec-proposals/pull/3202). When using Synapse, the playbook turns on the experimental features this depends on (`msc2409_to_device_messages_enabled` and `msc3202_transaction_extensions`) for you. On other homeserver implementations, you need to arrange for this yourself." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:45 -msgid "Take special note of the `matrix_hookshot_*_enabled` variables. Services that need no further configuration are enabled by default (GitLab and generic webhooks), while you must first add the required configuration and enable the others (GitHub, Jira, and Figma)." +#: ../../../docs/configuring-playbook-bridge-hookshot.md:46 +msgid "For each of the services (GitHub, GitLab, Jira, Figma, and generic webhooks) fill in the respective variables `matrix_bridge_hookshot_service_*` listed in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml) as required." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:47 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:48 +msgid "Take special note of the `matrix_bridge_hookshot_*_enabled` variables. Services that need no further configuration are enabled by default (GitLab and generic webhooks), while you must first add the required configuration and enable the others (GitHub, Jira, and Figma)." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-hookshot.md:50 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:49 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:52 msgid "There are some additional things you may wish to configure about the bridge." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:51 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:54 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:53 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:56 msgid "`roles/custom/matrix-bridge-hookshot/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:54 -msgid "`roles/custom/matrix-bridge-hookshot/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_hookshot_configuration_extension_yaml` and `matrix_hookshot_registration_extension_yaml` variables" +#: ../../../docs/configuring-playbook-bridge-hookshot.md:57 +msgid "`roles/custom/matrix-bridge-hookshot/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_hookshot_configuration_extension_yaml` and `matrix_bridge_hookshot_registration_extension_yaml` variables" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:56 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:59 msgid "Refer the [official instructions](https://matrix-org.github.io/matrix-hookshot/latest/setup.html) and the comments in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml) to learn what the individual options do." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:58 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:61 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:60 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:63 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:67 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:70 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-service hookshot` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:69 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:72 msgid "`just install-service hookshot` is useful for maintaining your setup quickly when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note `just setup-all` runs the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:71 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:74 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:73 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:76 msgid "To use the bridge, you need to create a room and invite the Hookshot bot (`@hookshot:example.com`) to it." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:75 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:78 msgid "Make sure the bot is able to send state events (usually the Moderator power level in clients)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:77 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:80 msgid "Send `!hookshot help` to the bot to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:79 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:82 msgid "Refer to [Hookshot's documentation](https://matrix-org.github.io/matrix-hookshot/latest/usage.html) for more details about using the bridge's various features." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:81 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:84 msgid "💡 **Note**: the different listeners are bound to certain paths which might differ from those assumed by the hookshot documentation. See [URLs for bridges setup](#urls-for-bridges-setup) below." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:83 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:86 msgid "Reset crypto store" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:85 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:88 msgid "Should the crypto store be corrupted, you can reset it by executing this Ansible playbook with the tag `reset-hookshot-encryption` added:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:91 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:94 msgid "More setup documentation" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:93 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:96 msgid "URLs for bridges setup" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:95 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:98 msgid "Unless indicated otherwise, the following endpoints are reachable on your `matrix.` subdomain (if the feature is enabled)." msgstr "" @@ -173,7 +177,7 @@ msgid "`/hookshot/webhooks/`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 -msgid "`matrix_hookshot_webhook_endpoint`" +msgid "`matrix_bridge_hookshot_webhook_endpoint`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 @@ -189,7 +193,7 @@ msgid "`/hookshot/webhooks/webhook`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 -msgid "`matrix_hookshot_generic_endpoint`" +msgid "`matrix_bridge_hookshot_generic_endpoint`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 @@ -205,7 +209,7 @@ msgid "`/hookshot/webhooks/oauth`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 -msgid "`matrix_hookshot_github_oauth_endpoint`" +msgid "`matrix_bridge_hookshot_github_oauth_endpoint`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 @@ -221,7 +225,7 @@ msgid "`/hookshot/webhooks/jira/oauth`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 -msgid "`matrix_hookshot_jira_oauth_endpoint`" +msgid "`matrix_bridge_hookshot_jira_oauth_endpoint`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 @@ -237,7 +241,7 @@ msgid "`/hookshot/webhooks/figma/webhook`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 -msgid "`matrix_hookshot_figma_endpoint`" +msgid "`matrix_bridge_hookshot_figma_endpoint`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 @@ -253,7 +257,7 @@ msgid "`/hookshot/_matrix/app/`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 -msgid "`matrix_hookshot_appservice_endpoint`" +msgid "`matrix_bridge_hookshot_appservice_endpoint`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 @@ -269,105 +273,105 @@ msgid "`/hookshot/widgetapi/`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 -msgid "`matrix_hookshot_widgets_endpoint`" +msgid "`matrix_bridge_hookshot_widgets_endpoint`" msgstr "" #: ../../../docs/configuring-playbook-bridge-hookshot.md:0 msgid "Widgets" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:107 -msgid "Also see the various `matrix_hookshot_container_labels_*` variables in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml), which expose URLs publicly." +#: ../../../docs/configuring-playbook-bridge-hookshot.md:110 +msgid "Also see the various `matrix_bridge_hookshot_container_labels_*` variables in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml), which expose URLs publicly." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:109 -msgid "The different listeners are also reachable *internally* in the docker-network via the container's name (configured by `matrix_hookshot_container_url`) and on different ports (e.g. `matrix_hookshot_appservice_port`). Read [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml) in detail for more info." +#: ../../../docs/configuring-playbook-bridge-hookshot.md:112 +msgid "The different listeners are also reachable *internally* in the docker-network via the container's name (configured by `matrix_bridge_hookshot_container_url`) and on different ports (e.g. `matrix_bridge_hookshot_appservice_port`). Read [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml) in detail for more info." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:111 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:114 msgid "Manage GitHub Private Key with aux role" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:113 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:116 msgid "The GitHub bridge requires you to install a private key file. This can be done in multiple ways:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:115 -msgid "copy the *contents* of the downloaded file and set the variable `matrix_hookshot_github_private_key` to the contents (see example in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml))." +#: ../../../docs/configuring-playbook-bridge-hookshot.md:118 +msgid "copy the *contents* of the downloaded file and set the variable `matrix_bridge_hookshot_github_private_key` to the contents (see example in [main.yml](../roles/custom/matrix-bridge-hookshot/defaults/main.yml))." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:116 -msgid "somehow copy the file to the path `{{ matrix_hookshot_base_path }}/{{ matrix_hookshot_github_private_key_file }}` (default: `/matrix/hookshot/private-key.pem`) on the server manually." +#: ../../../docs/configuring-playbook-bridge-hookshot.md:119 +msgid "somehow copy the file to the path `{{ matrix_bridge_hookshot_base_path }}/{{ matrix_bridge_hookshot_github_private_key_file }}` (default: `/matrix/hookshot/private-key.pem`) on the server manually." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:117 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:120 msgid "use the [`aux` role](https://github.com/mother-of-all-self-hosting/ansible-role-aux) to copy the file from an arbitrary path on your ansible client to the correct path on the server." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:119 -msgid "To use the `aux` role, make sure the `matrix_hookshot_github_private_key` variable is empty. Then add the following configuration to your `vars.yml` file:" +#: ../../../docs/configuring-playbook-bridge-hookshot.md:122 +msgid "To use the `aux` role, make sure the `matrix_bridge_hookshot_github_private_key` variable is empty. Then add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:130 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:133 msgid "For more information, see the documentation in the [default configuration of the aux role](https://github.com/mother-of-all-self-hosting/ansible-role-aux/blob/main/defaults/main.yml)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:132 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:135 msgid "Enable metrics" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:134 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:137 msgid "The playbook can enable and configure the metrics of the service for you." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:136 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:139 msgid "Metrics are **only enabled by default** if the builtin [Prometheus](configuring-playbook-prometheus-grafana.md) is enabled (by default, Prometheus isn't enabled). If so, metrics will automatically be collected by Prometheus and made available in Grafana. You will, however, need to set up your own Dashboard for displaying them." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:138 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:141 msgid "To enable the metrics, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:145 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:148 msgid "**To collect metrics from an external Prometheus server**, besides enabling metrics as described above, you will also need to enable metrics exposure on `https://matrix.example.com/metrics/hookshot` by adding the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:151 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:154 msgid "By default metrics are exposed publicly **without** password-protection. To password-protect the metrics with dedicated credentials, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:158 -msgid "To `matrix_hookshot_container_labels_metrics_middleware_basic_auth_users`, set the Basic Authentication credentials (raw `htpasswd` file content) used to protect the endpoint. See https://doc.traefik.io/traefik/middlewares/http/basicauth/#users for details about it." +#: ../../../docs/configuring-playbook-bridge-hookshot.md:161 +msgid "To `matrix_bridge_hookshot_container_labels_metrics_middleware_basic_auth_users`, set the Basic Authentication credentials (raw `htpasswd` file content) used to protect the endpoint. See https://doc.traefik.io/traefik/middlewares/http/basicauth/#users for details about it." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:160 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:163 msgid "**Note**: alternatively, you can use `matrix_metrics_exposure_enabled` to expose all services on this `/metrics/*` feature, and you can use `matrix_metrics_exposure_http_basic_auth_enabled` and `matrix_metrics_exposure_http_basic_auth_users` to password-protect the metrics of them. See [this section](configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) for more information." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:162 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:165 msgid "Enable Grafana (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:164 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:167 msgid "Probably you wish to enable Grafana along with Prometheus for generating graphs of the metrics." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:166 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:169 msgid "To enable Grafana, see [this section](configuring-playbook-prometheus-grafana.md#adjusting-the-playbook-configuration-grafana) for instructions." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:168 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:171 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:170 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:173 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-hookshot`." msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:172 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:175 msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bridge-hookshot.md:174 +#: ../../../docs/configuring-playbook-bridge-hookshot.md:177 msgid "The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-matrix-bridge-sms.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-matrix-bridge-sms.pot index f83068b82..7a50e405e 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-matrix-bridge-sms.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-matrix-bridge-sms.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -57,7 +57,7 @@ msgid "Take a look at:" msgstr "" #: ../../../docs/configuring-playbook-bridge-matrix-bridge-sms.md:49 -msgid "`roles/custom/matrix-bridge-sms/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_sms_bridge_configuration_extension_yaml` variable" +msgid "`roles/custom/matrix-bridge-sms/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_sms_configuration_extension_yaml` variable" msgstr "" #: ../../../docs/configuring-playbook-bridge-matrix-bridge-sms.md:51 diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-bridges.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-bridges.pot index f9c8027b1..e87d25beb 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-bridges.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-bridges.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,11 +41,11 @@ msgid "To enable the bridge, add the following configuration to your `inventory/ msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:27 -msgid "**Note**: for bridging to Meta's Messenger or Instagram, you would need to add `meta` with an underscore symbol (`_`) or hyphen (`-`) based on the context as prefix to each `SERVICENAME`; add `_` to variables (as in `matrix_mautrix_meta_messenger_configuration_extension_yaml` for example) and `-` to paths of the configuration files (as in `roles/custom/matrix-bridge-mautrix-meta-messenger/templates/config.yaml.j2`), respectively." +msgid "**Note**: for bridging to Meta's Messenger or Instagram, you would need to add `meta` with an underscore symbol (`_`) or hyphen (`-`) based on the context as prefix to each `SERVICENAME`; add `_` to variables (as in `matrix_bridge_mautrix_meta_messenger_configuration_extension_yaml` for example) and `-` to paths of the configuration files (as in `roles/custom/matrix-bridge-mautrix-meta-messenger/templates/config.yaml.j2`), respectively." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:29 -msgid "There are some additional things you may wish to configure about the bridge before you continue. Each bridge may have additional requirements besides `_enabled: true`. For example, the mautrix-telegram bridge (our documentation page about it is [here](configuring-playbook-bridge-mautrix-telegram.md)) requires the `matrix_mautrix_telegram_api_id` and `matrix_mautrix_telegram_api_hash` variables to be defined. Refer to each bridge's individual documentation page for details about enabling bridges." +msgid "There are some additional things you may wish to configure about the bridge before you continue. Each bridge may have additional requirements besides `_enabled: true`. For example, the mautrix-telegram bridge (our documentation page about it is [here](configuring-playbook-bridge-mautrix-telegram.md)) requires the `matrix_bridge_mautrix_telegram_api_id` and `matrix_bridge_mautrix_telegram_api_hash` variables to be defined. Refer to each bridge's individual documentation page for details about enabling bridges." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:31 @@ -110,7 +110,7 @@ msgid "**for all bridges with relay mode support**:" msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:95 -msgid "You can only have one `matrix_mautrix_SERVICENAME_configuration_extension_yaml` definition in `vars.yml` per bridge, so if you need multiple pieces of configuration there, just merge them like this:" +msgid "You can only have one `matrix_bridge_mautrix_SERVICENAME_configuration_extension_yaml` definition in `vars.yml` per bridge, so if you need multiple pieces of configuration there, just merge them like this:" msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:109 @@ -154,141 +154,173 @@ msgid "If you have issues with a service, and are requesting support, the higher msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:141 -msgid "Extending the configuration" +msgid "Expose the bridge's API (for Mautrix Manager and similar tools)" msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:143 -msgid "There are some additional things you may wish to configure about the bridge." +msgid "Each mautrix bridge runs an HTTP API which tools like [Mautrix Manager](https://github.com/mautrix/manager) can use to help you log into the bridge. This is especially handy for bridges where logging in manually is cumbersome (like [mautrix-gmessages](configuring-playbook-bridge-mautrix-gmessages.md))." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:145 -msgid "Take a look at:" +msgid "By default, the playbook exposes this API publicly at `https://matrix.example.com/bridges/SERVICENAME` (for example, `https://matrix.example.com/bridges/gmessages`). Such tools authenticate to the bridge with your own Matrix access token, so you never need to share any bridge secret with them." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:147 +msgid "To make discovery easier, the playbook also serves a `/.well-known/matrix/mautrix` file which advertises all your exposed bridges. Mautrix Manager reads this file and offers your bridges automatically, so you don't need to enter their URLs by hand." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:149 +msgid "This is all enabled by default. To **disable exposing the API for all bridges**, add the following configuration to your `vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:155 +msgid "**Alternatively**, to disable it for a specific bridge:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:161 +msgid "If you run additional bridges on the same server which are not managed by this playbook and would like compatible tools to discover them as well, you can advertise their base URLs in the `/.well-known/matrix/mautrix` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:168 +msgid "Only list bridges hosted on (and connected to) this server here, as compatible tools will send your Matrix access token to them. For bridges on other servers, take a look at the `fi.mau.external_bridge_servers` property described in the [Mautrix Manager](https://github.com/mautrix/manager) documentation, which you can add via `matrix_static_files_file_matrix_mautrix_configuration_extension_json`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:170 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:172 +msgid "There are some additional things you may wish to configure about the bridge." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:174 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:176 msgid "`roles/custom/matrix-bridge-mautrix-SERVICENAME/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:148 -msgid "`roles/custom/matrix-bridge-mautrix-SERVICENAME/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_mautrix_SERVICENAME_configuration_extension_yaml` variable" +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:177 +msgid "`roles/custom/matrix-bridge-mautrix-SERVICENAME/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_mautrix_SERVICENAME_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:150 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:179 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:152 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:181 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:159 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:188 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:161 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:190 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:163 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:192 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:165 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:194 msgid "To use the bridge, you need to start a chat with `@SERVICENAMEbot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:167 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:196 msgid "For details about the next steps, refer to each bridge's individual documentation page." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:169 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:198 msgid "Send `help` to the bot to see the available commands." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:171 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:200 msgid "If you run into trouble, check the [Troubleshooting](#troubleshooting) section below." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:173 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:202 msgid "Set up Double Puppeting (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:175 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:204 msgid "After successfully enabling bridging, you may wish to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:177 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:206 msgid "To set it up, you have 2 ways of going about it." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:179 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:208 msgid "Method 1: automatically, by enabling Appservice Double Puppet (recommended)" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:181 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:210 msgid "To set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html), you could enable the [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) service for this playbook." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:183 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:212 msgid "Appservice Double Puppet is a homeserver appservice through which bridges (and potentially other services) can impersonate any user on the homeserver." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:185 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:214 msgid "To enable the Appservice Double Puppet service, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:191 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:220 msgid "When enabled, double puppeting will automatically be enabled for all bridges that support double puppeting via the appservice method." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:193 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:222 msgid "This is the recommended way of setting up Double Puppeting, as it's easier to accomplish, works for all your users automatically, and has less of a chance of breaking in the future." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:195 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:224 msgid "**Notes**:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:197 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:226 msgid "Previously there were multiple different automatic double puppeting methods like one with the help of the [Shared Secret Auth password provider module](./configuring-playbook-shared-secret-auth.md), but they have been superseded by this Appservice Double Puppet method. Double puppeting with the Shared Secret Auth works at the time of writing, but is deprecated and will stop working in the future as the older methods were completely removed in the megabridge rewrites on [the upstream project](https://docs.mau.fi/bridges/general/double-puppeting.html#automatically)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:200 -msgid "Some bridges like [the deprecated Facebook mautrix bridge](configuring-playbook-bridge-mautrix-facebook.md) and [matrix-appservice-kakaotalk](configuring-playbook-bridge-appservice-kakaotalk.md), which is partially based on the Facebook bridge, are compatible with the Shared Secret Auth service only. These bridges automatically perform Double Puppeting if [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) service is configured and enabled on the server for this playbook." +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:229 +msgid "Some bridges like [the deprecated Facebook mautrix bridge](configuring-playbook-bridge-mautrix-facebook.md) are compatible with the Shared Secret Auth service only. These bridges automatically perform Double Puppeting if [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) service is configured and enabled on the server for this playbook." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:202 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:231 msgid "Method 2: manually, by asking each user to provide a working access token" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:204 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:233 msgid "When using this method, **each user** that wishes to enable Double Puppeting needs to follow the following steps:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:206 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:235 msgid "retrieve a Matrix access token for yourself. Refer to the documentation on [how to obtain one](obtaining-access-tokens.md)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:208 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:237 msgid "send the access token to the bot. Example: `login-matrix MATRIX_ACCESS_TOKEN_HERE`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:210 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:239 msgid "make sure you don't log out the session for which you obtained an access token some time in the future, as that would break the Double Puppeting feature" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:212 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:241 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:214 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:243 msgid "For troubleshooting information with a specific bridge, please see the playbook documentation about it (some other document in in `docs/`) and the upstream ([mautrix](https://github.com/mautrix)) bridge documentation for that specific bridge." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:216 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:245 msgid "If the bridge's bot doesn't accept the invite to a chat, refer [the official troubleshooting page](https://docs.mau.fi/bridges/general/troubleshooting.html) as well." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:218 +#: ../../../docs/configuring-playbook-bridge-mautrix-bridges.md:247 msgid "If you found bugs in mautrix bridges, they should be reported to the upstream project, in the corresponding mautrix repository, not to us." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-discord.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-discord.pot index 1ed9203b6..40c99f53a 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-discord.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-discord.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-15 09:10+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -28,130 +28,146 @@ msgstr "" msgid "**Note**: bridging to [Discord](https://discordapp.com/) can also happen via the [matrix-appservice-discord](configuring-playbook-bridge-appservice-discord.md) bridge supported by the playbook." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:18 -msgid "For using as a Bot we recommend the [Appservice Discord](configuring-playbook-bridge-appservice-discord.md), because it supports plumbing." -msgstr "" - #: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:19 -msgid "For personal use with a discord account we recommend the `mautrix-discord` bridge (the one being discussed here), because it is the most fully-featured and stable of the 3 Discord bridges supported by the playbook." +msgid "The playbook can install and configure [mautrix-discord](https://github.com/mautrix/discord) for you." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:21 -msgid "The playbook can install and configure [mautrix-discord](https://github.com/mautrix/discord) for you." +msgid "See the project's [documentation](https://docs.mau.fi/bridges/go/discord/index.html) to learn what it does and why it might be useful to you." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:23 -msgid "See the project's [documentation](https://docs.mau.fi/bridges/go/discord/index.html) to learn what it does and why it might be useful to you." +msgid "Prerequisites" msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:25 -msgid "Prerequisites" +msgid "There are 3 ways to login to discord using this bridge, either by [scanning a QR code](https://docs.mau.fi/bridges/go/discord/authentication.html#qr-login) using the Discord mobile app, by using a [Discord token](https://docs.mau.fi/bridges/go/discord/authentication.html#token-login), **or** by using a [Discord bot token](https://docs.mau.fi/bridges/go/discord/authentication.html#bot-token-login)." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:27 -msgid "There are 2 ways to login to discord using this bridge, either by [scanning a QR code](#method-1-login-using-qr-code-recommended) using the Discord mobile app **or** by using a [Discord token](#method-2-login-using-discord-token-not-recommended)." +msgid "⚠️ QR code login is considered a self-bot and is forbidden by Discord. It can result in an account termination. See the [Discord policy](https://support.discord.com/hc/en-us/articles/115002192352-Automated-User-Accounts-Self-Bots)." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:29 -msgid "If this is a dealbreaker for you, consider using [matrix-appservice-discord](configuring-playbook-bridge-appservice-discord.md). This comes with its own complexity and limitations, however, so we recommend that you proceed with this one if possible." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:31 msgid "Enable Appservice Double Puppet or Shared Secret Auth (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:33 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:31 msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) or [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) service for this playbook." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:35 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:33 msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:37 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:35 msgid "**Note**: double puppeting with the Shared Secret Auth works at the time of writing, but is deprecated and will stop working in the future." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:39 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:37 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:41 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:39 msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:47 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:45 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:49 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:47 msgid "There are some additional things you may wish to configure about the bridge." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:52 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:50 msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:54 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:52 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:56 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:54 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:63 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:61 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:65 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:63 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:67 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:65 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:69 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:67 msgid "To use the bridge, you need to start a chat with `@discordbot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:71 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:69 msgid "You can then follow instructions on the bridge's [official documentation on Authentication](https://docs.mau.fi/bridges/go/discord/authentication.html)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:73 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:71 msgid "After logging in, the bridge will create portal rooms for some recent direct messages." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:75 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:73 msgid "Bridge guilds" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:77 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:75 msgid "If you'd like to bridge guilds, send `guilds status` to see the list of guilds, then send `guilds bridge GUILD_ID_HERE` for each guild that you'd like bridged. Make sure to replace `GUILD_ID_HERE` with the guild's ID." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:79 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:77 msgid "After bridging, spaces will be created automatically, and rooms will be created if necessary when messages are received. You can also pass `--entire` to the bridge command to immediately create all rooms." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:81 +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:79 msgid "If you want to manually bridge channels, invite the bot to the room you want to bridge, and run `!discord bridge CHANNEL_ID_HERE` to bridge the room. Make sure to replace `CHANNEL_ID_HERE` with the channel's ID." msgstr "" +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:81 +msgid "Enable relay" +msgstr "" + #: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:83 -msgid "Troubleshooting" +msgid "The bridge supports using Discord's webhook feature to relay messages from Matrix users who haven't logged into the bridge." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:85 -msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-mautrix-discord`." +msgid "In a room that has already been bridged, run `!discord set-relay --create`. The bridge will then create a webhook in the bridged discord channel and begin relaying messages. If the discord user does not have access to manage webhooks, run `!discord set-relay --url ` with the url of an already created webhook. (See Discords [Intro to webhooks](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks))" msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:87 -msgid "Increase logging verbosity" +msgid "More information on relaying is available on the [official documentation](https://docs.mau.fi/bridges/go/discord/relay.html)." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:89 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:91 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-mautrix-discord`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:93 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:95 msgid "The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:102 +msgid "Command requires room admin rights when user is creator" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-discord.md:104 +msgid "[MSC4289](https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/4289-privilege-creators.md), introduced in [room version 12](https://spec.matrix.org/unstable/rooms/v12/), gives creators an infinitley high powerlevel. At the time of implementation, mautrix-discord and similar applications may not identify creators as or above admins. Either a separate admin user will need to manage the bridge or the room version should be less than version 12." +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-gvoice.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-gvoice.pot new file mode 100644 index 000000000..c3533eedb --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-gvoice.pot @@ -0,0 +1,121 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:8 +msgid "Setting up Mautrix Google Voice bridging (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:10 +msgid "Refer the common guide for configuring mautrix bridges: [Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:12 +msgid "The playbook can install and configure [mautrix-gvoice](https://github.com/mautrix/gvoice) for you, for bridging to [Google Voice](https://voice.google.com/)." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:14 +msgid "See the project's [documentation](https://docs.mau.fi/bridges/go/gvoice/index.html) to learn what it does and why it might be useful to you." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:16 +msgid "Prerequisite (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:18 +msgid "Enable Appservice Double Puppet" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:20 +msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) for this playbook." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:22 +msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:24 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:26 +msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:32 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:34 +msgid "There are some additional things you may wish to configure about the bridge." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:37 +msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:39 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:41 +msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:48 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:50 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:52 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:54 +msgid "To use the bridge, start a chat with `@gvoicebot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:56 +msgid "Google Voice has no phone to pair and no QR code to scan. It logs in with cookies, which you copy from a browser already signed in to [voice.google.com](https://voice.google.com/) and hand to the bot. It is fiddlier than scanning a code and feels more suspicious than it is, but Google leaves no cleaner door open. The bridge's [official Authentication guide](https://docs.mau.fi/bridges/go/gvoice/authentication.html) has the exact cookies to grab and the steps for grabbing them." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:58 +msgid "Those cookies are a login session, and Google expires them on its own schedule. When they lapse the bridge goes quiet and you log in again. Nothing is broken, that is just how cookie auth ages." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:60 +msgid "Once you log in, the bridge builds portal rooms for your recent conversations and carries text and media both ways. Don't reach for it to start a brand-new chat or to place a call, though. That ground still belongs to Google Voice, so keep the app around for those." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:62 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:64 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-mautrix-gvoice`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:66 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-gvoice.md:68 +msgid "The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-linkedin.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-linkedin.pot new file mode 100644 index 000000000..f3fed2b17 --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-linkedin.pot @@ -0,0 +1,205 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-08-01 17:14+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:9 +msgid "Setting up Mautrix LinkedIn bridging (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:11 +msgid "Refer the common guide for configuring mautrix bridges: [Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:13 +msgid "The playbook can install and configure [mautrix-linkedin](https://github.com/mautrix/linkedin) for you, for bridging to [LinkedIn](https://www.linkedin.com/) messaging." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:15 +msgid "See the project's [documentation](https://docs.mau.fi/bridges/go/linkedin/index.html) to learn what it does and why it might be useful to you." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:18 +msgid "LinkedIn keeps its messaging function behind a login wall and does not provide a usable public API, so using this bridge requires you to manually copy cookies on a web browser for logging in. Refer to [this section](#usage) below for details." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:20 +msgid "Prerequisite" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:22 +msgid "Uninstalling `beeper-linkedin`" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:24 +msgid "If `beeper-linkedin` bridge is enabled on your host, you need to uninstall it first, since it claims the `@linkedinbot` username and `@linkedin_*` user range as exclusive appservice namespaces, which will cause conflicts with `mautrix-linkedin`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:26 +msgid "To uninstall the bridge, set `matrix_bridge_beeper_linkedin_enabled: false` and re-run the playbook. The playbook refuses to install `mautrix-linkedin` until `beeper-linkedin` is uninstalled." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:28 +msgid "Enable Appservice Double Puppet (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:30 +msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) for this playbook." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:32 +msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:34 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:36 +msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:42 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:44 +msgid "There are some additional things you may wish to configure about the bridge." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:47 +msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:49 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:51 +msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:58 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:60 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:62 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:64 +msgid "Start a chat with `@linkedinbot:example.com` (where `example.com` is your base domain, the bare one without the `matrix.` prefix) and send `login`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:66 +msgid "Logging in" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:68 +msgid "To log in, you need to sign in to LinkedIn with a web browser and hand one of the requests it makes to the bot. Because the bridge presents itself as Chrome on Linux, the request needs to come from **Chrome or a Chrome-based browser**." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:71 +msgid "LinkedIn ties the session to the browser that made the request and rejects it when it is replayed under a different user-agent. A request copied from Firefox therefore results in a session that stops working immediately, without an error message." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:73 +msgid "You need to follow these steps to log in:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:75 +msgid "Open [linkedin.com](https://www.linkedin.com/) in a private/incognito window on Chrome / a Chrome-based browser" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:76 +msgid "Sign in to LinkedIn" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:77 +msgid "Open your browser's devtools (F12) and go to the Network tab" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:78 +msgid "Filter for `graphql`" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:79 +msgid "Right-click any one of those requests, then \"Copy\" and \"Copy as cURL\"" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:80 +msgid "Paste the output into the chat with the bot and send it" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:82 +msgid "The bridge's [official Authentication guide](https://docs.mau.fi/bridges/go/linkedin/authentication.html) walks the same steps with screenshots." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:84 +msgid "Once you log in, the bridge builds portal rooms for your recent conversations and carries messages both ways." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:86 +msgid "**💡 Notes:**" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:88 +msgid "The request contains a login session, which LinkedIn may expire at any time. When the bridge goes quiet, log in again by following the steps above." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:89 +msgid "If you would rather not retrieve the request yourself, you may wish to take a look at [mautrix-manager](https://github.com/mautrix/manager)." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:91 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:93 +msgid "The bot does not respond after you send it the cURL output" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:95 +msgid "This most likely means that you have obtained the request with a browser other than Chrome or a Chrome-based one. LinkedIn silently discards a session replayed under a different user-agent. Follow the login steps above again, this time using Chrome or a Chrome-based browser." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:97 +msgid "The bridge worked before, but has gone quiet" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:99 +msgid "Your LinkedIn session has most likely expired. Send `login` to the bot and follow the login steps above again." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:101 +msgid "Other issues" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:103 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-mautrix-linkedin`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:105 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-mautrix-linkedin.md:107 +msgid "The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-meta-instagram.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-meta-instagram.pot index e3ea1cec2..d1a1a3f7d 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-meta-instagram.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-meta-instagram.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-16 16:15+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -33,7 +33,7 @@ msgid "See the project's [documentation](https://docs.mau.fi/bridges/go/meta/ind msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-meta-instagram.md:16 -msgid "Since this bridge component can bridge to both [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/) and you may wish to do both at the same time, the playbook makes it available via 2 different Ansible roles (`matrix-bridge-mautrix-meta-messenger` and `matrix-bridge-mautrix-meta-instagram`). The latter is a reconfigured copy of the first one (created by `just rebuild-mautrix-meta-instagram` and `bin/rebuild-mautrix-meta-instagram.sh`)." +msgid "The mautrix-meta project provides bridging to both [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/), each via a separate bridge (its own binary and container image) since mautrix-meta v26.07. The playbook makes them available via 2 different Ansible roles (`matrix-bridge-mautrix-meta-messenger` and `matrix-bridge-mautrix-meta-instagram`), which can both be enabled at the same time." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-meta-instagram.md:18 @@ -53,7 +53,7 @@ msgid "If you've been using the [mautrix-instagram](./configuring-playbook-bridg msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-meta-instagram.md:26 -msgid "both trying to use `@instagrambot:example.com` as their username. This conflict may be resolved by adjusting `matrix_mautrix_instagram_appservice_bot_username` or `matrix_mautrix_meta_instagram_appservice_username`" +msgid "both trying to use `@instagrambot:example.com` as their username. This conflict may be resolved by adjusting `matrix_mautrix_instagram_appservice_bot_username` or `matrix_bridge_mautrix_meta_instagram_appservice_username`" msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-meta-instagram.md:27 diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-meta-messenger.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-meta-messenger.pot index ea8796d7f..419f3bea8 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-meta-messenger.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-meta-messenger.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-16 16:15+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -33,7 +33,7 @@ msgid "See the project's [documentation](https://docs.mau.fi/bridges/go/meta/ind msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-meta-messenger.md:17 -msgid "Since this bridge component can bridge to both [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/) and you may wish to do both at the same time, the playbook makes it available via 2 different Ansible roles (`matrix-bridge-mautrix-meta-messenger` and `matrix-bridge-mautrix-meta-instagram`). The latter is a reconfigured copy of the first one (created by `just rebuild-mautrix-meta-instagram` and `bin/rebuild-mautrix-meta-instagram.sh`)." +msgid "The mautrix-meta project provides bridging to both [Messenger](https://messenger.com/) and [Instagram](https://instagram.com/), each via a separate bridge (its own binary and container image) since mautrix-meta v26.07. The playbook makes them available via 2 different Ansible roles (`matrix-bridge-mautrix-meta-messenger` and `matrix-bridge-mautrix-meta-instagram`), which can both be enabled at the same time." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-meta-messenger.md:19 @@ -113,7 +113,7 @@ msgid "(default) (`messenger`) Messenger via `messenger.com` — usable even wit msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-meta-messenger.md:59 -msgid "You may switch the mode via the `matrix_mautrix_meta_messenger_meta_mode` variable. The playbook defaults to the `messenger` mode, because it's most universal (every Facebook user has a Messenger account, but the opposite is not true)." +msgid "You may switch the mode via the `matrix_bridge_mautrix_meta_messenger_meta_mode` variable. The playbook defaults to the `messenger` mode, because it's most universal (every Facebook user has a Messenger account, but the opposite is not true)." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-meta-messenger.md:61 diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-signal.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-signal.pot index 18bacaf90..ab85a8a9c 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-signal.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-signal.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -45,7 +45,7 @@ msgid "If you're running with the Postgres database server integrated by the pla msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-signal.md:31 -msgid "However, if you're [using an external Postgres server](configuring-playbook-external-postgres.md), you'd need to manually prepare a Postgres database for this bridge and adjust the variables related to that (`matrix_mautrix_signal_database_*`)." +msgid "However, if you're [using an external Postgres server](configuring-playbook-external-postgres.md), you'd need to manually prepare a Postgres database for this bridge and adjust the variables related to that (`matrix_bridge_mautrix_signal_database_*`)." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-signal.md:33 diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-slack.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-slack.pot index 9625ff9cb..006a08276 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-slack.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-slack.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-15 09:10+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -25,117 +25,105 @@ msgid "Refer the common guide for configuring mautrix bridges: [Setting up msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:14 -msgid "**Note**: bridging to [Slack](https://slack.com/) can also happen via the [matrix-appservice-slack](configuring-playbook-bridge-appservice-slack.md) bridge supported by the playbook." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:15 -msgid "For using as a Bot we recommend the [Appservice Slack](configuring-playbook-bridge-appservice-slack.md), because it supports plumbing. Note that it is not available for new installation unless you have already created a classic Slack application, because the creation of classic Slack applications, which this bridge makes use of, has been discontinued." +msgid "The playbook can install and configure [mautrix-slack](https://github.com/mautrix/slack) for you." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:16 -msgid "For personal use with a slack account we recommend the `mautrix-slack` bridge (the one being discussed here), because it is the most fully-featured and stable of the 3 Slack bridges supported by the playbook." +msgid "See the project's [documentation](https://docs.mau.fi/bridges/go/slack/index.html) to learn what it does and why it might be useful to you." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:18 -msgid "The playbook can install and configure [mautrix-slack](https://github.com/mautrix/slack) for you." +msgid "See the [features and roadmap](https://github.com/mautrix/slack/blob/main/ROADMAP.md) for more information." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:20 -msgid "See the project's [documentation](https://docs.mau.fi/bridges/go/slack/index.html) to learn what it does and why it might be useful to you." +msgid "Prerequisites" msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:22 -msgid "See the [features and roadmap](https://github.com/mautrix/slack/blob/main/ROADMAP.md) for more information." +msgid "For using this bridge, you would need to authenticate by **providing your username and password** (legacy) or by using a **token login**. See more information in the [docs](https://docs.mau.fi/bridges/go/slack/authentication.html)." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:24 -msgid "Prerequisites" +msgid "Note that neither of these methods are officially supported by Slack." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:26 -msgid "For using this bridge, you would need to authenticate by **providing your username and password** (legacy) or by using a **token login**. See more information in the [docs](https://docs.mau.fi/bridges/go/slack/authentication.html)." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:28 -msgid "Note that neither of these methods are officially supported by Slack. [matrix-appservice-slack](configuring-playbook-bridge-appservice-slack.md) uses a Slack bot account which is the only officially supported method for bridging a Slack channel." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:30 msgid "Enable Appservice Double Puppet (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:32 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:28 msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) service for this playbook." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:34 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:30 msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:36 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:32 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:38 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:34 msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:44 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:40 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:46 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:42 msgid "There are some additional things you may wish to configure about the bridge." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:48 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:44 msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [relay mode](configuring-playbook-bridge-mautrix-bridges.md#enable-relay-mode-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:50 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:46 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:52 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:48 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:59 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:55 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:61 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:57 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:63 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:59 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:65 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:61 msgid "To use the bridge, you need to start a chat with `@slackbot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:67 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:63 msgid "You can then follow instructions on the bridge's [official documentation on Authentication](https://docs.mau.fi/bridges/go/slack/authentication.html)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:69 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:65 msgid "If you authenticated using a token, the recent chats will be bridged automatically (depending on the `conversation_count` setting). Otherwise (i.e. logging with the Discord application), the chats the bot is in will be bridged automatically." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:71 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:67 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:73 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:69 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-mautrix-slack`." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:75 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:71 msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:77 +#: ../../../docs/configuring-playbook-bridge-mautrix-slack.md:73 msgid "The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-telegram.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-telegram.pot index cf912b600..0a7bcdd3e 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-telegram.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-telegram.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-07 11:16+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -29,7 +29,7 @@ msgid "The playbook can install and configure [mautrix-telegram](https://github. msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:20 -msgid "See the project's [documentation](https://docs.mau.fi/bridges/python/telegram/index.html) to learn what it does and why it might be useful to you." +msgid "See the project's [documentation](https://docs.mau.fi/bridges/go/telegram/index.html) to learn what it does and why it might be useful to you." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:22 @@ -45,11 +45,11 @@ msgid "To use the bridge, you'd need to obtain an API key from [https://my.teleg msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:28 -msgid "Enable Appservice Double Puppet or Shared Secret Auth (optional)" +msgid "Enable Appservice Double Puppet (optional)" msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:30 -msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) or [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) service for this playbook." +msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) service for this playbook." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:32 @@ -57,113 +57,85 @@ msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up- msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:34 -msgid "**Notes**:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:36 -msgid "Double puppeting with the Shared Secret Auth works at the time of writing, but is deprecated and will stop working in the future." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:38 -msgid "If you decided to enable Double Puppeting manually, send `login-matrix` to the bot in order to receive an instruction about how to send an access token to it." -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:40 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:42 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:36 msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file. Make sure to replace `YOUR_TELEGRAM_APP_ID` and `YOUR_TELEGRAM_API_HASH`." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:50 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:44 msgid "Relaying" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:52 -msgid "Enable relay-bot (optional)" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:54 -msgid "If you want to use the relay-bot feature ([relay bot documentation](https://docs.mau.fi/bridges/python/telegram/relay-bot.html)), which allows anonymous user to chat with telegram users, add the following configuration to your `vars.yml` file:" +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:46 +msgid "This bridge supports the common [mautrix bridge relay mode](configuring-playbook-bridge-mautrix-bridges.md#enable-relay-mode-optional). Once enabled, any authenticated user can be turned into a relaybot for a chat by sending `!tg set-relay` in that chat." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:64 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:48 msgid "Configure a user as an administrator of the bridge (optional)" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:66 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:50 msgid "You might also want to give permissions to a user to administrate the bot. See [this section](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional) on the common guide for details about it." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:68 -msgid "More details about permissions in this example: https://github.com/mautrix/telegram/blob/master/mautrix_telegram/example-config.yaml#L410" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:70 -msgid "Use the bridge for direct chats only (optional)" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:72 -msgid "If you want to exclude all groups from syncing and use the Telegram-Bridge only for direct chats, add the following configuration to your `vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:78 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:52 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:80 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:54 msgid "There are some additional things you may wish to configure about the bridge." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:83 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:56 msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:85 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:58 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:87 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:60 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:94 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:67 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:96 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:69 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:98 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:71 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:100 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:73 msgid "To use the bridge, you need to start a chat with `@telegrambot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:102 -msgid "You can then follow instructions on the bridge's [official documentation on Authentication](https://docs.mau.fi/bridges/python/telegram/authentication.html)." +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:75 +msgid "You can then follow instructions on the bridge's [official documentation on Authentication](https://docs.mau.fi/bridges/go/telegram/authentication.html)." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:104 -msgid "After logging in, the bridge will create portal rooms for all of your Telegram groups and invite you to them. Note that the bridge won't automatically create rooms for private chats." +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:77 +msgid "After logging in, the bridge will create portal rooms for all of your Telegram groups and invite you to them." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:106 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:79 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:108 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:81 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-mautrix-telegram`." msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:110 +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:83 msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:112 -msgid "The default logging level for this component is `WARNING`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +#: ../../../docs/configuring-playbook-bridge-mautrix-telegram.md:85 +msgid "The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-wsproxy.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-wsproxy.pot index 96c26f6d2..548c8c604 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-wsproxy.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-mautrix-wsproxy.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -61,7 +61,7 @@ msgid "Adjusting the wsproxy URL (optional)" msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-wsproxy.md:41 -msgid "By tweaking the `matrix_mautrix_wsproxy_hostname` variable, you can easily make the service available at a **different hostname** than the default one." +msgid "By tweaking the `matrix_bridge_mautrix_wsproxy_hostname` variable, you can easily make the service available at a **different hostname** than the default one." msgstr "" #: ../../../docs/configuring-playbook-bridge-mautrix-wsproxy.md:43 diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-meshtastic-relay.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-meshtastic-relay.pot new file mode 100644 index 000000000..beef1d21a --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-meshtastic-relay.pot @@ -0,0 +1,133 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:8 +msgid "Setting up a Matrix <-> Meshtastic bridge (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:10 +msgid "The playbook can install and configure [meshtastic-matrix-relay](https://github.com/jeremiah-k/meshtastic-matrix-relay) (sometimes referred to as `mmrelay`) for you — a bridge between [Matrix](https://matrix.org/) and [Meshtastic](https://meshtastic.org/) mesh networks." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:12 +msgid "See the [project's documentation](https://github.com/jeremiah-k/meshtastic-matrix-relay) to learn what it does and why it might be useful to you." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:14 +msgid "Prerequisites" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:16 +msgid "You need a Matrix account for the bot. You can either [register the bot account manually](registering-users.md) or let the playbook create it when running `ansible-playbook … --tags=ensure-matrix-users-created`. Either way, you'll need the account's **password** to configure the bridge — unlike most other bridges in this playbook, `mmrelay` authenticates with a password and creates its own session (optionally with End-to-End Encryption material)." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:18 +msgid "You also need access to a Meshtastic device, connected to the server via one of:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:20 +msgid "**TCP**: the device is reachable on the network (e.g. a Meshtastic node running the TCP API)," +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:21 +msgid "**Serial**: the device is plugged in via USB and available on the host (e.g. `/dev/ttyUSB0`)," +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:22 +msgid "**BLE**: the device is reachable via Bluetooth Low Energy from the host." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:24 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:26 +msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:56 +msgid "By default, the bot's Matrix ID is `@meshtasticbot:{{ matrix_domain }}`. To change it, adjust `matrix_bridge_meshtastic_relay_matrix_bot_user_id`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:58 +msgid "Bluetooth (BLE) connections" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:60 +msgid "When `matrix_bridge_meshtastic_relay_connection_type` is `ble`, the container runs with `--network=host` and bind-mounts the host's DBus socket — both are required for Bluetooth pairing/communication. Only use this connection type if you trust the playbook-managed host and are comfortable with these privileges." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:62 +msgid "Serial connections" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:64 +msgid "When `matrix_bridge_meshtastic_relay_connection_type` is `serial`, the host device referenced by `matrix_bridge_meshtastic_relay_serial_port` is passed through to the container. Make sure that `matrix_user_uid` / `matrix_user_gid` have read/write access to that device (e.g. by adding the matrix user to the `dialout` group, or adjusting udev rules)." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:66 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:68 +msgid "There are some additional things you may wish to configure about the bridge." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:70 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:72 +msgid "`roles/custom/matrix-bridge-meshtastic-relay/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override individual `matrix_bridge_meshtastic_relay_*` variables, or make finer-grained adjustments via `matrix_bridge_meshtastic_relay_configuration_extension_yaml`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:74 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:76 +msgid "After configuring the playbook, run the playbook with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:83 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:85 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:87 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:89 +msgid "Invite the bot to the Matrix rooms listed in `matrix_bridge_meshtastic_relay_matrix_rooms_list` and it will relay between Matrix and the corresponding Meshtastic channel. Messages sent on Meshtastic will appear in Matrix and vice versa." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:91 +msgid "See the [project's wiki](https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki) for details about commands, plugins and advanced usage." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:93 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-meshtastic-relay.md:95 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-meshtastic-relay`." +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-postmoogle.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-postmoogle.pot index 760593f05..410d7c416 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-postmoogle.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-postmoogle.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -53,7 +53,7 @@ msgid "If you don't open these ports, you will still be able to send emails, but msgstr "" #: ../../../docs/configuring-playbook-bridge-postmoogle.md:27 -msgid "These port numbers are configurable via the `matrix_postmoogle_smtp_host_bind_port` and `matrix_postmoogle_submission_host_bind_port` variables, but other email servers will try to deliver on these default (standard) ports, so changing them is of little use." +msgid "These port numbers are configurable via the `matrix_bridge_postmoogle_smtp_host_bind_port` and `matrix_bridge_postmoogle_submission_host_bind_port` variables, but other email servers will try to deliver on these default (standard) ports, so changing them is of little use." msgstr "" #: ../../../docs/configuring-playbook-bridge-postmoogle.md:29 @@ -189,7 +189,7 @@ msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x f msgstr "" #: ../../../docs/configuring-playbook-bridge-postmoogle.md:90 -msgid "If you change the bridge's bot password (`matrix_postmoogle_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_postmoogle_password` to let the bot know its new password." +msgid "If you change the bridge's bot password (`matrix_bridge_postmoogle_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [Ketesa](configuring-playbook-ketesa.md) to change it, and then update `matrix_bridge_postmoogle_password` to let the bot know its new password." msgstr "" #: ../../../docs/configuring-playbook-bridge-postmoogle.md:92 diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-rustpush.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-rustpush.pot new file mode 100644 index 000000000..63f646c1c --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-rustpush.pot @@ -0,0 +1,173 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:8 +msgid "Setting up RustPush (iMessage) bridging (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:10 +msgid "**Note:** This bridge is in early development and may have stability issues. It may not be desirable to deploy this to a large number of users. Your testing and feedback is appreciated." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:12 +msgid "Refer the common guide for configuring mautrix bridges: [Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:14 +msgid "The playbook can install and configure [RustPush bridge to iMessage](https://github.com/jasonlaguidice/imessage) for you using Apple's push notification service." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:16 +msgid "See the project's [documentation](https://github.com/jasonlaguidice/imessage/blob/main/README.md) to learn what it does and why it might be useful to you." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:18 +msgid "Prerequisites" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:20 +msgid "Hardware Key Extraction" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:22 +msgid "To use this bridge on Linux (Docker), each user needs a **hardware key** extracted from a real Mac. This key contains hardware identifiers needed for iMessage registration. Hardware keys can be shared by a number of users (approximately 20) before causing issues with Apple." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:24 +msgid "The key is entered interactively through the bridge bot's login flow (not configured via Ansible variables). See the upstream [README](https://github.com/jasonlaguidice/imessage/blob/main/README.md) for instructions on extracting the key." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:26 +msgid "If extracted from an Intel Mac, the Mac does not need to remain running after the key is extracted for this bridge to work. Apple Silicon Macs must run a NAC relay and thus must remain running." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:28 +msgid "Phone Number Registration (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:30 +msgid "This bridge can **not** do phone number registration (PNR). The only way to have your phone number registered and used (instead of an Apple ID e-mail address) is to have an iPhone connected to your Apple account. Reference the [BlueBubbles Phone Number Registration Guide](https://docs.bluebubbles.app/server/advanced/registering-a-phone-number-with-your-imessage-account) for information on how to set this up." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:32 +msgid "Enable Appservice Double Puppet (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:34 +msgid "If you want to set up [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do) for this bridge automatically, you need to have enabled [Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md) service for this playbook." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:36 +msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#set-up-double-puppeting-optional) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about setting up Double Puppeting." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:38 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:40 +msgid "To enable the bridge, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:46 +msgid "Disable Backfill (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:48 +msgid "Backfill can be disabled globally if desired via config. By default, the bridge will backfill from iCloud (CloudKit) and APNS if available. Backfill from `chat.db` is only possible when the bridge is running on MacOS." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:54 +msgid "Extending the Configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:56 +msgid "There are some additional things you may wish to configure about the bridge." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:58 +msgid "See [this section](configuring-playbook-bridge-mautrix-bridges.md#extending-the-configuration) on the [common guide for configuring mautrix bridges](configuring-playbook-bridge-mautrix-bridges.md) for details about variables that you can customize and the bridge's default configuration, including [bridge permissions](configuring-playbook-bridge-mautrix-bridges.md#configure-bridge-permissions-optional), [encryption support](configuring-playbook-bridge-mautrix-bridges.md#enable-encryption-optional), [bot's username](configuring-playbook-bridge-mautrix-bridges.md#set-the-bots-username-optional), etc." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:60 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:62 +msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:69 +msgid "**Notes**:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:71 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:73 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:75 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:77 +msgid "To use the bridge, you need to start a chat with `@rustpushbot:example.com` (where `example.com` is your base domain, not the `matrix.` domain)." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:79 +msgid "After logging in, the bridge will start receiving iMessages and creating portal rooms." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:81 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:83 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-rustpush-bridge`." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:85 +msgid "Increase logging verbosity" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:87 +msgid "The default logging level for this component is `warn`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:96 +msgid "Notable Configuration Options" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:97 +msgid "`matrix_bridge_rustpush_statuskit_notifications` will display StatusKit information for conversation participants. In some clients, this update will cause the DM to be pushed to the top of the conversation list continuously, so this option is disabled by default." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:98 +msgid "`matrix_bridge_rustpush_statuskit_notification_style` can be set to either `topic` or `notice`" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:99 +msgid "`topic` sets the status as a room topic. In supported clients (like Cinny and Sable), this will display `🔕 Focus` as a second line when the person has focus mode enabled." +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-rustpush.md:100 +msgid "`notice` sends an `m.notice` event to the room which will display text in the room but should not generate a notification" +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-steam.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-steam.pot index 2e1e60cbd..05300612d 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-steam.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-steam.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -83,3 +83,11 @@ msgstr "" #: ../../../docs/configuring-playbook-bridge-steam.md:48 msgid "Send `help` to the bot to see the available commands." msgstr "" + +#: ../../../docs/configuring-playbook-bridge-steam.md:50 +msgid "Notable Configuration Options" +msgstr "" + +#: ../../../docs/configuring-playbook-bridge-steam.md:51 +msgid "`matrix_bridge_steam_network_presence_topic_enabled` and `matrix_bridge_steam_network_presence_topic_rich_presence_enabled` mirror Steam's [Enhanced Rich Presence](https://partner.steamgames.com/doc/features/enhancedrichpresence) feature in Matrix. This will display the user's current game and rich presence if supported by the game. This sets the DM room's `m.topic` field to achieve this. Some games (like Deadlock) update the rich presence every minute with a match timer. In some clients, the topic update will cause the DM to be pushed to the top of the conversation list continuously, so this option is disabled by default." +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-bridge-wechat.pot b/i18n/translation-templates/docs/configuring-playbook-bridge-wechat.pot index ddacd7704..c1725daa5 100644 --- a/i18n/translation-templates/docs/configuring-playbook-bridge-wechat.pot +++ b/i18n/translation-templates/docs/configuring-playbook-bridge-wechat.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -28,8 +28,8 @@ msgstr "" msgid "See the project's [documentation](https://github.com/duo/matrix-wechat/blob/master/README.md) to learn what it does and why it might be useful to you." msgstr "" -#: ../../../docs/configuring-playbook-bridge-wechat.md:14 -msgid "[!WARNING] This bridge does not work against newer versions of Synapse anymore. See [this issue](https://github.com/duo/matrix-wechat/issues/33). Don't even bother installing it. Unless bridge maintenance is resumed and fixes this issue, we have no choice but to remove it from the playbook." +#: ../../../docs/configuring-playbook-bridge-wechat.md:15 +msgid "This bridge does not work against newer versions of Synapse anymore. See [this issue](https://github.com/duo/matrix-wechat/issues/33). Don't even bother installing it. Unless bridge maintenance is resumed and fixes this issue, we have no choice but to remove it from the playbook." msgstr "" #: ../../../docs/configuring-playbook-bridge-wechat.md:17 @@ -57,7 +57,7 @@ msgid "`roles/custom/matrix-bridge-wechat/defaults/main.yml` for some variables msgstr "" #: ../../../docs/configuring-playbook-bridge-wechat.md:32 -msgid "`roles/custom/matrix-bridge-wechat/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_wechat_configuration_extension_yaml` variable" +msgid "`roles/custom/matrix-bridge-wechat/templates/config.yaml.j2` for the bridge's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_bridge_wechat_configuration_extension_yaml` variable" msgstr "" #: ../../../docs/configuring-playbook-bridge-wechat.md:34 diff --git a/i18n/translation-templates/docs/configuring-playbook-client-commet.pot b/i18n/translation-templates/docs/configuring-playbook-client-commet.pot new file mode 100644 index 000000000..703056783 --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-client-commet.pot @@ -0,0 +1,141 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-12 15:37+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-client-commet.md:7 +msgid "Setting up Commet (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:9 +msgid "The playbook can install and configure the [Commet](https://github.com/commetchat/commet) Matrix web client for you." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:11 +msgid "Adjusting DNS records" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:13 +msgid "By default, this playbook installs Commet on the `commet.` subdomain (`commet.example.com`) and requires you to create a CNAME record for `commet`, which targets `matrix.example.com`." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:15 +msgid "When setting, replace `example.com` with your own." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:17 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:19 +msgid "To enable Commet, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:25 +msgid "Adjusting the Commet URL (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:27 +msgid "By tweaking the `matrix_client_commet_hostname` and `matrix_client_commet_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:29 +msgid "Example additional configuration for your `vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:40 +msgid "After changing the domain, **you may need to adjust your DNS** records to point the Commet domain to the Matrix server." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:42 +msgid "If you've decided to reuse the `matrix.` domain, you won't need to do any extra DNS configuration." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:44 +msgid "**Note**: `matrix_client_commet_path_prefix` must either be `/` or not end with a slash (e.g. `/commet`)." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:46 +msgid "Adjusting the default homeserver (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:48 +msgid "Commet is configured with a `default_homeserver` value. By default, the playbook uses `matrix.org`." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:50 +msgid "To change it, add the following configuration to your `vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:56 +msgid "Adjusting the Commet version/branch to build (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:58 +msgid "When self-building the container image (`matrix_client_commet_container_image_self_build: true`), the playbook checks out the Commet source repository and builds an image from it." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:60 +msgid "To build from a different git branch/tag/SHA, set `matrix_client_commet_version` in your `vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:67 +msgid "**Note**: by default, the image tag is derived from `matrix_client_commet_version` (`localhost/matrix-client-commet:{{ matrix_client_commet_version }}`). If your branch name contains `/` (e.g. `feature/foo`), override `matrix_client_commet_container_image` (and optionally `matrix_client_commet_container_image_self_build_version_tag`) to a Docker-tag-safe value." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:69 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:71 +msgid "There are some additional things you may wish to configure about the component." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:73 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:75 +msgid "`roles/custom/matrix-client-commet/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:76 +msgid "`roles/custom/matrix-client-commet/templates/global_config.json.j2` for the component's default runtime configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:78 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:80 +msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:87 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:89 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:91 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-client-commet.md:93 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-client-commet`." +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-client-sable.pot b/i18n/translation-templates/docs/configuring-playbook-client-sable.pot new file mode 100644 index 000000000..b0d5f8090 --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-client-sable.pot @@ -0,0 +1,113 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-04-15 09:10+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-client-sable.md:9 +msgid "Setting up Sable (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:11 +msgid "The playbook can install and configure the [Sable](https://github.com/SableClient/Sable) Matrix web client for you." +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:13 +msgid "Sable is a web client focusing primarily on simple, elegant and secure interface. It can be installed alongside or instead of [Element Web](./configuring-playbook-client-element-web.md), [Cinny](./configuring-playbook-client-cinny.md) and others." +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:15 +msgid "Adjusting DNS records" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:17 +msgid "By default, this playbook installs Sable on the `sable.` subdomain (`sable.example.com`) and requires you to create a CNAME record for `sable`, which targets `matrix.example.com`." +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:19 +msgid "When setting, replace `example.com` with your own." +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:21 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:23 +msgid "To enable Sable, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:29 +msgid "Adjusting the Sable URL (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:31 +msgid "By tweaking the `sable_hostname` variable, you can easily make the service available at a **different hostname** than the default one." +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:33 +msgid "Example additional configuration for your `vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:43 +msgid "After changing the domain, **you may need to adjust your DNS** records to point the Sable domain to the Matrix server." +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:45 +msgid "**Note**: while there is a `sable_path_prefix` variable for changing the path where Sable is served, overriding it is [not possible](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3701), because Sable requires an application rebuild (with a tweaked build config) to be functional under a custom path. You'd need to serve Sable at a dedicated subdomain." +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:47 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:49 +msgid "There are some additional things you may wish to configure about the component." +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:51 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:53 +msgid "`roles/galaxy/sable/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:54 +msgid "`roles/galaxy/sable/templates/config.json.j2` for the component's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `sable_configuration_extension_json` variable" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:56 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:58 +msgid "After configuring the playbook and [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:65 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:67 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:69 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-client-sable.md:71 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-client-sable`." +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-conduit.pot b/i18n/translation-templates/docs/configuring-playbook-conduit.pot index c892615f9..120cff72b 100644 --- a/i18n/translation-templates/docs/configuring-playbook-conduit.pot +++ b/i18n/translation-templates/docs/configuring-playbook-conduit.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -32,10 +32,6 @@ msgstr "" msgid "By default, the playbook installs [Synapse](https://github.com/element-hq/synapse) as it's the only full-featured Matrix server at the moment. If that's okay, you can skip this document." msgstr "" -#: ../../../docs/configuring-playbook-conduit.md:16 -msgid "[!WARNING]" -msgstr "" - #: ../../../docs/configuring-playbook-conduit.md:17 msgid "**You can't switch an existing Matrix server's implementation** (e.g. Synapse -> Conduit). Proceed below only if you're OK with losing data or you're dealing with a server on a new domain name, which hasn't participated in the Matrix federation yet." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-conduwuit.pot b/i18n/translation-templates/docs/configuring-playbook-conduwuit.pot index 723493ed3..9e4133902 100644 --- a/i18n/translation-templates/docs/configuring-playbook-conduwuit.pot +++ b/i18n/translation-templates/docs/configuring-playbook-conduwuit.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -37,21 +37,29 @@ msgid "To uninstall the service, run the command below on the server:" msgstr "" #: ../../../docs/configuring-playbook-conduwuit.md:32 -msgid "Migrating to Continuwuity" +msgid "Migrating to Tuwunel" msgstr "" #: ../../../docs/configuring-playbook-conduwuit.md:34 -msgid "Since [Continuwuity](configuring-playbook-continuwuity.md) is a drop-in replacement for conduwuit, migration is possible. Please refer to [this section](./configuring-playbook-continuwuity.md#migrating-from-conduwuit) for details." +msgid "[Tuwunel](configuring-playbook-tuwunel.md) is a fork of conduwuit, [endorsed as conduwuit's successor](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/5200#issuecomment-4396211185) by the former conduwuit maintainer. It reads conduwuit's database directly, so migration is possible. Please refer to [this section](./configuring-playbook-tuwunel.md#migrating-from-conduwuit) for details." msgstr "" #: ../../../docs/configuring-playbook-conduwuit.md:36 -msgid "Removing data manually" +msgid "Migrating to Continuwuity" msgstr "" #: ../../../docs/configuring-playbook-conduwuit.md:38 -msgid "If you are not going to migrate to [Continuwuity](configuring-playbook-continuwuity.md), you can remove data by running the command on the server:" +msgid "Since [Continuwuity](configuring-playbook-continuwuity.md) is a drop-in replacement for conduwuit, migration is possible. Please refer to [this section](./configuring-playbook-continuwuity.md#migrating-from-conduwuit) for details." +msgstr "" + +#: ../../../docs/configuring-playbook-conduwuit.md:40 +msgid "Removing data manually" +msgstr "" + +#: ../../../docs/configuring-playbook-conduwuit.md:42 +msgid "If you are not going to migrate to [Tuwunel](configuring-playbook-tuwunel.md) or [Continuwuity](configuring-playbook-continuwuity.md), you can remove data by running the command on the server:" msgstr "" -#: ../../../docs/configuring-playbook-conduwuit.md:44 -msgid "[!WARNING] Once you removing the path, there is no going back. Your data on the homeserver (including chat history, rooms, etc.) will be deleted and not be possible to restore them. Please be certain." +#: ../../../docs/configuring-playbook-conduwuit.md:49 +msgid "Once you removing the path, there is no going back. Your data on the homeserver (including chat history, rooms, etc.) will be deleted and not be possible to restore them. Please be certain." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-continuwuity.pot b/i18n/translation-templates/docs/configuring-playbook-continuwuity.pot index 0d95a2676..2bb79c1d4 100644 --- a/i18n/translation-templates/docs/configuring-playbook-continuwuity.pot +++ b/i18n/translation-templates/docs/configuring-playbook-continuwuity.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -36,10 +36,6 @@ msgstr "" msgid "💡 **Note**: continuwuity is a fork of [conduwuit](./configuring-playbook-conduwuit.md), which the playbook has supported." msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:18 -msgid "[!WARNING]" -msgstr "" - #: ../../../docs/configuring-playbook-continuwuity.md:19 msgid "**You can't switch an existing Matrix server's implementation** (e.g. Synapse -> Continuwuity). Proceed below only if you're OK with losing data or you're dealing with a server on a new domain name, which hasn't participated in the Matrix federation yet." msgstr "" @@ -81,81 +77,97 @@ msgid "There are various Ansible variables that control settings in the `continu msgstr "" #: ../../../docs/configuring-playbook-continuwuity.md:49 +msgid "💡 By default, the playbook wires Continuwuity into a few playbook-wide settings:" +msgstr "" + +#: ../../../docs/configuring-playbook-continuwuity.md:51 +msgid "if `exim_relay_enabled: true` (the default), Continuwuity SMTP is automatically enabled and pointed at the [local Exim relay](configuring-playbook-email.md) service" +msgstr "" + +#: ../../../docs/configuring-playbook-continuwuity.md:52 +msgid "`matrix_continuwuity_config_well_known_client` is automatically set to the public homeserver URL in the usual SSL-enabled setup, which helps email verification and password-reset links work in delegated-domain setups" +msgstr "" + +#: ../../../docs/configuring-playbook-continuwuity.md:54 +msgid "You can override any of these defaults in your `vars.yml` file if you want Continuwuity to use a different SMTP server or a different well-known client URL." +msgstr "" + +#: ../../../docs/configuring-playbook-continuwuity.md:56 msgid "If a specific setting you'd like to change does not have a dedicated Ansible variable, you can either submit a PR to us to add it, or you can [override the setting using an environment variable](https://continuwuity.org/configuration#environment-variables) using `matrix_continuwuity_environment_variables_extension`. For example:" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:57 +#: ../../../docs/configuring-playbook-continuwuity.md:64 msgid "Creating the first user account" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:59 +#: ../../../docs/configuring-playbook-continuwuity.md:66 msgid "Unlike other homeserver implementations (like Synapse and Dendrite), continuwuity does not support creating users via the command line or via the playbook." msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:61 -msgid "If you followed the instructions above (see [Adjusting the playbook configuration](#adjusting-the-playbook-configuration)), you should have registration enabled and protected by a registration token." +#: ../../../docs/configuring-playbook-continuwuity.md:68 +msgid "On first startup, Continuwuity creates a special one-time-use registration token and logs it to the server's console. To access this, you will need to SSH into the server and run the following command:" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:63 -msgid "This should allow you to create the first user account via any client (like [Element Web](./configuring-playbook-client-element-web.md)) which supports creating users." +#: ../../../docs/configuring-playbook-continuwuity.md:75 +msgid "Find the token, highlight it, and copy it (ctrl+shift+C). This token should allow you to create the first user account via any client (like [Element Web](./configuring-playbook-client-element-web.md)) which supports creating users." msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:65 +#: ../../../docs/configuring-playbook-continuwuity.md:77 msgid "The **first user account that you create will be marked as an admin** and **will be automatically invited to an admin room**." msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:68 +#: ../../../docs/configuring-playbook-continuwuity.md:80 msgid "Configuring bridges / appservices" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:70 +#: ../../../docs/configuring-playbook-continuwuity.md:82 msgid "For other homeserver implementations (like Synapse and Dendrite), the playbook automatically registers appservices (for bridges, bots, etc.) with the homeserver." msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:72 +#: ../../../docs/configuring-playbook-continuwuity.md:84 msgid "For continuwuity, you will have to manually register appservices using the [`!admin appservices register` command](https://continuwuity.org/appservices.html#set-up-the-appservice---general-instructions) sent to the server bot account." msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:74 +#: ../../../docs/configuring-playbook-continuwuity.md:86 msgid "The server's bot account has a Matrix ID of `@conduit:example.com` (not `@continuwuity:example.com`!) due to continuwuity's historical legacy. Your first user account would already have been invited to an admin room with this bot." msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:77 +#: ../../../docs/configuring-playbook-continuwuity.md:89 msgid "Find the appservice file you'd like to register. This can be any `registration.yaml` file found in the `/matrix` directory, for example `/matrix/mautrix-signal/bridge/registration.yaml`." msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:79 +#: ../../../docs/configuring-playbook-continuwuity.md:91 msgid "Then, send its content to the existing admin room:" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:103 +#: ../../../docs/configuring-playbook-continuwuity.md:115 msgid "Migrating from conduwuit" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:105 +#: ../../../docs/configuring-playbook-continuwuity.md:117 msgid "Since Continuwuity is a drop-in replacement for [conduwuit](configuring-playbook-conduwuit.md), migration is possible." msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:107 +#: ../../../docs/configuring-playbook-continuwuity.md:119 msgid "Make sure that Continuwuity is properly set up on your `vars.yml` as described above" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:109 +#: ../../../docs/configuring-playbook-continuwuity.md:121 msgid "Make sure that Conduwuit references are removed from your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:111 +#: ../../../docs/configuring-playbook-continuwuity.md:123 msgid "Run the installation in a way that installs new services and uninstalls old ones (e.g. `just setup-all`)" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:113 +#: ../../../docs/configuring-playbook-continuwuity.md:125 msgid "Run the playbook with the `continuwuity-migrate-from-conduwuit` tag (e.g. `just run-tags continuwuity-migrate-from-conduwuit`). This migrates data from `/matrix/conduwuit` to `/matrix/continuwuity`" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:115 +#: ../../../docs/configuring-playbook-continuwuity.md:127 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-continuwuity.md:117 +#: ../../../docs/configuring-playbook-continuwuity.md:129 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-continuwuity`." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-dendrite.pot b/i18n/translation-templates/docs/configuring-playbook-dendrite.pot index be9195de0..48abb10ac 100644 --- a/i18n/translation-templates/docs/configuring-playbook-dendrite.pot +++ b/i18n/translation-templates/docs/configuring-playbook-dendrite.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -32,10 +32,6 @@ msgstr "" msgid "By default, the playbook installs [Synapse](https://github.com/element-hq/synapse) as it's the only full-featured Matrix server at the moment. If that's okay, you can skip this document." msgstr "" -#: ../../../docs/configuring-playbook-dendrite.md:17 -msgid "[!WARNING]" -msgstr "" - #: ../../../docs/configuring-playbook-dendrite.md:18 msgid "**You can't switch an existing Matrix server's implementation** (e.g. Synapse -> Dendrite). Proceed below only if you're OK with losing data or you're dealing with a server on a new domain name, which hasn't participated in the Matrix federation yet." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-element-admin.pot b/i18n/translation-templates/docs/configuring-playbook-element-admin.pot index 85129b8cd..ef0360a8a 100644 --- a/i18n/translation-templates/docs/configuring-playbook-element-admin.pot +++ b/i18n/translation-templates/docs/configuring-playbook-element-admin.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -33,7 +33,7 @@ msgid "See the project's [documentation](https://github.com/element-hq/element-a msgstr "" #: ../../../docs/configuring-playbook-element-admin.md:16 -msgid "💡 **Note**: This project is still very young and doesn't have many features. For now, it's recommended to use [Synapse Admin](./configuring-playbook-synapse-admin.md) instead. Deployments that use [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) can use Element Admin for user-management (something that Synapse Admin can't do), while continuing to use Synapse Admin for all other purposes." +msgid "💡 **Note**: This project is still very young and doesn't have many features. [Ketesa](./configuring-playbook-ketesa.md) is the fully-featured alternative — it covers all Synapse and MAS Admin APIs, including complete user management, session management, and MAS policy data. Element Admin remains a valid choice if you prefer its interface." msgstr "" #: ../../../docs/configuring-playbook-element-admin.md:18 @@ -92,8 +92,8 @@ msgstr "" msgid "Example additional configuration for your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-element-admin.md:53 -msgid "[!WARNING] A `matrix_element_admin_path_prefix` variable is also available and mean to let you configure a path prefix for the Element Admin service, but **Element Admin does not support running under a sub-path yet**." +#: ../../../docs/configuring-playbook-element-admin.md:54 +msgid "A `matrix_element_admin_path_prefix` variable is also available and mean to let you configure a path prefix for the Element Admin service, but **Element Admin does not support running under a sub-path yet**." msgstr "" #: ../../../docs/configuring-playbook-element-admin.md:56 diff --git a/i18n/translation-templates/docs/configuring-playbook-element-call.pot b/i18n/translation-templates/docs/configuring-playbook-element-call.pot index df198ee4d..d784e4a91 100644 --- a/i18n/translation-templates/docs/configuring-playbook-element-call.pot +++ b/i18n/translation-templates/docs/configuring-playbook-element-call.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -52,8 +52,8 @@ msgstr "" msgid "(Optional) Guest accounts being enabled for your Matrix server, if you'd like guests to be able to use Element Call. See [Allowing guests to use Element Call](#allowing-guests-to-use-element-call-optional)" msgstr "" -#: ../../../docs/configuring-playbook-element-call.md:23 -msgid "[!WARNING] Because Element Call [requires](https://github.com/element-hq/element-call/blob/93ae2aed9841e0b066d515c56bd4c122d2b591b2/docs/self-hosting.md#a-matrix-homeserver) a few experimental features in the Matrix protocol, it's **very likely that it only works with the Synapse homeserver**." +#: ../../../docs/configuring-playbook-element-call.md:24 +msgid "Because Element Call [requires](https://github.com/element-hq/element-call/blob/93ae2aed9841e0b066d515c56bd4c122d2b591b2/docs/self-hosting.md#a-matrix-homeserver) a few experimental features in the Matrix protocol, it's **very likely that it only works with the Synapse homeserver**." msgstr "" #: ../../../docs/configuring-playbook-element-call.md:26 @@ -192,8 +192,8 @@ msgstr "" msgid "Example additional configuration for your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-element-call.md:82 -msgid "[!WARNING] A `matrix_element_call_path_prefix` variable is also available and mean to let you configure a path prefix for the Element Call service, but [Element Call does not support running under a sub-path yet](https://github.com/element-hq/element-call/issues/3084)." +#: ../../../docs/configuring-playbook-element-call.md:83 +msgid "A `matrix_element_call_path_prefix` variable is also available and mean to let you configure a path prefix for the Element Call service, but [Element Call does not support running under a sub-path yet](https://github.com/element-hq/element-call/issues/3084)." msgstr "" #: ../../../docs/configuring-playbook-element-call.md:85 @@ -208,8 +208,8 @@ msgstr "" msgid "If you'd like guests to be able to use Element Call as well, you need to enable guest accounts support for your homeserver." msgstr "" -#: ../../../docs/configuring-playbook-element-call.md:91 -msgid "[!WARNING] Enabling guest accounts means that your homeserver's user database may get polluted with guest account signups (potentially made by bots). Guest accounts should be limited in what (damage) they can do to your server and the rest of the Matrix ecosystem, but it's better to not enable them unless necessary." +#: ../../../docs/configuring-playbook-element-call.md:92 +msgid "Enabling guest accounts means that your homeserver's user database may get polluted with guest account signups (potentially made by bots). Guest accounts should be limited in what (damage) they can do to your server and the rest of the Matrix ecosystem, but it's better to not enable them unless necessary." msgstr "" #: ../../../docs/configuring-playbook-element-call.md:95 diff --git a/i18n/translation-templates/docs/configuring-playbook-email.pot b/i18n/translation-templates/docs/configuring-playbook-email.pot index 1f56396e5..21abb8f93 100644 --- a/i18n/translation-templates/docs/configuring-playbook-email.pot +++ b/i18n/translation-templates/docs/configuring-playbook-email.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-07 11:16+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,89 +41,109 @@ msgid "📁 `roles/galaxy/exim_relay/docs/configuring-exim-relay.md` locally, if msgstr "" #: ../../../docs/configuring-playbook-email.md:20 -msgid "Firewall settings" +msgid "Why use exim-relay?" msgstr "" #: ../../../docs/configuring-playbook-email.md:22 -msgid "No matter whether you send email directly (the default) or you relay email through another host, you'll probably need to allow outgoing traffic for TCP ports 25/587 (depending on configuration)." +msgid "**Benefits of using exim-relay** instead of configuring SMTP directly in each service:" msgstr "" #: ../../../docs/configuring-playbook-email.md:24 -msgid "Docker automatically opens these ports in the server's firewall, so you likely don't need to do anything. If you use another firewall in front of the server, you may need to adjust it." +msgid "**Final delivery capability**: Can deliver emails directly if you don't have an SMTP server" msgstr "" #: ../../../docs/configuring-playbook-email.md:26 -msgid "Adjusting the playbook configuration" +msgid "**Centralized configuration**: Configure your upstream SMTP server once in exim-relay, then point all services ([Synapse](configuring-playbook-synapse.md), [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md), [Continuwuity](configuring-playbook-continuwuity.md), etc.) there, with no need to configure SMTP in each component" msgstr "" #: ../../../docs/configuring-playbook-email.md:28 -msgid "Enable DKIM authentication to improve deliverability (optional)" +msgid "**Local spooling**: Stores messages locally and retries delivery if your upstream SMTP server is temporarily unavailable" msgstr "" #: ../../../docs/configuring-playbook-email.md:30 -msgid "By default, exim-relay attempts to deliver emails directly. This may or may not work, depending on your domain configuration." +msgid "Firewall settings" msgstr "" #: ../../../docs/configuring-playbook-email.md:32 -msgid "To improve email deliverability, you can configure authentication methods such as DKIM (DomainKeys Identified Mail), SPF, and DMARC for your domain. Without setting any of these authentication methods, your outgoing email is most likely to be quarantined as spam at recipient's mail servers." +msgid "No matter whether you send email directly (the default) or you relay email through another host, you'll probably need to allow outgoing traffic for TCP ports 25/587 (depending on configuration)." msgstr "" #: ../../../docs/configuring-playbook-email.md:34 -msgid "For details about configuring DKIM, refer [this section](https://github.com/mother-of-all-self-hosting/ansible-role-exim-relay/blob/main/docs/configuring-exim-relay.md#enable-dkim-support-optional) on the role's documentation." +msgid "Docker automatically opens these ports in the server's firewall, so you likely don't need to do anything. If you use another firewall in front of the server, you may need to adjust it." msgstr "" #: ../../../docs/configuring-playbook-email.md:36 -msgid "💡 If you cannot enable DKIM, SPF, or DMARC on your domain for some reason, we recommend relaying email through another SMTP server." +msgid "Adjusting the playbook configuration" msgstr "" #: ../../../docs/configuring-playbook-email.md:38 -msgid "Relaying email through another SMTP server (optional)" +msgid "Enable DKIM authentication to improve deliverability (optional)" msgstr "" #: ../../../docs/configuring-playbook-email.md:40 -msgid "**On some cloud providers such as Google Cloud, [port 25 is always blocked](https://cloud.google.com/compute/docs/tutorials/sending-mail/), so sending email directly from your server is not possible.** In this case, you will need to relay email through another SMTP server." +msgid "By default, exim-relay attempts to deliver emails directly. This may or may not work, depending on your domain configuration." msgstr "" #: ../../../docs/configuring-playbook-email.md:42 -msgid "For details about configuration, refer [this section](https://github.com/mother-of-all-self-hosting/ansible-role-exim-relay/blob/main/docs/configuring-exim-relay.md#relaying-email-through-another-smtp-server) on the role's document." +msgid "To improve email deliverability, you can configure authentication methods such as DKIM (DomainKeys Identified Mail), SPF, and DMARC for your domain. Without setting any of these authentication methods, your outgoing email is most likely to be quarantined as spam at recipient's mail servers." msgstr "" #: ../../../docs/configuring-playbook-email.md:44 -msgid "Disable mail service (optional)" +msgid "For details about configuring DKIM, refer [this section](https://github.com/mother-of-all-self-hosting/ansible-role-exim-relay/blob/main/docs/configuring-exim-relay.md#enable-dkim-support-optional) on the role's documentation." msgstr "" #: ../../../docs/configuring-playbook-email.md:46 -msgid "For a low-power server you might probably want to disable exim-relay. To do so, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgid "💡 If you cannot enable DKIM, SPF, or DMARC on your domain for some reason, we recommend relaying email through another SMTP server." +msgstr "" + +#: ../../../docs/configuring-playbook-email.md:48 +msgid "Relaying email through another SMTP server (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-email.md:50 +msgid "**On some cloud providers such as Google Cloud, [port 25 is always blocked](https://cloud.google.com/compute/docs/tutorials/sending-mail/), so sending email directly from your server is not possible.** In this case, you will need to relay email through another SMTP server." msgstr "" #: ../../../docs/configuring-playbook-email.md:52 -msgid "Note that disabling exim-relay will stop email-notifications and other similar functions from working." +msgid "For details about configuration, refer [this section](https://github.com/mother-of-all-self-hosting/ansible-role-exim-relay/blob/main/docs/configuring-exim-relay.md#relaying-email-through-another-smtp-server) on the role's document." msgstr "" #: ../../../docs/configuring-playbook-email.md:54 -msgid "See [this entry on the FAQ](faq.md#how-do-i-optimize-this-setup-for-a-low-power-server) for other possible optimizations for a low-power server." +msgid "Disable mail service (optional)" msgstr "" #: ../../../docs/configuring-playbook-email.md:56 +msgid "For a low-power server you might probably want to disable exim-relay. To do so, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-email.md:62 +msgid "Note that disabling exim-relay will stop email-notifications and other similar functions from working." +msgstr "" + +#: ../../../docs/configuring-playbook-email.md:64 +msgid "See [this entry on the FAQ](faq.md#how-do-i-optimize-this-setup-for-a-low-power-server) for other possible optimizations for a low-power server." +msgstr "" + +#: ../../../docs/configuring-playbook-email.md:66 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-email.md:58 +#: ../../../docs/configuring-playbook-email.md:68 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-email.md:65 +#: ../../../docs/configuring-playbook-email.md:75 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-email.md:67 +#: ../../../docs/configuring-playbook-email.md:77 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-email.md:69 +#: ../../../docs/configuring-playbook-email.md:79 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-email.md:71 +#: ../../../docs/configuring-playbook-email.md:81 msgid "See [this section](https://github.com/mother-of-all-self-hosting/ansible-role-exim-relay/blob/main/docs/configuring-exim-relay.md#troubleshooting) on the role's documentation for details." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-federation.pot b/i18n/translation-templates/docs/configuring-playbook-federation.pot index 2b7dea842..cda7f7153 100644 --- a/i18n/translation-templates/docs/configuring-playbook-federation.pot +++ b/i18n/translation-templates/docs/configuring-playbook-federation.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,15 +41,15 @@ msgid "If you wish to disable federation, you can do that with an empty list (`[ msgstr "" #: ../../../docs/configuring-playbook-federation.md:27 -msgid "Exposing the room directory over federation" +msgid "Controlling exposure of the room directory over federation" msgstr "" #: ../../../docs/configuring-playbook-federation.md:29 -msgid "By default, your server's public rooms directory is not exposed to other servers via federation." +msgid "By default, your server's public rooms directory is exposed to other servers via federation, so that public rooms hosted on your server can be discovered by users on other servers. This goes against the Synapse upstream default (which is `false`); see the [2023-10-23 changelog entry](../CHANGELOG.md#enabling-allow_public_rooms_over_federation-by-default-for-synapse) for the reasoning behind this choice." msgstr "" #: ../../../docs/configuring-playbook-federation.md:31 -msgid "To expose it, add the following configuration to your `vars.yml` file:" +msgid "To prevent your public rooms directory from being exposed over federation (restoring the Synapse upstream default), add the following configuration to your `vars.yml` file:" msgstr "" #: ../../../docs/configuring-playbook-federation.md:37 @@ -81,5 +81,9 @@ msgid "To make it possible to proxy the federation through a CDN such as CloudFl msgstr "" #: ../../../docs/configuring-playbook-federation.md:74 +msgid "**Note**: `matrix_synapse_federation_port_enabled: false` only makes sense in this specific setup, where federation traffic is served through the client port (because of the `federation` entry in `matrix_synapse_http_listener_resource_names`). If federation still flows through the dedicated federation port on your setup (e.g. another reverse proxy of yours forwarding a custom public port to this playbook's federation port), leave `matrix_synapse_federation_port_enabled` at its default (enabled). Disabling it removes the federation route entirely and breaks such setups." +msgstr "" + +#: ../../../docs/configuring-playbook-federation.md:76 msgid "**Use this at you own risk as all the possible side-effects of doing this are not fully known. However, it has been tested and works fine and passes all the tests on without issues.**" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-jitsi.pot b/i18n/translation-templates/docs/configuring-playbook-jitsi.pot index 52954c44b..db10963e1 100644 --- a/i18n/translation-templates/docs/configuring-playbook-jitsi.pot +++ b/i18n/translation-templates/docs/configuring-playbook-jitsi.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -25,149 +25,153 @@ msgid "The playbook can install and configure the [Jitsi](https://jitsi.org/) vi msgstr "" #: ../../../docs/configuring-playbook-jitsi.md:21 +msgid "Because Jitsi still requires a TURN server, enabling Jitsi automatically enables coturn (`coturn_enabled: true`) unless you explicitly disable it." +msgstr "" + +#: ../../../docs/configuring-playbook-jitsi.md:24 msgid "Jitsi is an open source video-conferencing platform. It can not only be integrated with Element clients ([Element Web](configuring-playbook-client-element-web.md)/Desktop, Android and iOS) as a widget, but also be used as standalone web app." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:23 +#: ../../../docs/configuring-playbook-jitsi.md:26 msgid "💡 If you're into experimental technology, you may also be interested in trying out [Element Call](configuring-playbook-element-call.md) - a native Matrix video conferencing application." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:25 +#: ../../../docs/configuring-playbook-jitsi.md:28 msgid "The [Ansible role for Jitsi](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi) is developed and maintained by [the MASH (mother-of-all-self-hosting) project](https://github.com/mother-of-all-self-hosting). For details about configuring Jitsi, you can check them via:" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:26 +#: ../../../docs/configuring-playbook-jitsi.md:29 msgid "🌐 [the role's documentation at the MASH project](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md) online" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:27 +#: ../../../docs/configuring-playbook-jitsi.md:30 msgid "📁 `roles/galaxy/jitsi/docs/configuring-jitsi.md` locally, if you have [fetched the Ansible roles](installing.md#update-ansible-roles)" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:29 +#: ../../../docs/configuring-playbook-jitsi.md:32 msgid "Prerequisites" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:31 +#: ../../../docs/configuring-playbook-jitsi.md:34 msgid "Before proceeding, make sure to check server's requirements recommended by [the official deployment guide](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-requirements)." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:33 +#: ../../../docs/configuring-playbook-jitsi.md:36 msgid "You may need to open some ports to your server, if you use another firewall in front of the server. Refer [the role's documentation](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md#prerequisites) to check which ones to be configured." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:35 +#: ../../../docs/configuring-playbook-jitsi.md:38 msgid "Adjusting DNS records" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:37 +#: ../../../docs/configuring-playbook-jitsi.md:40 msgid "By default, this playbook installs Jitsi on the `jitsi.` subdomain (`jitsi.example.com`) and requires you to create a CNAME record for `jitsi`, which targets `matrix.example.com`." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:39 +#: ../../../docs/configuring-playbook-jitsi.md:42 msgid "When setting, replace `example.com` with your own." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:41 +#: ../../../docs/configuring-playbook-jitsi.md:44 msgid "Adjusting the playbook configuration" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:43 +#: ../../../docs/configuring-playbook-jitsi.md:46 msgid "To enable Jitsi, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:61 +#: ../../../docs/configuring-playbook-jitsi.md:64 msgid "As the most of the necessary settings for the role have been taken care of by the playbook, you can enable Jitsi on your Matrix server with this minimum configuration." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:63 +#: ../../../docs/configuring-playbook-jitsi.md:66 msgid "However, **since Jitsi's performance heavily depends on server resource (bandwidth, RAM, and CPU), it is recommended to review settings and optimize them as necessary before deployment.** You can check [here](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md#example-configurations) for an example set of configurations to set up a Jitsi instance, focusing on performance. If you will host a large conference, you probably might also want to consider to provision additional JVBs ([Jitsi VideoBridge](https://github.com/jitsi/jitsi-videobridge)). See [here](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md#set-up-additional-jvbs-for-more-video-conferences-optional) for details about setting them up with the playbook." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:65 +#: ../../../docs/configuring-playbook-jitsi.md:68 msgid "See the role's documentation for details about configuring Jitsi per your preference (such as setting [a custom hostname](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md#set-the-hostname) and [the environment variable for running Jitsi in a LAN](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md#configure-jvb_advertise_ips-for-running-behind-nat-or-on-a-lan-environment-optional))." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:67 +#: ../../../docs/configuring-playbook-jitsi.md:70 msgid "Enable authentication and guests mode (optional)" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:69 +#: ../../../docs/configuring-playbook-jitsi.md:72 msgid "By default the Jitsi Meet instance **does not require for anyone to log in, and is open to use without an account**." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:71 +#: ../../../docs/configuring-playbook-jitsi.md:74 msgid "If you would like to control who is allowed to start meetings on your instance, you'd need to enable Jitsi's authentication and optionally guests mode." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:73 +#: ../../../docs/configuring-playbook-jitsi.md:76 msgid "See [this section](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md#configure-jitsi-authentication-and-guests-mode-optional) on the role's documentation for details about how to configure the authentication and guests mode. The recommended authentication method is `internal` as it also works in federated rooms. If you want to enable authentication with Matrix OpenID making use of [Matrix User Verification Service (UVS)](configuring-playbook-user-verification-service.md), see [here](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md#authenticate-using-matrix-openid-auth-type-matrix) for details about how to set it up." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:75 +#: ../../../docs/configuring-playbook-jitsi.md:78 msgid "Enable Gravatar (optional)" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:77 +#: ../../../docs/configuring-playbook-jitsi.md:80 msgid "In the default Jisti Meet configuration, `gravatar.com` is enabled as an avatar service." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:79 +#: ../../../docs/configuring-playbook-jitsi.md:82 msgid "Since the Element clients send the URL of configured Matrix avatars to the Jitsi instance, our configuration has disabled the Gravatar service." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:81 +#: ../../../docs/configuring-playbook-jitsi.md:84 msgid "To enable the Gravatar service nevertheless, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:87 -msgid "[!WARNING] This will result in third party request leaking data to the Gravatar Service (`gravatar.com`, unless configured otherwise). Besides metadata, the Matrix user_id and possibly the room ID (via `referrer` header) will be also sent to the third party." +#: ../../../docs/configuring-playbook-jitsi.md:91 +msgid "This will result in third party request leaking data to the Gravatar Service (`gravatar.com`, unless configured otherwise). Besides metadata, the Matrix user_id and possibly the room ID (via `referrer` header) will be also sent to the third party." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:90 +#: ../../../docs/configuring-playbook-jitsi.md:93 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:92 +#: ../../../docs/configuring-playbook-jitsi.md:95 msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:99 +#: ../../../docs/configuring-playbook-jitsi.md:102 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:101 +#: ../../../docs/configuring-playbook-jitsi.md:104 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:103 +#: ../../../docs/configuring-playbook-jitsi.md:106 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:105 +#: ../../../docs/configuring-playbook-jitsi.md:108 msgid "You can use the self-hosted Jitsi server in multiple ways:" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:107 +#: ../../../docs/configuring-playbook-jitsi.md:110 msgid "**by adding a widget to a room via Element Web** (the one configured by the playbook at `https://element.example.com`). Just start a voice or a video call in a room containing more than 2 members and that would create a Jitsi widget which utilizes your self-hosted Jitsi server." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:109 +#: ../../../docs/configuring-playbook-jitsi.md:112 msgid "**directly (without any Matrix integration)**. Just go to `https://jitsi.example.com`, and you can start a videoconference." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:111 +#: ../../../docs/configuring-playbook-jitsi.md:114 msgid "Note that you'll need to log in to your Jitsi's account to start a conference if you have configured authentication with `internal` auth." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:113 +#: ../../../docs/configuring-playbook-jitsi.md:116 msgid "Check [the official user guide](https://jitsi.github.io/handbook/docs/category/user-guide) for details about how to use Jitsi." msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:115 +#: ../../../docs/configuring-playbook-jitsi.md:118 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-jitsi.md:117 +#: ../../../docs/configuring-playbook-jitsi.md:120 msgid "See [this section](https://github.com/mother-of-all-self-hosting/ansible-role-jitsi/blob/main/docs/configuring-jitsi.md#troubleshooting) on the role's documentation for details." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-jwt-service.pot b/i18n/translation-templates/docs/configuring-playbook-jwt-service.pot deleted file mode 100644 index db0a12f43..000000000 --- a/i18n/translation-templates/docs/configuring-playbook-jwt-service.pot +++ /dev/null @@ -1,93 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members -# This file is distributed under the same license as the matrix-docker-ansible-deploy package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: matrix-docker-ansible-deploy \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../../docs/configuring-playbook-jwt-service.md:8 -msgid "Setting up JWT Service (optional)" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:10 -msgid "The playbook can install and configure [LiveKit JWT Service](https://github.com/element-hq/lk-jwt-service) for you." -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:12 -msgid "LK-JWT-Service is currently used for a single reason: generate JWT tokens with a given identity for a given room, so that users can use them to authenticate against LiveKit SFU." -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:14 -msgid "See the project's [documentation](https://github.com/element-hq/lk-jwt-service/) to learn more." -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:16 -msgid "Decide on a domain and path" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:18 -msgid "By default, JWT Service is configured to be served:" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:20 -msgid "on the Matrix domain (`matrix.example.com`), configurable via `matrix_livekit_jwt_service_hostname`" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:21 -msgid "under a `/livekit-jwt-service` path prefix, configurable via `matrix_livekit_jwt_service_path_prefix`" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:23 -msgid "This makes it easy to set it up, **without** having to adjust your DNS records manually." -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:25 -msgid "Adjusting DNS records" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:27 -msgid "If you've changed the default hostname, **you may need to adjust your DNS** records accordingly to point to the correct server." -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:29 -msgid "Adjusting the playbook configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:31 -msgid "Add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:37 -msgid "Installing" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:39 -msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the [installation](installing.md) command: `just install-all` or `just setup-all`" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:41 -msgid "Usage" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:43 -msgid "Once installed, a new `org.matrix.msc4143.rtc_foci` section is added to the Element Web client to point to your JWT service URL (e.g., `https://matrix.example.com/livekit-jwt-service`)." -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:45 -msgid "Additional Information" -msgstr "" - -#: ../../../docs/configuring-playbook-jwt-service.md:47 -msgid "Refer to the LiveKit JWT-Service documentation for more details on configuring and using JWT Service." -msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-ketesa.pot b/i18n/translation-templates/docs/configuring-playbook-ketesa.pot new file mode 100644 index 000000000..49f9f0ed8 --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-ketesa.pot @@ -0,0 +1,161 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-19 03:41+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-ketesa.md:14 +msgid "Setting up Ketesa (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:16 +msgid "The playbook can install and configure [Ketesa](https://ketesa.app) ([source code](https://github.com/etkecc/ketesa)) for you." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:18 +msgid "Ketesa is a fully-featured admin interface for Matrix homeservers — manage users, rooms, media, sessions, and more from one clean, responsive web UI. It is the evolution of [Awesome-Technologies/synapse-admin](https://github.com/Awesome-Technologies/synapse-admin): what began as a fork has grown into its own independent project with a redesigned interface, comprehensive Synapse and MAS API coverage, and multi-language support. See the [Ketesa v1.0.0 announcement](https://etke.cc/blog/introducing-ketesa/) for a full overview of what's new." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:22 +msgid "Ketesa does not work with other homeserver implementations than Synapse due to API's incompatibility." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:23 +msgid "The latest version of Ketesa is hosted by [etke.cc](https://etke.cc/) at [cloud.ketesa.app](https://cloud.ketesa.app/). If you only need this service occasionally and trust giving your admin credentials to a 3rd party Single Page Application, you can consider using it from there and avoiding the (small) overhead of self-hosting." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:24 +msgid "This playbook also supports an alternative management UI in the shape of [Element Admin](./configuring-playbook-element-admin.md). Please note that it's currently less feature-rich than Ketesa and requires [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md)." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:26 +msgid "Adjusting DNS records (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:28 +msgid "By default, this playbook installs Ketesa on the `matrix.` subdomain, at the `/synapse-admin` path (https://matrix.example.com/synapse-admin) — the legacy path is kept for backward compatibility. This makes it easy to install it, because it **doesn't require additional DNS records to be set up**. If that's okay, you can skip this section." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:30 +msgid "If you wish to adjust it, see the section [below](#adjusting-the-ketesa-url-optional) for details about DNS configuration." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:32 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:34 +msgid "To enable Ketesa, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:40 +msgid "**Note**: Ketesa requires Synapse's [Admin APIs](https://element-hq.github.io/synapse/latest/usage/administration/admin_api/index.html) to function. Access to them is restricted with a valid access token, so exposing them publicly should not be a real security concern. Still, for additional security, we normally leave them unexposed, following [official Synapse reverse-proxying recommendations](https://element-hq.github.io/synapse/latest/reverse_proxy.html#synapse-administration-endpoints). Because Ketesa needs these APIs to function, when installing Ketesa, the playbook **automatically** exposes the Synapse Admin API publicly for you. Depending on the homeserver implementation you're using (Synapse, Dendrite), this is equivalent to:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:42 +msgid "for [Synapse](./configuring-playbook-synapse.md) (our default homeserver implementation): `matrix_synapse_container_labels_public_client_synapse_admin_api_enabled: true`" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:43 +msgid "for [Dendrite](./configuring-playbook-dendrite.md): `matrix_dendrite_container_labels_public_client_synapse_admin_api_enabled: true`" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:44 +msgid "for [Tuwunel](./configuring-playbook-tuwunel.md): `matrix_tuwunel_container_labels_public_client_synapse_admin_api_enabled: true`" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:46 +msgid "By default, Ketesa installation will be [restricted to only work with one homeserver](https://github.com/etkecc/ketesa/blob/main/README.md#restricting-available-homeserver) — the one managed by the playbook. To adjust these restrictions, tweak the `matrix_ketesa_config_restrictBaseUrl` variable." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:48 +msgid "Adjusting the Ketesa URL (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:50 +msgid "By tweaking the `matrix_ketesa_hostname` and `matrix_ketesa_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:52 +msgid "We recommend updating the path prefix to `/ketesa` to align with the new branding, while the default `/synapse-admin` is kept for backward compatibility:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:58 +msgid "Or to change the hostname entirely:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:66 +msgid "If you've changed the default hostname, you may need to create a CNAME record for the Ketesa domain (`admin.example.com`), which targets `matrix.example.com`." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:68 +msgid "When setting, replace `example.com` with your own." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:70 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:72 +msgid "There are some additional things you may wish to configure about the component." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:74 +msgid "Take a look at:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:76 +msgid "`roles/custom/matrix-ketesa/defaults/main.yml` for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_ketesa_configuration_extension_json` variable" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:78 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:80 +msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:87 +msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:89 +msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:91 +msgid "Usage" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:93 +msgid "After installation, Ketesa will be accessible at: `https://matrix.example.com/synapse-admin/` (or `/ketesa/` if you updated the path prefix as recommended)" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:95 +msgid "To use Ketesa, you need to have [registered at least one administrator account](registering-users.md) on your server." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:97 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:99 +msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-ketesa`." +msgstr "" + +#: ../../../docs/configuring-playbook-ketesa.md:101 +msgid "If you have questions, you can join this community room and feel free to ask: [#ketesa:etke.cc](https://matrix.to/#/#ketesa:etke.cc)" +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-ldap-auth.pot b/i18n/translation-templates/docs/configuring-playbook-ldap-auth.pot index 93e7c826e..a301a94c9 100644 --- a/i18n/translation-templates/docs/configuring-playbook-ldap-auth.pot +++ b/i18n/translation-templates/docs/configuring-playbook-ldap-auth.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-06-29 17:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -25,7 +25,7 @@ msgid "The playbook can install and configure the [matrix-synapse-ldap3](https:/ msgstr "" #: ../../../docs/configuring-playbook-ldap-auth.md:14 -msgid "See the project's [documentation](https://github.com/matrix-org/matrix-synapse-ldap3/blob/main/README.rst) to learn what it does and why it might be useful to you." +msgid "See the project's [documentation](https://github.com/matrix-org/matrix-synapse-ldap3/blob/main/README.md) to learn what it does and why it might be useful to you." msgstr "" #: ../../../docs/configuring-playbook-ldap-auth.md:16 @@ -59,15 +59,3 @@ msgstr "" #: ../../../docs/configuring-playbook-ldap-auth.md:54 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" - -#: ../../../docs/configuring-playbook-ldap-auth.md:56 -msgid "Usage" -msgstr "" - -#: ../../../docs/configuring-playbook-ldap-auth.md:58 -msgid "Handling user registration" -msgstr "" - -#: ../../../docs/configuring-playbook-ldap-auth.md:60 -msgid "If you wish for users to also be able to make new registrations against LDAP, you may **also** wish to [set up the ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md)." -msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-livekit-server.pot b/i18n/translation-templates/docs/configuring-playbook-livekit-server.pot index 000f0b883..46e8c1285 100644 --- a/i18n/translation-templates/docs/configuring-playbook-livekit-server.pot +++ b/i18n/translation-templates/docs/configuring-playbook-livekit-server.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-18 07:22+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -41,7 +41,7 @@ msgid "🌐 [the role's documentation at the MASH project](https://github.com/mo msgstr "" #: ../../../docs/configuring-playbook-livekit-server.md:18 -msgid "📁 `roles/galaxy/livekit-server/docs/configuring-livekit-server.md` locally, if you have [fetched the Ansible roles](installing.md#update-ansible-roles)" +msgid "📁 `roles/galaxy/livekit_server/docs/configuring-livekit-server.md` locally, if you have [fetched the Ansible roles](installing.md#update-ansible-roles)" msgstr "" #: ../../../docs/configuring-playbook-livekit-server.md:20 @@ -69,17 +69,81 @@ msgid "`5350/tcp`: TURN/TCP. Also see the [Limitations](#limitations) section be msgstr "" #: ../../../docs/configuring-playbook-livekit-server.md:32 -msgid "💡 The suggestions above are inspired by the upstream [Ports and Firewall](https://docs.livekit.io/home/self-hosting/ports-firewall/) documentation based on how LiveKit is configured in the playbook. If you've using custom configuration for the LiveKit Server role, you may need to adjust the firewall rules accordingly." +msgid "`30000-30020/udp`: TURN relay range used by LiveKit's embedded TURN server." msgstr "" #: ../../../docs/configuring-playbook-livekit-server.md:34 -msgid "Limitations" +msgid "💡 The suggestions above are inspired by the upstream [Ports and Firewall](https://docs.livekit.io/home/self-hosting/ports-firewall/) documentation based on how LiveKit is configured in the playbook. If you're using custom configuration for the LiveKit Server role, you may need to adjust firewall rules accordingly." msgstr "" #: ../../../docs/configuring-playbook-livekit-server.md:36 -msgid "For some reason, LiveKit Server's TURN ports (`3479/udp` and `5350/tcp`) are not reachable over IPv6 regardless of whether you've [enabled IPv6](./configuring-ipv6.md) for your server." +msgid "TURN TLS handling" msgstr "" #: ../../../docs/configuring-playbook-livekit-server.md:38 -msgid "It seems like LiveKit Server intentionally only listens on `udp4` and `tcp4` as seen [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L128) and [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L92)." +msgid "When `matrix_playbook_reverse_proxy_type` is `playbook-managed-traefik` (which is the default for this playbook), TURN over TCP is terminated by Traefik and forwarded to LiveKit with `turn.external_tls = true`. In this playbook default, this mode is enabled automatically when SSL is enabled and TURN is enabled." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:40 +msgid "The playbook installs a dedicated Traefik TCP entrypoint for TURN (`matrix-livekit-turn`) by default and binds it to `tcp/5350`." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:41 +msgid "`livekit_server_config_turn_external_tls` is automatically enabled for this setup." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:42 +msgid "Because Traefik handles TLS, LiveKit no longer needs certificate-file paths for TURN in this mode." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:44 +msgid "To opt out and keep TURN TLS termination in LiveKit itself, set:" +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:50 +msgid "In this playbook, certificate paths are managed automatically via `group_vars/matrix_servers` when certificate dumping is enabled." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:52 +msgid "If your setup uses `other-traefik-container` or [another reverse-proxy](./configuring-playbook-own-webserver.md), behavior is unchanged by default and still relies on certificates being available inside the container as before." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:54 +msgid "Deployments using `other-traefik-container` can opt into the same Traefik-terminated mode there, by setting:" +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:62 +msgid "and configuring their own Traefik TCP entrypoint dedicated to LiveKit TURN traffic." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:64 +msgid "TURN access controls" +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:66 +msgid "LiveKit's embedded TURN server enforces a credential TTL and restricts which peer CIDRs it will relay to. The playbook leaves these at the role's secure defaults, which are appropriate for typical deployments where TURN peers live on the public Internet." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:68 +msgid "If your setup needs TURN to relay to private/restricted ranges, or you want to override the credential TTL, see the [TURN access controls and credential TTL](https://github.com/mother-of-all-self-hosting/ansible-role-livekit-server/blob/main/docs/configuring-livekit-server.md#turn-access-controls-and-credential-ttl) section of the role's documentation." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:70 +msgid "Limitations" +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:72 +msgid "LiveKit Server's TURN listener behavior depends on where TLS is terminated:" +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:74 +msgid "Direct LiveKit TURN listeners (`livekit_server_config_turn_external_tls: false`) still use IPv4-only sockets for `3479/udp` and `5350/tcp`, so IPv6 connectivity to these endpoints is not possible." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:75 +msgid "With [TURN TLS handling](#turn-tls-handling) (`livekit_server_config_turn_external_tls: true`), the playbook's dedicated `matrix-livekit-turn` TCP entrypoint can still listen on both IPv4 and IPv6. Traefik then forwards TURN/TCP to LiveKit." +msgstr "" + +#: ../../../docs/configuring-playbook-livekit-server.md:77 +msgid "It appears that LiveKit Server intentionally only listens on `udp4` and `tcp4` in direct mode, as seen [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L128) and [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L92)." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-matrix-authentication-service.pot b/i18n/translation-templates/docs/configuring-playbook-matrix-authentication-service.pot index 9baf8c970..a35e6b8e3 100644 --- a/i18n/translation-templates/docs/configuring-playbook-matrix-authentication-service.pot +++ b/i18n/translation-templates/docs/configuring-playbook-matrix-authentication-service.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -113,7 +113,7 @@ msgid "❌ **Synapse password providers will need to be disabled**. You can no l msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:54 -msgid "❌ Certain **tools like [Synapse Admin](./configuring-playbook-synapse-admin.md) do not have full compatibility with MAS yet**. Synapse Admin already supports OIDC auth, browsing users (which Synapse will internally fetch from MAS) and updating user avatars. However, editing users (passwords, etc.) now needs to happen directly against MAS using the [MAS Admin API](https://element-hq.github.io/matrix-authentication-service/api/index.html), which Synapse Admin cannot interact with yet. You may be interested in using [Element Admin](./configuring-playbook-element-admin.md) for these purposes." +msgid "✅ **[Ketesa](./configuring-playbook-ketesa.md) has full MAS integration**. Ketesa supports OIDC auth, user management, all session types (browser, OAuth2, compatibility), linked email addresses, upstream OAuth provider links, MAS policy data, and user creation through MAS. It is the recommended tool for managing homeservers running MAS." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:56 @@ -514,105 +514,109 @@ msgid "To perform a real migration, run the `matrix-authentication-service-mas-c msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:401 -msgid "Having performed a `syn2mas` migration once, trying to do it again will report errors (e.g. \"Error: The MAS database is not empty: rows found in at least `users`. Please drop and recreate the database, then try again.\")." +msgid "After `syn2mas` completes, Synapse will intentionally remain stopped to avoid new registrations or other authentication changes from being accepted before the migration is completed. Continue with the next steps in this guide before re-running the installation." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:403 -msgid "Verify that Matrix Authentication Service is installed correctly" +msgid "Having performed a `syn2mas` migration once, trying to do it again will report errors (e.g. \"Error: The MAS database is not empty: rows found in at least `users`. Please drop and recreate the database, then try again.\")." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:405 -msgid "After [installation](#installing), run the `doctor` subcommand of the [`mas-cli` command-line tool](https://element-hq.github.io/matrix-authentication-service/reference/cli/index.html) to verify that MAS is installed correctly." +msgid "Verify that Matrix Authentication Service is installed correctly" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:407 -msgid "You can do it:" +msgid "After [installation](#installing), run the `doctor` subcommand of the [`mas-cli` command-line tool](https://element-hq.github.io/matrix-authentication-service/reference/cli/index.html) to verify that MAS is installed correctly." msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:409 -msgid "either via the Ansible playbook's `matrix-authentication-service-mas-cli-doctor` tag: `just run-tags matrix-authentication-service-mas-cli-doctor`" +msgid "You can do it:" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:411 -msgid "or by running the `mas-cli` script on the server (which invokes the `mas-cli` tool inside a container): `/matrix/matrix-authentication-service/bin/mas-cli doctor`" +msgid "either via the Ansible playbook's `matrix-authentication-service-mas-cli-doctor` tag: `just run-tags matrix-authentication-service-mas-cli-doctor`" msgstr "" #: ../../../docs/configuring-playbook-matrix-authentication-service.md:413 +msgid "or by running the `mas-cli` script on the server (which invokes the `mas-cli` tool inside a container): `/matrix/matrix-authentication-service/bin/mas-cli doctor`" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:415 msgid "If successful, you should see some output that looks like this:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:425 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:427 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:427 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:429 msgid "Management" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:429 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:431 msgid "You can use the [`mas-cli` command-line tool](https://element-hq.github.io/matrix-authentication-service/reference/cli/index.html) (exposed via the `/matrix/matrix-authentication-service/bin/mas-cli` script) to perform administrative tasks against MAS." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:431 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:433 msgid "This documentation page already mentions:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:433 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:435 msgid "the `mas-cli doctor` sub-command in the [Verify that Matrix Authentication Service is installed correctly](#verify-that-matrix-authentication-service-is-installed-correctly) section, which you can run via the CLI and via the Ansible playbook's `matrix-authentication-service-mas-cli-doctor` tag" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:435 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:437 msgid "the `mas-cli manage register-user` sub-command in the [Registering users](./registering-users.md) documentation" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:437 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:439 msgid "There are other sub-commands available. Run `/matrix/matrix-authentication-service/bin/mas-cli` to get an overview." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:439 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:441 msgid "User registration" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:441 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:443 msgid "After Matrix Authentication Service is [installed](#installing), users need to be managed there (unless you're managing them in an [upstream OAuth2 provider](#upstream-oauth2-configuration))." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:443 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:445 msgid "You can register users new users as described in the [Registering users](./registering-users.md) documentation (via `mas-cli manage register-user` or the Ansible playbook's `register-user` tag)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:445 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:447 msgid "Working around email deliverability issues" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:447 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:449 msgid "Matrix Authentication Service only sends emails when:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:449 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:451 msgid "it verifies email addresses for users who are self-registering with a password" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:451 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:453 msgid "a user tries to add an email to their account" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:453 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:455 msgid "If Matrix Authentication Service tries to send an email and it fails because [your email-sending configuration](./configuring-playbook-email.md) is not working, you may need to work around email deliverability." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:455 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:457 msgid "If email delivery is not working, **you can retrieve the email verification code from the Matrix Authentication Service's logs** (`journalctl -fu matrix-authentication-service`)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:457 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:459 msgid "Alternatively, you can use the [`mas-cli` management tool](#management) to manually verify email addresses for users. Example: `/matrix/matrix-authentication-service/bin/mas-cli manage verify-email some.username email@example.com`" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:459 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:461 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-matrix-authentication-service.md:461 +#: ../../../docs/configuring-playbook-matrix-authentication-service.md:463 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-authentication-service`." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-matrix-corporal.pot b/i18n/translation-templates/docs/configuring-playbook-matrix-corporal.pot index 33a246a63..913141eb5 100644 --- a/i18n/translation-templates/docs/configuring-playbook-matrix-corporal.pot +++ b/i18n/translation-templates/docs/configuring-playbook-matrix-corporal.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -20,8 +20,8 @@ msgstr "" msgid "Setting up Matrix Corporal (optional, advanced)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-corporal.md:11 -msgid "[!WARNING] This is an advanced feature! It requires prior experience with Matrix and a specific need for using [Matrix Corporal](https://github.com/devture/matrix-corporal). If you're unsure whether you have such a need, you most likely don't." +#: ../../../docs/configuring-playbook-matrix-corporal.md:12 +msgid "This is an advanced feature! It requires prior experience with Matrix and a specific need for using [Matrix Corporal](https://github.com/devture/matrix-corporal). If you're unsure whether you have such a need, you most likely don't." msgstr "" #: ../../../docs/configuring-playbook-matrix-corporal.md:14 diff --git a/i18n/translation-templates/docs/configuring-playbook-matrix-ldap-registration-proxy.pot b/i18n/translation-templates/docs/configuring-playbook-matrix-ldap-registration-proxy.pot index d09f16bb8..4f31d15be 100644 --- a/i18n/translation-templates/docs/configuring-playbook-matrix-ldap-registration-proxy.pot +++ b/i18n/translation-templates/docs/configuring-playbook-matrix-ldap-registration-proxy.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-06-29 17:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,74 +16,18 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:9 -msgid "Setting up matrix-ldap-registration-proxy (optional)" +#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:20 +msgid "Setting up matrix-ldap-registration-proxy (optional, removed)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:11 -msgid "The playbook can install and configure [matrix-ldap-registration-proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy) for you." +#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:22 +msgid "🪦 The playbook used to be able to install and configure [matrix-ldap-registration-proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy), but no longer includes this component, as it has become unavailable." msgstr "" -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:13 -msgid "This proxy handles Matrix registration requests and forwards them to LDAP." +#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:24 +msgid "Uninstalling the component manually" msgstr "" -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:15 -msgid "See the project's [documentation](https://gitlab.com/activism.international/matrix_ldap_registration_proxy/-/blob/main/README.md) to learn what it does and why it might be useful to you." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:17 -msgid "**Note**: This does support the full Matrix specification for registrations. It only provide a very coarse implementation of a basic password registration." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:19 -msgid "Adjusting the playbook configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:21 -msgid "To enable the component, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file (adapt to your needs):" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:33 -msgid "If you already use the [synapse external password provider via LDAP](configuring-playbook-ldap-auth.md) (that is, you have `matrix_synapse_ext_password_provider_ldap_enabled: true` and other options in your configuration) you can use the following values as configuration:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:46 -msgid "Extending the configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:48 -msgid "There are some additional things you may wish to configure about the component." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:50 -msgid "Take a look at:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:52 -msgid "`roles/custom/matrix-ldap-registration-proxy/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:54 -msgid "Installing" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:56 -msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:63 -msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:65 -msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:67 -msgid "Troubleshooting" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:69 -msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-ldap-registration-proxy`." +#: ../../../docs/configuring-playbook-matrix-ldap-registration-proxy.md:26 +msgid "If you still have matrix-ldap-registration-proxy installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-matrix-registration.pot b/i18n/translation-templates/docs/configuring-playbook-matrix-registration.pot index 7d96bb08f..6391b56ff 100644 --- a/i18n/translation-templates/docs/configuring-playbook-matrix-registration.pot +++ b/i18n/translation-templates/docs/configuring-playbook-matrix-registration.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,166 +16,22 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../docs/configuring-playbook-matrix-registration.md:9 -msgid "Setting up matrix-registration (optional)" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:11 -msgid "[!WARNING]" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:12 -msgid "This is a poorly maintained and buggy project. It's better to avoid using it." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:13 -msgid "This is not related to [matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md)" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:15 -msgid "The playbook can install and configure [matrix-registration](https://github.com/ZerataX/matrix-registration) for you. It is a simple python application to have a token based Matrix registration." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:17 -msgid "Use matrix-registration to **create unique registration links**, which people can use to register on your Matrix server. It allows certain people (these having a special link) to register a user account, **keeping your server's registration closed (private)**." -msgstr "" - #: ../../../docs/configuring-playbook-matrix-registration.md:19 -msgid "**matrix-registration** provides 2 things:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:21 -msgid "**an API for creating registration tokens** (unique registration links). This API can be used via `curl` or via the playbook (see [Usage](#usage) below)" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:23 -msgid "**a user registration page**, where people can use these registration tokens. By default, exposed at `https://matrix.example.com/matrix-registration`" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:25 -msgid "Adjusting DNS records (optional)" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:27 -msgid "By default, this playbook installs the matrix-registration on the `matrix.` subdomain, at the `/matrix-registration` path (https://matrix.example.com/matrix-registration). This makes it easy to install it, because it **doesn't require additional DNS records to be set up**. If that's okay, you can skip this section." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:29 -msgid "If you wish to adjust it, see the section [below](#adjusting-the-matrix-registration-url-optional) for details about DNS configuration." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:31 -msgid "Adjusting the playbook configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:33 -msgid "To enable matrix-registration, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:42 -msgid "Adjusting the matrix-registration URL (optional)" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:44 -msgid "By tweaking the `matrix_registration_hostname` and `matrix_registration_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:46 -msgid "Example additional configuration for your `vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:54 -msgid "If you've changed the default hostname, you may need to create a CNAME record for the matrix-registration domain (`registration.example.com`), which targets `matrix.example.com`." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:56 -msgid "When setting, replace `example.com` with your own." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:58 -msgid "Extending the configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:60 -msgid "There are some additional things you may wish to configure about the component." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:62 -msgid "Take a look at:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:64 -msgid "`roles/custom/matrix-registration/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:65 -msgid "`roles/custom/matrix-registration/templates/config.yaml.j2` for the component's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_registration_configuration_extension_yaml` variable" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:67 -msgid "Installing" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:69 -msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:76 -msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:78 -msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:80 -msgid "Usage" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:82 -msgid "**matrix-registration** gets exposed at `https://matrix.example.com/matrix-registration`" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:84 -msgid "It provides various [APIs](https://github.com/ZerataX/matrix-registration/wiki/api) — for creating registration tokens, listing tokens, disabling tokens, etc. To make use of all of its capabilities, consider using `curl`." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:86 -msgid "We make the most common APIs easy to use via the playbook (see below)." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:88 -msgid "Creating registration tokens" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:90 -msgid "To **create a new user registration token (link)**, use this command:" -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:98 -msgid "The above command creates and returns a **one-time use** token, which **expires** on the 31st of December 2021. Adjust the `one_time` and `ex_date` variables as you see fit." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:100 -msgid "Share the unique registration link (generated by the command above) with users to let them register on your Matrix server." -msgstr "" - -#: ../../../docs/configuring-playbook-matrix-registration.md:102 -msgid "Listing registration tokens" +msgid "Setting up matrix-registration (optional, removed)" msgstr "" -#: ../../../docs/configuring-playbook-matrix-registration.md:104 -msgid "To **list the existing user registration tokens**, use this command:" +#: ../../../docs/configuring-playbook-matrix-registration.md:22 +msgid "This is not related to [matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-registration.md:111 -msgid "The shortcut command with `just` program is also available: `just run-tags list-matrix-registration-tokens`" +#: ../../../docs/configuring-playbook-matrix-registration.md:24 +msgid "🪦 The playbook used to be able to install and configure [matrix-registration](https://github.com/ZerataX/matrix-registration), but no longer includes this component, as it has been unmaintained since November, 2025." msgstr "" -#: ../../../docs/configuring-playbook-matrix-registration.md:113 -msgid "Troubleshooting" +#: ../../../docs/configuring-playbook-matrix-registration.md:26 +msgid "Uninstalling the component manually" msgstr "" -#: ../../../docs/configuring-playbook-matrix-registration.md:115 -msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-registration`." +#: ../../../docs/configuring-playbook-matrix-registration.md:28 +msgid "If you still have matrix-registration installed on your Matrix server, the playbook can no longer help you uninstall it and you will need to do it manually. To uninstall manually, run these commands on the server:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-matrix-rtc.pot b/i18n/translation-templates/docs/configuring-playbook-matrix-rtc.pot index 20c5f27e6..81792a2ae 100644 --- a/i18n/translation-templates/docs/configuring-playbook-matrix-rtc.pot +++ b/i18n/translation-templates/docs/configuring-playbook-matrix-rtc.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -45,19 +45,19 @@ msgid "Various experimental features for the Synapse homeserver which Element Ca msgstr "" #: ../../../docs/configuring-playbook-matrix-rtc.md:20 -msgid "A [LiveKit Server](configuring-playbook-livekit-server.md) (automatically installed when [Element Call or the Matrix RTC stack is enabled](#decide-between-element-call-vs-just-the-matrix-rtc-stack))" +msgid "A [LiveKit Server](configuring-playbook-livekit-server.md) (automatically installed when [Element Call or the Matrix RTC stack is enabled](configuring-playbook-element-call.md#decide-between-element-call-vs-just-the-matrix-rtc-stack))" msgstr "" #: ../../../docs/configuring-playbook-matrix-rtc.md:21 -msgid "The [LiveKit JWT Service](configuring-playbook-livekit-jwt-service.md) (automatically installed when [Element Call or the Matrix RTC stack is enabled](#decide-between-element-call-vs-just-the-matrix-rtc-stack))" +msgid "The [LiveKit JWT Service](configuring-playbook-livekit-jwt-service.md) (automatically installed when [Element Call or the Matrix RTC stack is enabled](configuring-playbook-element-call.md#decide-between-element-call-vs-just-the-matrix-rtc-stack))" msgstr "" #: ../../../docs/configuring-playbook-matrix-rtc.md:22 msgid "A client compatible with Element Call. As of 2025-03-15, that's just [Element Web](configuring-playbook-client-element-web.md) and the Element X mobile clients (iOS and Android)." msgstr "" -#: ../../../docs/configuring-playbook-matrix-rtc.md:24 -msgid "[!WARNING] Because Element Call [requires](https://github.com/element-hq/element-call/blob/93ae2aed9841e0b066d515c56bd4c122d2b591b2/docs/self-hosting.md#a-matrix-homeserver) a few experimental features in the Matrix protocol, it's **very likely that it only works with the Synapse homeserver**." +#: ../../../docs/configuring-playbook-matrix-rtc.md:25 +msgid "Because Element Call [requires](https://github.com/element-hq/element-call/blob/93ae2aed9841e0b066d515c56bd4c122d2b591b2/docs/self-hosting.md#a-matrix-homeserver) a few experimental features in the Matrix protocol, it's **very likely that it only works with the Synapse homeserver**." msgstr "" #: ../../../docs/configuring-playbook-matrix-rtc.md:27 @@ -77,29 +77,41 @@ msgid "In addition to the HTTP/HTTPS ports (which you've already exposed as per msgstr "" #: ../../../docs/configuring-playbook-matrix-rtc.md:41 -msgid "Installing" +msgid "Fronting the integrated reverse-proxy with another reverse-proxy" msgstr "" #: ../../../docs/configuring-playbook-matrix-rtc.md:43 +msgid "If you're [fronting the integrated reverse-proxy webserver with another reverse-proxy](configuring-playbook-own-webserver.md#fronting-the-integrated-reverse-proxy-webserver-with-another-reverse-proxy) (e.g. nginx), it needs to forward WebSocket traffic for [LiveKit Server](configuring-playbook-livekit-server.md) at the `/livekit-server/` path. Without that, Matrix RTC calls will not work." +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-rtc.md:45 +msgid "See [`examples/reverse-proxies/nginx/matrix.conf`](../examples/reverse-proxies/nginx/matrix.conf) for an nginx example." +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-rtc.md:47 +msgid "Installing" +msgstr "" + +#: ../../../docs/configuring-playbook-matrix-rtc.md:49 msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records) and [adjusting firewall rules](#adjusting-firewall-rules), run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-matrix-rtc.md:50 +#: ../../../docs/configuring-playbook-matrix-rtc.md:56 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-matrix-rtc.md:52 +#: ../../../docs/configuring-playbook-matrix-rtc.md:58 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-matrix-rtc.md:54 +#: ../../../docs/configuring-playbook-matrix-rtc.md:60 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-matrix-rtc.md:56 +#: ../../../docs/configuring-playbook-matrix-rtc.md:62 msgid "Once installed, Matrix clients which support Element Call (like [Element Web](configuring-playbook-client-element-web.md) and Element X on mobile (iOS and Android)) will automatically use the Matrix RTC stack." msgstr "" -#: ../../../docs/configuring-playbook-matrix-rtc.md:58 +#: ../../../docs/configuring-playbook-matrix-rtc.md:64 msgid "These clients typically embed the Element Call frontend UI within them, so installing [Element Call](configuring-playbook-element-call.md) is only necessary if you'd like to use it standalone - directly via a browser." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-prometheus-grafana.pot b/i18n/translation-templates/docs/configuring-playbook-prometheus-grafana.pot index f2ab67ceb..fddaf821b 100644 --- a/i18n/translation-templates/docs/configuring-playbook-prometheus-grafana.pot +++ b/i18n/translation-templates/docs/configuring-playbook-prometheus-grafana.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-01 17:14+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -24,8 +24,8 @@ msgstr "" msgid "The playbook can install [Prometheus](https://prometheus.io/) with [Grafana](https://grafana.com/) and configure performance metrics of your homeserver with graphs for you." msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:18 -msgid "[!WARNING] Metrics and graphs contain a lot of information, and anyone who has access to them can make an educated guess about your server usage patterns. This especially applies to small personal/family scale homeservers, where the number of samples is fairly limited. Analyzing the metrics over time, one might be able to figure out your life cycle, such as when you wake up, go to bed, etc. Before enabling (anonymous) access, you should carefully evaluate the risk, and if you do enable it, it is highly recommended to change your Grafana password from the default one." +#: ../../../docs/configuring-playbook-prometheus-grafana.md:19 +msgid "Metrics and graphs contain a lot of information, and anyone who has access to them can make an educated guess about your server usage patterns. This especially applies to small personal/family scale homeservers, where the number of samples is fairly limited. Analyzing the metrics over time, one might be able to figure out your life cycle, such as when you wake up, go to bed, etc. Before enabling (anonymous) access, you should carefully evaluate the risk, and if you do enable it, it is highly recommended to change your Grafana password from the default one." msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:21 @@ -143,7 +143,7 @@ msgid "[Prometheus role](https://github.com/mother-of-all-self-hosting/ansible-r msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:109 -msgid "`roles/custom/matrix-prometheus-nginxlog-exporter/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" +msgid "`roles/galaxy/prometheus_nginxlog_exporter/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:111 @@ -291,7 +291,7 @@ msgid "Set this to `true` to enable the node (general system stats) exporter (lo msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:0 -msgid "`prometheus_node_exporter_container_labels_traefik_enabled`" +msgid "`prometheus_node_exporter_container_labels_metrics_enabled`" msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:0 @@ -307,7 +307,7 @@ msgid "Set this to `true` to enable the [Postgres exporter](#enable-metrics-and- msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:0 -msgid "`prometheus_postgres_exporter_container_labels_traefik_enabled`" +msgid "`prometheus_postgres_exporter_container_labels_metrics_enabled`" msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:0 @@ -315,105 +315,129 @@ msgid "Set this to `true` to expose the [Postgres exporter](#enable-metrics-and- msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:0 -msgid "`matrix_prometheus_nginxlog_exporter_enabled`" +msgid "`prometheus_nginxlog_exporter_enabled`" msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:0 -msgid "Set this to `true` to enable the [nginx Log exporter](#enable-metrics-and-graphs-for-nginx-logs-optional) (locally, on the container network)." +msgid "Set this to `true` to enable the [prometheus-nginxlog-exporter](#enable-metrics-and-graphs-for-nginx-logs-optional) (locally, on the container network)." msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:0 -msgid "`matrix_prometheus_nginxlog_exporter_metrics_proxying_enabled`" +msgid "`prometheus_nginxlog_exporter_container_labels_metrics_enabled`" msgstr "" #: ../../../docs/configuring-playbook-prometheus-grafana.md:0 -msgid "Set this to `true` to expose the [nginx Log exporter](#enable-metrics-and-graphs-for-nginx-logs-optional) metrics on `https://matrix.example.com/metrics/nginxlog`." +msgid "Set this to `true` to expose the [prometheus-nginxlog-exporter](#enable-metrics-and-graphs-for-nginx-logs-optional) metrics on `https://matrix.example.com/metrics/nginxlog`." msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:187 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:0 +msgid "`ntfy_metrics_listen_http_port`" +msgstr "" + +#: ../../../docs/configuring-playbook-prometheus-grafana.md:0 +msgid "Set this to a port number (e.g. `9090`) to make [ntfy](configuring-playbook-ntfy.md) serve its metrics (locally, on the container network) on that port." +msgstr "" + +#: ../../../docs/configuring-playbook-prometheus-grafana.md:0 +msgid "`ntfy_container_labels_traefik_metrics_enabled`" +msgstr "" + +#: ../../../docs/configuring-playbook-prometheus-grafana.md:0 +msgid "Set this to `true` to expose the [ntfy](configuring-playbook-ntfy.md) metrics on `https://matrix.example.com/metrics/ntfy`." +msgstr "" + +#: ../../../docs/configuring-playbook-prometheus-grafana.md:0 +msgid "`matrix_synapse_usage_exporter_metrics_proxying_enabled`" +msgstr "" + +#: ../../../docs/configuring-playbook-prometheus-grafana.md:0 +msgid "Set this to `true` to expose the [synapse-usage-exporter](configuring-playbook-synapse-usage-exporter.md) metrics on `https://matrix.example.com/metrics/synapse-usage-exporter`." +msgstr "" + +#: ../../../docs/configuring-playbook-prometheus-grafana.md:190 msgid "Expose metrics of other services/roles" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:189 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:192 msgid "Various other services/roles may provide similar `_metrics_enabled` and `_metrics_proxying_enabled` variables for exposing their metrics. Refer to each role for details." msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:191 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:194 msgid "To password-protect the metrics of a specific role, you can use `matrix_SERVICE_container_labels_metrics_middleware_basic_auth_enabled` and `matrix_SERVICE_container_labels_metrics_middleware_basic_auth_users` variables provided by the role." msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:193 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:196 msgid "**Note**: alternatively you can use `matrix_metrics_exposure_http_basic_auth_enabled` and `matrix_metrics_exposure_http_basic_auth_users` in order to password-protect the metrics of all services." msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:195 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:198 msgid "For example, you can enable and expose metrics for Synapse protecting them with dedicated credentials by adding the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:213 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:216 msgid "Collecting Synapse worker metrics to an external Prometheus server" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:215 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:218 msgid "If you are using workers (`matrix_synapse_workers_enabled: true`) and have enabled `matrix_synapse_metrics_proxying_enabled` as described above, the playbook will also automatically expose all Synapse worker threads' metrics to `https://matrix.example.com/metrics/synapse/worker/ID`, where `ID` corresponds to the worker `id` as exemplified in `matrix_synapse_workers_enabled_list`." msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:217 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:220 msgid "The playbook also generates an exemplary config file (`/matrix/synapse/external_prometheus.yml.template`) with all the correct paths which you can copy to your Prometheus server and adapt to your needs. Make sure to edit the specified `password_file` path and contents and path to your `synapse-v2.rules`. It will look a bit like this:" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:245 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:248 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:247 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:250 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running the commands below:" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:248 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:251 msgid "`journalctl -fu matrix-prometheus` for Prometheus" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:249 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:252 msgid "`journalctl -fu matrix-prometheus-node-exporter` for Node Exporter" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:250 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:253 msgid "`journalctl -fu matrix-prometheus-postgres-exporter` for PostgreSQL Server Exporter" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:251 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:254 msgid "`journalctl -fu matrix-prometheus-nginxlog-exporter` for prometheus-nginxlog-exporter" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:252 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:255 msgid "`journalctl -fu matrix-grafana` for Grafana" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:254 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:257 msgid "More information" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:256 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:259 msgid "[Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md)" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:257 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:260 msgid "[Understanding Synapse Performance Issues Through Grafana Graphs](https://element-hq.github.io/synapse/latest/usage/administration/understanding_synapse_through_grafana_graphs.html) at the Synapse Github Wiki" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:258 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:261 msgid "[The Prometheus scraping rules](https://github.com/element-hq/synapse/tree/master/contrib/prometheus) (we use v2)" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:259 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:262 msgid "[The Synapse Grafana dashboard](https://github.com/element-hq/synapse/tree/master/contrib/grafana)" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:260 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:263 msgid "[The Node Exporter dashboard](https://github.com/rfrail3/grafana-dashboards) (for generic non-synapse performance graphs)" msgstr "" -#: ../../../docs/configuring-playbook-prometheus-grafana.md:261 +#: ../../../docs/configuring-playbook-prometheus-grafana.md:264 msgid "[The PostgreSQL dashboard](https://grafana.com/grafana/dashboards/9628) (generic Postgres dashboard)" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-synapse-auto-accept-invite.pot b/i18n/translation-templates/docs/configuring-playbook-synapse-auto-accept-invite.pot index b36ec32af..164a32bee 100644 --- a/i18n/translation-templates/docs/configuring-playbook-synapse-auto-accept-invite.pot +++ b/i18n/translation-templates/docs/configuring-playbook-synapse-auto-accept-invite.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-15 09:10+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,54 +16,18 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:9 -msgid "Setting up Synapse Auto Invite Accept (optional)" +#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:18 +msgid "Setting up Synapse Auto Invite Accept (optional, removed)" msgstr "" -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:11 -msgid "The playbook can install and configure [synapse-auto-invite-accept](https://github.com/matrix-org/synapse-auto-accept-invite) for you." +#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:20 +msgid "🪦 The playbook used to be able to install and configure [synapse-auto-invite-accept](https://github.com/matrix-org/synapse-auto-accept-invite), but no longer includes this component, as the same functionality [has been integrated](https://github.com/element-hq/synapse/pull/17147) to Synapse since [v1.109.0](https://github.com/element-hq/synapse/releases/tag/v1.109.0)." msgstr "" -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:13 -msgid "In short, it automatically accepts room invites. You can specify that only 1:1 room invites are auto-accepted. Defaults to false if not specified." -msgstr "" - -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:15 -msgid "See the project's [documentation](https://github.com/matrix-org/synapse-auto-accept-invite/blob/main/README.md) to learn what it does and why it might be useful to you." -msgstr "" - -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:17 -msgid "**Note**: Synapse [v1.109.0](https://github.com/element-hq/synapse/releases/tag/v1.109.0), the same feature [has been merged](https://github.com/element-hq/synapse/pull/17147) into Synapse (see the [Native alternative](#native-alternative) section below). You'd better use the native feature, instead of the [synapse-auto-invite-accept](https://github.com/matrix-org/synapse-auto-accept-invite) 3rd party module." -msgstr "" - -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:19 -msgid "Adjusting the playbook configuration" -msgstr "" - -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:21 -msgid "If you decide that you'd like to let this playbook install the [synapse-auto-invite-accept](https://github.com/matrix-org/synapse-auto-accept-invite module for you, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" -msgstr "" - -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:29 -msgid "Synapse worker deployments" -msgstr "" - -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:31 -msgid "In a [workerized Synapse deployment](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/c9a842147e09647c355799ca024d65a5de66b099/docs/configuring-playbook-synapse.md#load-balancing-with-workers) it is possible to run this module on a worker to reduce the load on the main process (Default is `null`). For example, add this to your configuration:" -msgstr "" - -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:37 -msgid "There might be an [issue with federation](https://github.com/matrix-org/synapse-auto-accept-invite/issues/18)." -msgstr "" - -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:39 +#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:22 msgid "Native alternative" msgstr "" -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:41 -msgid "Since Synapse [v1.109.0](https://github.com/element-hq/synapse/releases/tag/v1.109.0), the functionality provided by the [synapse-auto-invite-accept](https://github.com/matrix-org/synapse-auto-accept-invite) 3rd party module [has been made](https://github.com/element-hq/synapse/pull/17147) part of Synapse." -msgstr "" - -#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:43 +#: ../../../docs/configuring-playbook-synapse-auto-accept-invite.md:24 msgid "Here's example configuration for using the **native** Synapse feature:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-synapse-s3-storage-provider.pot b/i18n/translation-templates/docs/configuring-playbook-synapse-s3-storage-provider.pot index 58ceb305b..0d216b704 100644 --- a/i18n/translation-templates/docs/configuring-playbook-synapse-s3-storage-provider.pot +++ b/i18n/translation-templates/docs/configuring-playbook-synapse-s3-storage-provider.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-15 09:10+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -293,9 +293,13 @@ msgid "… triggered by the `matrix-synapse-s3-storage-provider-migrate.timer` t msgstr "" #: ../../../docs/configuring-playbook-synapse-s3-storage-provider.md:180 -msgid "So… you don't need to perform any maintenance yourself." +msgid "The same `migrate` script also prunes empty directories in the local media repository (`remote_content` and `remote_thumbnail`) after upload/delete operations." msgstr "" #: ../../../docs/configuring-playbook-synapse-s3-storage-provider.md:182 +msgid "So… you don't need to perform any maintenance yourself." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse-s3-storage-provider.md:184 msgid "The schedule is defined in the format of systemd timer calendar. To edit the schedule, add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-synapse-usage-exporter.pot b/i18n/translation-templates/docs/configuring-playbook-synapse-usage-exporter.pot index 9d5ba04a6..467c86e81 100644 --- a/i18n/translation-templates/docs/configuring-playbook-synapse-usage-exporter.pot +++ b/i18n/translation-templates/docs/configuring-playbook-synapse-usage-exporter.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-01 17:14+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -81,61 +81,81 @@ msgid "To enable synapse-usage-exporter, add the following configuration to your msgstr "" #: ../../../docs/configuring-playbook-synapse-usage-exporter.md:48 -msgid "Adjusting the synapse-usage-exporter URL (optional)" +msgid "**Note**: `matrix_synapse_usage_exporter_proxying_enabled` only exposes the endpoint that Synapse pushes usage statistics **to** (`/report-usage-stats/push`). Despite its generic name, it has nothing to do with the metrics endpoint that Prometheus reads **from**. See [below](#collecting-metrics-to-an-external-prometheus-server) for exposing metrics." msgstr "" #: ../../../docs/configuring-playbook-synapse-usage-exporter.md:50 -msgid "By tweaking the `matrix_synapse_usage_exporter_hostname` and `matrix_synapse_usage_exporter_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." +msgid "Collecting metrics to an external Prometheus server" msgstr "" #: ../../../docs/configuring-playbook-synapse-usage-exporter.md:52 +msgid "Metrics are always served on the container network, so the [integrated Prometheus](./configuring-playbook-prometheus-grafana.md) (`prometheus_enabled: true`) scrapes them without any additional configuration." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:54 +msgid "To collect them with an **external Prometheus server**, you need to expose them publicly. You can do so by enabling metrics exposure for all services (`matrix_metrics_exposure_enabled: true`), or just for this service:" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:68 +msgid "Refer to [this section](./configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) of the Prometheus and Grafana documentation for more details." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:70 +msgid "Adjusting the synapse-usage-exporter URL (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:72 +msgid "By tweaking the `matrix_synapse_usage_exporter_hostname` and `matrix_synapse_usage_exporter_path_prefix` variables, you can easily make the service available at a **different hostname and/or path** than the default one." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:74 msgid "Example additional configuration for your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:61 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:83 msgid "If you've changed the default hostname, you may need to create a CNAME record for the synapse-usage-exporter domain (`sue.example.com`), which targets `matrix.example.com`." msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:63 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:85 msgid "When setting, replace `example.com` with your own." msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:65 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:87 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:67 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:89 msgid "There are some additional things you may wish to configure about the component." msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:69 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:91 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:71 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:93 msgid "`roles/custom/matrix-synapse-usage-exporter/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:73 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:95 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:75 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:97 msgid "After configuring the playbook and potentially [adjusting your DNS records](#adjusting-dns-records), run the playbook with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:82 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:104 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:84 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:106 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:86 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:108 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:88 +#: ../../../docs/configuring-playbook-synapse-usage-exporter.md:110 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-synapse-usage-exporter`." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-synapse.pot b/i18n/translation-templates/docs/configuring-playbook-synapse.pot index f0050564b..cbf8f6815 100644 --- a/i18n/translation-templates/docs/configuring-playbook-synapse.pot +++ b/i18n/translation-templates/docs/configuring-playbook-synapse.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-03 11:56+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -149,7 +149,7 @@ msgid "When Synapse workers are enabled, the integrated [Postgres database is tu msgstr "" #: ../../../docs/configuring-playbook-synapse.md:79 -msgid "A separate Ansible role (`matrix-synapse-reverse-proxy-companion`) and component handles load-balancing for workers. This role/component is automatically enabled when you enable workers. Make sure to use the `setup-all` tag (not `install-all`!) during the playbook's [installation](./installing.md) process, especially if you're disabling workers, so that components may be installed/uninstalled correctly." +msgid "The `matrix-synapse` role also manages the `matrix-synapse-reverse-proxy-companion` component for load-balancing with workers. This component is automatically enabled when you enable workers. Make sure to use the `setup-all` tag (not `install-all`!) during the playbook's [installation](./installing.md) process, especially if you're disabling workers, so that components may be installed/uninstalled correctly." msgstr "" #: ../../../docs/configuring-playbook-synapse.md:81 @@ -157,141 +157,161 @@ msgid "In case any problems occur, make sure to have a look at the [list of syna msgstr "" #: ../../../docs/configuring-playbook-synapse.md:83 -msgid "Synapse + OpenID Connect for Single-Sign-On" +msgid "Limit joining heavy rooms on constrained hosts" msgstr "" #: ../../../docs/configuring-playbook-synapse.md:85 -msgid "💡 An alternative to setting up OIDC in Synapse is to use [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) (MAS). Newer clients (like Element X) only support SSO-based authentication via MAS and not via the legacy Synapse OIDC setup described below. That said, MAS is still a new experimental service which comes with its own downsides. Consult its documentation to learn if it will be a good fit for your deployment." +msgid "If your server is underpowered, joining heavy rooms can cause Synapse to consume a lot of resources and be unavailable for long (while it catches up)." msgstr "" #: ../../../docs/configuring-playbook-synapse.md:87 -msgid "If you'd like to use OpenID Connect authentication with Synapse, you'll need some additional configuration." +msgid "To avoid this, Synapse can be configured to reject joins for remote rooms that are too complex before users enter them." msgstr "" #: ../../../docs/configuring-playbook-synapse.md:89 -msgid "This example configuration is for [keycloak](https://www.keycloak.org/), an opensource Identity Provider maintained by Red Hat." +msgid "Complexity is computed as `current_state_events / 500` (Synapse state event count for current room state). When the resulting value is higher than `matrix_synapse_limit_remote_rooms_complexity` and `matrix_synapse_limit_remote_rooms_enabled` is `true`, Synapse blocks joining the room." msgstr "" #: ../../../docs/configuring-playbook-synapse.md:91 +msgid "We recommend using this as a guardrail on low-resource servers:" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:106 +msgid "Synapse + OpenID Connect for Single-Sign-On" +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:108 +msgid "💡 An alternative to setting up OIDC in Synapse is to use [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) (MAS). Newer clients (like Element X) only support SSO-based authentication via MAS and not via the legacy Synapse OIDC setup described below. That said, MAS is still a new experimental service which comes with its own downsides. Consult its documentation to learn if it will be a good fit for your deployment." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:110 +msgid "If you'd like to use OpenID Connect authentication with Synapse, you'll need some additional configuration." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:112 +msgid "This example configuration is for [keycloak](https://www.keycloak.org/), an opensource Identity Provider maintained by Red Hat." +msgstr "" + +#: ../../../docs/configuring-playbook-synapse.md:114 msgid "For more detailed documentation on available options and how to setup keycloak, see the [Synapse documentation on OpenID Connect with keycloak](https://github.com/element-hq/synapse/blob/develop/docs/openid.md#keycloak)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:93 +#: ../../../docs/configuring-playbook-synapse.md:116 msgid "In case you encounter errors regarding the parsing of the variables, you can try to add `{% raw %}` and `{% endraw %}` blocks around them. For example ;" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:114 +#: ../../../docs/configuring-playbook-synapse.md:137 msgid "Customizing templates" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:116 +#: ../../../docs/configuring-playbook-synapse.md:139 msgid "[Templates](https://github.com/element-hq/synapse/blob/develop/docs/templates.md) are used by Synapse for showing **certain web pages** handled by the server, as well as for **email notifications**." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:118 +#: ../../../docs/configuring-playbook-synapse.md:141 msgid "This playbook allows you to customize the default templates (see the [`synapse/res/templates` directory](https://github.com/element-hq/synapse/tree/develop/synapse/res/templates))." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:120 +#: ../../../docs/configuring-playbook-synapse.md:143 msgid "If template customization is enabled, the playbook will build a custom container image based on the official one." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:122 +#: ../../../docs/configuring-playbook-synapse.md:145 msgid "Your custom templates need to live in a public or private git repository. This repository will be cloned during Synapse image customization (during the playbook run)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:124 +#: ../../../docs/configuring-playbook-synapse.md:147 msgid "To enable template customizations, add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:150 +#: ../../../docs/configuring-playbook-synapse.md:173 msgid "As mentioned in Synapse's Templates documentation, Synapse will fall back to its own templates if a template is not found in that directory. Due to this, it's recommended to only store and maintain template files in your repository if you need to make custom changes. Other files (which you don't need to change), should not be duplicated, so that you don't need to worry about getting out-of-sync with the original Synapse templates." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:152 +#: ../../../docs/configuring-playbook-synapse.md:175 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:154 +#: ../../../docs/configuring-playbook-synapse.md:177 msgid "There are some additional things you may wish to configure about the server." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:156 +#: ../../../docs/configuring-playbook-synapse.md:179 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:158 +#: ../../../docs/configuring-playbook-synapse.md:181 msgid "`roles/custom/matrix-synapse/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:159 +#: ../../../docs/configuring-playbook-synapse.md:182 msgid "`roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2` for the server's default configuration. You can override settings (even those that don't have dedicated playbook variables) using the `matrix_synapse_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:161 +#: ../../../docs/configuring-playbook-synapse.md:184 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:163 +#: ../../../docs/configuring-playbook-synapse.md:186 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:170 +#: ../../../docs/configuring-playbook-synapse.md:193 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:172 +#: ../../../docs/configuring-playbook-synapse.md:195 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:174 +#: ../../../docs/configuring-playbook-synapse.md:197 msgid "Usage" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:176 -msgid "Synapse Admin" +#: ../../../docs/configuring-playbook-synapse.md:199 +msgid "Ketesa" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:178 -msgid "With [Synapse Admin](configuring-playbook-synapse-admin.md), certain Synapse administration tasks (managing users and rooms, etc.) can be performed via a web user-interace." +#: ../../../docs/configuring-playbook-synapse.md:201 +msgid "[Ketesa](configuring-playbook-ketesa.md) is a fully-featured web UI for administrating your homeserver — managing users, rooms, media, sessions, and more." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:180 -msgid "The playbook can install and configure Synapse Admin for you. For details about it, see [this page](configuring-playbook-synapse-admin.md)." +#: ../../../docs/configuring-playbook-synapse.md:203 +msgid "The playbook can install and configure Ketesa for you. For details about it, see [this page](configuring-playbook-ketesa.md)." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:182 +#: ../../../docs/configuring-playbook-synapse.md:205 msgid "Monitoring Synapse Metrics with Prometheus and Grafana" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:184 +#: ../../../docs/configuring-playbook-synapse.md:207 msgid "This playbook allows you to enable Synapse metrics, which can provide insight into the performance and activity of Synapse." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:186 +#: ../../../docs/configuring-playbook-synapse.md:209 msgid "To enable Synapse runtime metrics, see: [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md) and [its subsection](configuring-playbook-prometheus-grafana.md#expose-metrics-of-other-services-roles)" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:188 +#: ../../../docs/configuring-playbook-synapse.md:211 msgid "To enable Synapse usage metrics, see: [Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md)" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:190 +#: ../../../docs/configuring-playbook-synapse.md:213 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:192 +#: ../../../docs/configuring-playbook-synapse.md:215 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-synapse`." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:194 +#: ../../../docs/configuring-playbook-synapse.md:217 msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:196 +#: ../../../docs/configuring-playbook-synapse.md:219 msgid "Because Synapse is originally very chatty when it comes to logging, we intentionally reduce its [logging level](https://docs.python.org/3/library/logging.html#logging-levels) from `INFO` to `WARNING`." msgstr "" -#: ../../../docs/configuring-playbook-synapse.md:198 +#: ../../../docs/configuring-playbook-synapse.md:221 msgid "If you'd like to debug an issue or [report a Synapse bug](https://github.com/element-hq/synapse/issues/new/choose) to the developers, it'd be better if you temporarily increase the logging verbosity to `INFO`. To do so, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-synology.pot b/i18n/translation-templates/docs/configuring-playbook-synology.pot new file mode 100644 index 000000000..fdf2bf5d2 --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-synology.pot @@ -0,0 +1,237 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-06-29 17:11+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-synology.md:7 +msgid "Configuring Synology DSM" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:9 +msgid "This document is a guide for preparing Synology DSM for the installation of the [Matrix Docker Ansible Deploy](https://github.com/spantaleev/matrix-docker-ansible-deploy) project." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:11 +msgid "**Note:** Synology DSM is a community-supported platform. It is not officially tested or maintained by the project maintainers. Use at your own discretion." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:13 +msgid "**Intended audience:** Users already familiar with DSM, SSH, and this Ansible project." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:15 +msgid "Assumptions" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:17 +msgid "DSM version 7 or higher" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:18 +msgid "`Volume1` is used as the default Docker storage location" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:19 +msgid "You are using DSM's built-in reverse proxy for handling HTTPS" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:21 +msgid "How Synology Support Works" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:23 +msgid "The playbook automatically detects Synology DSM by checking for `/etc/synoinfo.conf`. When detected, it:" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:25 +msgid "Uses `synouser` and `synogroup` (DSM-native tools) instead of standard Linux user management" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:26 +msgid "Constrains the Python `requests` package to a version compatible with the Docker SDK" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:27 +msgid "Ensures `/volume1` has shared mount propagation so container bind mounts work correctly" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:28 +msgid "Deploys a `matrix-synology-boot-fix` service that runs on every boot after Docker is ready" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:30 +msgid "You can override auto-detection by setting `matrix_base_host_is_synology: true` or `false` in your `vars.yml`." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:32 +msgid "Matrix Service Account" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:34 +msgid "The playbook creates a `matrix` system account using Synology's `synouser` tool. The account is secured as follows:" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:36 +msgid "**Expired** (`expired=1`) — the account cannot be used to log in to DSM or any application" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:38 +msgid "You must set a password for this account via `matrix_synology_user_password` in your `vars.yml` (see [vars.yml Configuration](#varsyml-configuration)). The password cannot be used to log in because the account is expired, but a non-empty password is required as an additional security layer." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:40 +msgid "If you pre-create the `matrix` user manually before running the playbook, the playbook will not modify the existing account's settings — you are responsible for securing it." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:42 +msgid "Boot-fix Service" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:44 +msgid "Synology DSM has two boot-time quirks that the boot-fix service addresses automatically:" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:46 +msgid "**`/volume1` shared mount propagation**" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:48 +msgid "Docker requires `/volume1` to be mounted as shared (`mount --make-shared /volume1`) for container bind mounts with `bind-propagation=slave` to work correctly (used by matrix-synapse for its media store). On Synology, this cannot be inserted into the systemd chain before Container Manager starts — doing so causes Container Manager to detect a broken dependency and prompt for repair on every boot. The playbook applies this during setup, and the boot-fix service re-applies it on every subsequent reboot, safely outside Container Manager's dependency chain." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:50 +msgid "**Skipped services at boot**" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:52 +msgid "Synology's systemd drops services with multi-level dependency chains from the boot activation queue (e.g. `matrix-traefik → matrix-container-socket-proxy → docker`). These services show as `inactive` or `failed` after reboot even though they are enabled. The boot-fix service scans for any enabled `matrix-*.service` in either state and starts them automatically." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:54 +msgid "**If you previously configured a Task Scheduler entry** (`Control Panel > Task Scheduler`) to run `mount --make-shared /volume1` at boot-up, you can remove it — the boot-fix service now handles this." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:56 +msgid "Synology GUI Preparation" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:58 +msgid "**Enable SSH**" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:59 +msgid "`Control Panel` > `Terminal & SNMP` > `Enable SSH service`" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:61 +msgid "**Enable SFTP**" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:62 +msgid "`Control Panel` > `File Service` > `FTP` > `Enable SFTP service` with default port" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:64 +msgid "**Enable User Home Directory**" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:65 +msgid "`Control Panel` > `User & Group` > `Advanced` > `Enable user home service`" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:67 +msgid "**Install Container Manager**" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:68 +msgid "Install from `Package Center`" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:70 +msgid "**Configure Reverse Proxy**" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:71 +msgid "`Control Panel` > `Login Portal` > `Advanced` > `Reverse Proxy`" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:72 +msgid "Create entries for each service you enable (e.g. Matrix, Element, admin page)" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:73 +msgid "Example entry:" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:74 +msgid "Source: `HTTPS` / `matrix.example.com` / port `443`" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:75 +msgid "Destination: `HTTP` / `localhost` / port `81`" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:77 +msgid "SSH Preparation" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:79 +msgid "(Optional but Recommended) Enable SSH Key Authentication" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:81 +msgid "Configure key-based SSH login to avoid password prompts during Ansible runs." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:83 +msgid "Set Up the Ansible Environment" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:85 +msgid "Create a project folder and Python virtual environment on the DSM host:" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:96 +msgid "Inventory Configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:98 +msgid "In your `inventory/hosts` file, set the Python interpreter to your virtual environment:" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:105 +msgid "vars.yml Configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:107 +msgid "Add the following Synology-specific variables to your `vars.yml`:" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:151 +msgid "Running the Playbook" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:167 +msgid "**Important:** Always include `stop` before `setup-all,start` when changing configuration. Running `setup-all` alone does not restart already-running containers." +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:169 +msgid "Creating Matrix Users" +msgstr "" + +#: ../../../docs/configuring-playbook-synology.md:171 +msgid "After the services are running, create your first Matrix user:" +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-traefik.pot b/i18n/translation-templates/docs/configuring-playbook-traefik.pot index b0679f9ba..b14683370 100644 --- a/i18n/translation-templates/docs/configuring-playbook-traefik.pot +++ b/i18n/translation-templates/docs/configuring-playbook-traefik.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -45,142 +45,158 @@ msgid "Enable Traefik Dashboard" msgstr "" #: ../../../docs/configuring-playbook-traefik.md:28 -msgid "To enable a Traefik [Dashboard](https://doc.traefik.io/traefik/operations/dashboard/) UI at `https://matrix.example.com/dashboard/` (note the trailing `/`), add the following configuration to your `vars.yml` file:" +msgid "To enable the Traefik [Dashboard](https://doc.traefik.io/traefik/operations/dashboard/) UI at `https://matrix.example.com/dashboard/` (note the trailing `/`), add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:38 -msgid "[!WARNING] Enabling the dashboard on a hostname you use for something else (like `matrix_server_fqn_matrix` in the configuration above) may cause conflicts. Enabling the Traefik Dashboard makes Traefik capture all `/dashboard` and `/api` requests and forward them to itself. If any of the services hosted on the same hostname requires any of these 2 URL prefixes, you will experience problems. So far, we're not aware of any playbook services which occupy these endpoints and are likely to cause conflicts." +#: ../../../docs/configuring-playbook-traefik.md:37 +msgid "Choose a username and password for the dashboard, then generate the corresponding `htpasswd` entry with:" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:41 +#: ../../../docs/configuring-playbook-traefik.md:43 +msgid "The command outputs the exact value to use for `traefik_dashboard_basicauth_htpasswd` — your username, a colon, and a hash of your chosen password:" +msgstr "" + +#: ../../../docs/configuring-playbook-traefik.md:49 +msgid "Copy the full output line into `traefik_dashboard_basicauth_htpasswd`. After deploying, log in to the dashboard using the same username and password that you chose earlier." +msgstr "" + +#: ../../../docs/configuring-playbook-traefik.md:51 +msgid "The role also supports the legacy `traefik_dashboard_basicauth_user` / `traefik_dashboard_basicauth_password` convenience variables, but that path depends on the `passlib` Python library on the Ansible controller, may be affected by passlib/bcrypt compatibility issues, and generates non-deterministic hashes which can lead to unnecessary changes." +msgstr "" + +#: ../../../docs/configuring-playbook-traefik.md:54 +msgid "Enabling the dashboard on a hostname you use for something else (like `matrix_server_fqn_matrix` in the configuration above) may cause conflicts. Enabling the Traefik Dashboard makes Traefik capture all `/dashboard` and `/api` requests and forward them to itself. If any of the services hosted on the same hostname requires any of these 2 URL prefixes, you will experience problems. So far, we're not aware of any playbook services which occupy these endpoints and are likely to cause conflicts." +msgstr "" + +#: ../../../docs/configuring-playbook-traefik.md:56 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:43 +#: ../../../docs/configuring-playbook-traefik.md:58 msgid "There are some additional things you may wish to configure about the component." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:45 +#: ../../../docs/configuring-playbook-traefik.md:60 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:47 +#: ../../../docs/configuring-playbook-traefik.md:62 msgid "[Traefik role](https://github.com/mother-of-all-self-hosting/ansible-role-traefik)'s [`defaults/main.yml`](https://github.com/mother-of-all-self-hosting/ansible-role-traefik/blob/main/defaults/main.yml) for some variables that you can customize via your `vars.yml` file. You can override settings (even those that don't have dedicated playbook variables) using the `traefik_configuration_extension_yaml` variable" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:49 +#: ../../../docs/configuring-playbook-traefik.md:64 msgid "For example, to enable and secure the Dashboard, you can add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:51 +#: ../../../docs/configuring-playbook-traefik.md:66 msgid "**Note**: this is a contrived example as you can enable and secure the Dashboard using the dedicated variables. See above for details." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:69 +#: ../../../docs/configuring-playbook-traefik.md:84 msgid "Reverse-proxying another service behind Traefik" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:71 +#: ../../../docs/configuring-playbook-traefik.md:86 msgid "The preferred way to reverse-proxy additional services behind Traefik would be to start the service as another container, configure the container with the corresponding Traefik [container labels](https://docs.docker.com/config/labels-custom-metadata/) (see [Traefik & Docker](https://doc.traefik.io/traefik/routing/providers/docker/)), and connect the service to the `traefik` network. Some services are also already available via the compatible [mash-playbook](https://github.com/mother-of-all-self-hosting/mash-playbook), but take a look at the minor [interoperability adjustments](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/interoperability.md)." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:73 +#: ../../../docs/configuring-playbook-traefik.md:88 msgid "However, if your service does not run on a container or runs on another machine, the following configuration might be what you are looking for." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:75 +#: ../../../docs/configuring-playbook-traefik.md:90 msgid "Reverse-proxying a remote HTTP/HTTPS service behind Traefik" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:77 +#: ../../../docs/configuring-playbook-traefik.md:92 msgid "If you want to host another webserver would be reachable via `my-fancy-website.example.net` from the internet and via `https://:` from inside your network, you can make the playbook's integrated Traefik instance reverse-proxy the traffic to the correct host." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:79 +#: ../../../docs/configuring-playbook-traefik.md:94 msgid "Prerequisites: DNS and routing for the domain `my-fancy-website.example.net` need to be set up correctly. In this case, you'd be pointing the domain name to your Matrix server — `my-fancy-website.example.net` would be a CNAME going to `matrix.example.com`." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:81 +#: ../../../docs/configuring-playbook-traefik.md:96 msgid "First, we have to adjust the static configuration of Traefik, so that we can add additional configuration files:" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:95 +#: ../../../docs/configuring-playbook-traefik.md:110 msgid "If you are using a self-signed certificate on your webserver, you can tell Traefik to trust your own backend servers by adding more configuration to the static configuration file. If you do so, bear in mind the security implications of disabling the certificate validity checks towards your back end." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:109 +#: ../../../docs/configuring-playbook-traefik.md:124 msgid "Next, you have to add a new dynamic configuration file for Traefik that contains the actual information of the server using the `aux_file_definitions` variable. In this example, we will terminate SSL at the Traefik instance and connect to the other server via HTTPS. Traefik will now take care of managing the certificates." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:128 -#: ../../../docs/configuring-playbook-traefik.md:151 +#: ../../../docs/configuring-playbook-traefik.md:143 +#: ../../../docs/configuring-playbook-traefik.md:166 msgid "Changing the `url` to one with an `http://` prefix would allow to connect to the server via HTTP." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:130 +#: ../../../docs/configuring-playbook-traefik.md:145 msgid "Reverse-proxying another service behind Traefik without terminating SSL" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:132 +#: ../../../docs/configuring-playbook-traefik.md:147 msgid "If you do not want to terminate SSL at the Traefik instance (for example, because you're already terminating SSL at other webserver), you need to adjust the static configuration in the same way as in the previous chapter in order to be able to add our own dynamic configuration files. Afterwards, you can add the following configuration to your `vars.yml` configuration file:" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:153 +#: ../../../docs/configuring-playbook-traefik.md:168 msgid "With these changes, all TCP traffic will be reverse-proxied to the target system." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:155 -msgid "[!WARNING] This configuration might lead to problems or need additional steps when a [certbot](https://certbot.eff.org/) behind Traefik also tries to manage [Let's Encrypt](https://letsencrypt.org/) certificates, as Traefik captures all traffic to ```PathPrefix(`/.well-known/acme-challenge/`)```." +#: ../../../docs/configuring-playbook-traefik.md:171 +msgid "This configuration might lead to problems or need additional steps when a [certbot](https://certbot.eff.org/) behind Traefik also tries to manage [Let's Encrypt](https://letsencrypt.org/) certificates, as Traefik captures all traffic to ```PathPrefix(`/.well-known/acme-challenge/`)```." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:158 +#: ../../../docs/configuring-playbook-traefik.md:173 msgid "Traefik behind a `proxy_protocol` reverse-proxy" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:160 +#: ../../../docs/configuring-playbook-traefik.md:175 msgid "If you run a reverse-proxy which speaks `proxy_protocol`, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:179 +#: ../../../docs/configuring-playbook-traefik.md:194 msgid "Other configurations" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:181 +#: ../../../docs/configuring-playbook-traefik.md:196 msgid "Adjusting SSL certificate retrieval" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:183 +#: ../../../docs/configuring-playbook-traefik.md:198 msgid "See the dedicated [Adjusting SSL certificate retrieval](configuring-playbook-ssl-certificates.md) documentation page." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:185 +#: ../../../docs/configuring-playbook-traefik.md:200 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:187 +#: ../../../docs/configuring-playbook-traefik.md:202 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:194 +#: ../../../docs/configuring-playbook-traefik.md:209 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:196 +#: ../../../docs/configuring-playbook-traefik.md:211 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:198 +#: ../../../docs/configuring-playbook-traefik.md:213 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:200 +#: ../../../docs/configuring-playbook-traefik.md:215 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-traefik`." msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:202 +#: ../../../docs/configuring-playbook-traefik.md:217 msgid "Increase logging verbosity" msgstr "" -#: ../../../docs/configuring-playbook-traefik.md:204 +#: ../../../docs/configuring-playbook-traefik.md:219 msgid "The default logging level for this component is `INFO`. If you want to increase the verbosity, add the following configuration to your `vars.yml` file and re-run the playbook:" msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-turn.pot b/i18n/translation-templates/docs/configuring-playbook-turn.pot index 98744ac3c..df238efa6 100644 --- a/i18n/translation-templates/docs/configuring-playbook-turn.pot +++ b/i18n/translation-templates/docs/configuring-playbook-turn.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,173 +21,213 @@ msgid "Configuring a TURN server (optional, advanced)" msgstr "" #: ../../../docs/configuring-playbook-turn.md:16 -msgid "By default, this playbook installs and configures the [coturn](https://github.com/coturn/coturn) as a TURN server, through which clients can make audio/video calls even from [NAT](https://en.wikipedia.org/wiki/Network_address_translation)-ed networks. It also configures the Synapse chat server by default, so that it points to the coturn TURN server installed by the playbook. If that's okay, you can skip this document." +msgid "By default, the [coturn](https://github.com/coturn/coturn) TURN server component is enabled automatically only when [Jitsi](configuring-playbook-jitsi.md) is enabled. If you're not using Jitsi, coturn is not enabled by default." msgstr "" #: ../../../docs/configuring-playbook-turn.md:18 -msgid "If you'd like to stop the playbook installing the server, see the section [below](#disabling-coturn) to check the configuration for disabling it." +msgid "If you explicitly need coturn while not using Jitsi, enable it with:" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:20 -msgid "Adjusting the playbook configuration" +#: ../../../docs/configuring-playbook-turn.md:24 +msgid "and configure its IP-related settings in the section below." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:22 -msgid "Define public IP manually (optional)" +#: ../../../docs/configuring-playbook-turn.md:26 +msgid "If you'd like coturn to stay disabled even when Jitsi is enabled, or if you prefer to use an external TURN provider, see [disabling coturn](#disabling-coturn) section below." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:24 -msgid "In the `hosts` file we explicitly ask for your server's external IP address when defining `ansible_host`, because the same value is used for configuring coturn." +#: ../../../docs/configuring-playbook-turn.md:28 +msgid "When Coturn is not enabled, homeservers (like Synapse) would not point to TURN servers and *legacy* audio/video call functionality may fail. If you're using [Matrix RTC](configuring-playbook-matrix-rtc.md) (for [Element Call](configuring-playbook-element-call.md)), you likely don't have a need to enable coturn." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:26 -msgid "If you'd rather use a local IP for `ansible_host`, add the following configuration to your `vars.yml` file. Make sure to replace `YOUR_PUBLIC_IP` with the pubic IP used by the server." +#: ../../../docs/configuring-playbook-turn.md:30 +msgid "Adjusting firewall rules" msgstr "" #: ../../../docs/configuring-playbook-turn.md:32 -msgid "If you'd like to rely on external IP address auto-detection (not recommended unless you need it), set an empty value to the variable. The playbook will automatically contact an [echoip](https://github.com/mpolden/echoip)-compatible service (`https://ifconfig.co/json` by default) to determine your server's IP address. This API endpoint is configurable via the `coturn_turn_external_ip_address_auto_detection_echoip_service_url` variable." +msgid "To ensure Coturn functions correctly, the following firewall rules and port forwarding settings are required when coturn is enabled:" msgstr "" #: ../../../docs/configuring-playbook-turn.md:34 -msgid "[!NOTE] You can self-host the echoip service by using the [Mother-of-All-Self-Hosting (MASH)](https://github.com/mother-of-all-self-hosting/mash-playbook) Ansible playbook. See [this page](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/echoip.md) for the instruction to install it with the playbook. If you are wondering how to use it for your Matrix server, refer to [this page](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/setting-up-services-on-mdad-server.md) for the overview." +msgid "`3478/tcp`: STUN/TURN over TCP" +msgstr "" + +#: ../../../docs/configuring-playbook-turn.md:35 +msgid "`3478/udp`: STUN/TURN over UDP" +msgstr "" + +#: ../../../docs/configuring-playbook-turn.md:36 +msgid "`5349/tcp`: TURN over TCP" msgstr "" #: ../../../docs/configuring-playbook-turn.md:37 -msgid "If your server has multiple external IP addresses, the coturn role offers a different variable for specifying them:" +msgid "`5349/udp`: TURN over UDP" +msgstr "" + +#: ../../../docs/configuring-playbook-turn.md:38 +msgid "`49152-49172/udp`: TURN/UDP relay range" +msgstr "" + +#: ../../../docs/configuring-playbook-turn.md:40 +msgid "If LiveKit's embedded TURN is enabled at the same time (for MatrixRTC/Element Call), keep the Coturn relay range distinct from LiveKit's relay range (`livekit_server_config_turn_relay_range_start`/`livekit_server_config_turn_relay_range_end`)." +msgstr "" + +#: ../../../docs/configuring-playbook-turn.md:42 +msgid "💡 Docker configures the server's internal firewall for you. In most cases, you don't need to do anything special on the host itself." msgstr "" #: ../../../docs/configuring-playbook-turn.md:44 -msgid "Change the authentication mechanism (optional)" +msgid "Adjusting the playbook configuration" msgstr "" #: ../../../docs/configuring-playbook-turn.md:46 -msgid "The playbook uses the [`auth-secret` authentication method](https://github.com/coturn/coturn/blob/873cabd6a2e5edd7e9cc5662cac3ffe47fe87a8e/README.turnserver#L186-L199) by default, but you may switch to the [`lt-cred-mech` method](https://github.com/coturn/coturn/blob/873cabd6a2e5edd7e9cc5662cac3ffe47fe87a8e/README.turnserver#L178) which [some report](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3191) to be working better." +msgid "Define public IP manually (optional)" msgstr "" #: ../../../docs/configuring-playbook-turn.md:48 +msgid "If you enable coturn (either via Jitsi or manually), we recommend that you configure the public IP addresses of your server in the `vars.yml` file:" +msgstr "" + +#: ../../../docs/configuring-playbook-turn.md:55 +msgid "If you'd like to rely on external IP address auto-detection (not recommended unless you need it), avoid configuring this variable. The playbook will automatically contact an [echoip](https://github.com/mpolden/echoip)-compatible service (`https://ifconfig.co/json` by default) to determine your server's IP address. This API endpoint is configurable via the `coturn_turn_external_ip_address_auto_detection_echoip_service_url` variable." +msgstr "" + +#: ../../../docs/configuring-playbook-turn.md:58 +msgid "You can self-host the echoip service by using the [Mother-of-All-Self-Hosting (MASH)](https://github.com/mother-of-all-self-hosting/mash-playbook) Ansible playbook. See [this page](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/echoip.md) for the instruction to install it with the playbook. If you are wondering how to use it for your Matrix server, refer to [this page](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/setting-up-services-on-mdad-server.md) for the overview." +msgstr "" + +#: ../../../docs/configuring-playbook-turn.md:60 +msgid "Change the authentication mechanism (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-turn.md:62 +msgid "The playbook uses the [`auth-secret` authentication method](https://github.com/coturn/coturn/blob/873cabd6a2e5edd7e9cc5662cac3ffe47fe87a8e/README.turnserver#L186-L199) by default, but you may switch to the [`lt-cred-mech` method](https://github.com/coturn/coturn/blob/873cabd6a2e5edd7e9cc5662cac3ffe47fe87a8e/README.turnserver#L178) which [some report](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3191) to be working better." +msgstr "" + +#: ../../../docs/configuring-playbook-turn.md:64 msgid "To do so, add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:54 +#: ../../../docs/configuring-playbook-turn.md:70 msgid "Regardless of the selected authentication method, the playbook generates secrets automatically and passes them to the homeserver and coturn." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:56 +#: ../../../docs/configuring-playbook-turn.md:72 msgid "If [Jitsi](configuring-playbook-jitsi.md) is installed, note that switching to `lt-cred-mech` will disable the integration between Jitsi and your coturn server, as Jitsi seems to support the `auth-secret` authentication method only." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:58 +#: ../../../docs/configuring-playbook-turn.md:74 msgid "Customize the Coturn hostname (optional)" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:60 +#: ../../../docs/configuring-playbook-turn.md:76 msgid "By default, Coturn uses the same hostname as your Matrix homeserver (the value of `matrix_server_fqn_matrix`, which is typically `matrix.example.com`)." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:62 +#: ../../../docs/configuring-playbook-turn.md:78 msgid "If you'd like to use a custom subdomain for Coturn (e.g., `turn.example.com` or `t.matrix.example.com`), add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:68 +#: ../../../docs/configuring-playbook-turn.md:84 msgid "The playbook will automatically:" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:69 +#: ../../../docs/configuring-playbook-turn.md:85 msgid "Configure Coturn to use this hostname" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:70 +#: ../../../docs/configuring-playbook-turn.md:86 msgid "Obtain an SSL certificate for the custom domain via Traefik" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:71 +#: ../../../docs/configuring-playbook-turn.md:87 msgid "Update all TURN URIs to point to the custom domain" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:73 +#: ../../../docs/configuring-playbook-turn.md:89 msgid "**Note**: Make sure the custom hostname resolves to your server's IP address via DNS before running the playbook." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:75 +#: ../../../docs/configuring-playbook-turn.md:91 msgid "Use your own external coturn server (optional)" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:77 +#: ../../../docs/configuring-playbook-turn.md:93 msgid "If you'd like to use another TURN server (be it coturn or some other one), add the following configuration to your `vars.yml` file. Make sure to replace `HOSTNAME_OR_IP` with your own." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:91 +#: ../../../docs/configuring-playbook-turn.md:107 msgid "If you have or want to enable Jitsi, you might want to enable the TURN server there too. If you do not do it, Jitsi will fall back to an upstream service." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:98 +#: ../../../docs/configuring-playbook-turn.md:114 msgid "You can put multiple host/port combinations if you'd like to." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:100 +#: ../../../docs/configuring-playbook-turn.md:116 msgid "Edit the reloading schedule (optional)" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:102 +#: ../../../docs/configuring-playbook-turn.md:118 msgid "By default the service is reloaded on 6:30 a.m. every day based on the `coturn_reload_schedule` variable so that new SSL certificates can kick in. It is defined in the format of systemd timer calendar." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:104 +#: ../../../docs/configuring-playbook-turn.md:120 msgid "To edit the schedule, add the following configuration to your `vars.yml` file (adapt to your needs):" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:110 +#: ../../../docs/configuring-playbook-turn.md:126 msgid "**Note**: the actual job may run with a delay. See `coturn_reload_schedule_randomized_delay_sec` for its default value." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:112 +#: ../../../docs/configuring-playbook-turn.md:128 msgid "Extending the configuration" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:114 +#: ../../../docs/configuring-playbook-turn.md:130 msgid "There are some additional things you may wish to configure about the TURN server." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:116 +#: ../../../docs/configuring-playbook-turn.md:132 msgid "Take a look at:" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:118 +#: ../../../docs/configuring-playbook-turn.md:134 msgid "`roles/galaxy/coturn/defaults/main.yml` for some variables that you can customize via your `vars.yml` file" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:120 +#: ../../../docs/configuring-playbook-turn.md:136 msgid "Disabling coturn" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:122 -msgid "If, for some reason, you'd like for the playbook to not install coturn (or to uninstall it if it was previously installed), add the following configuration to your `vars.yml` file:" +#: ../../../docs/configuring-playbook-turn.md:138 +msgid "Coturn is only enabled by default when [Jitsi](configuring-playbook-jitsi.md) is enabled. In most instances, you don't need to explicitly disable it." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:128 -msgid "In that case, Synapse would not point to any coturn servers and audio/video call functionality may fail." +#: ../../../docs/configuring-playbook-turn.md:140 +msgid "To force the playbook to not install Coturn (even when Jitsi is enabled), add the following configuration to your `vars.yml` file:" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:130 +#: ../../../docs/configuring-playbook-turn.md:146 msgid "Installing" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:132 +#: ../../../docs/configuring-playbook-turn.md:148 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:139 +#: ../../../docs/configuring-playbook-turn.md:155 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:141 +#: ../../../docs/configuring-playbook-turn.md:157 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/configuring-playbook-turn.md:143 +#: ../../../docs/configuring-playbook-turn.md:159 msgid "Troubleshooting" msgstr "" -#: ../../../docs/configuring-playbook-turn.md:145 +#: ../../../docs/configuring-playbook-turn.md:161 msgid "As with all other services, you can find the logs in [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html) by logging in to the server with SSH and running `journalctl -fu matrix-coturn`." msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-tuwunel.pot b/i18n/translation-templates/docs/configuring-playbook-tuwunel.pot new file mode 100644 index 000000000..7ad561f7f --- /dev/null +++ b/i18n/translation-templates/docs/configuring-playbook-tuwunel.pot @@ -0,0 +1,297 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-19 03:41+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/configuring-playbook-tuwunel.md:8 +msgid "Configuring Tuwunel (optional)" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:10 +msgid "The playbook can install and configure the [Tuwunel](https://matrix-construct.github.io/tuwunel/) Matrix homeserver for you." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:12 +msgid "Tuwunel is a featureful homeserver written entirely in Rust, intended as a scalable, low-cost, enterprise-ready alternative to Synapse that fully implements the [Matrix specification](https://spec.matrix.org/latest/) for all but the most niche uses. It is the official successor to [conduwuit](configuring-playbook-conduwuit.md), is now sponsored by the government of Switzerland 🇨🇭 (where it is currently deployed for citizens), and is used by a number of organisations with a vested interest in its continued development. See the project's [documentation](https://matrix-construct.github.io/tuwunel/) for further background." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:14 +msgid "By default, the playbook installs [Synapse](https://github.com/element-hq/synapse) as it's the only full-featured Matrix server at the moment. If that's okay, you can skip this document." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:17 +msgid "**You can't switch an existing Matrix server's implementation** (e.g. Synapse → Tuwunel). Proceed below only if you're OK with starting over, or you're dealing with a server on a new domain name which hasn't participated in the Matrix federation yet. The one exception is migrating from conduwuit; see [Migrating from conduwuit](#migrating-from-conduwuit)." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:18 +msgid "**Homeserver implementations other than Synapse may not be fully functional** with every part of this playbook. Make yourself familiar with the trade-offs before proceeding." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:20 +msgid "Adjusting the playbook configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:22 +msgid "To use Tuwunel, set the following on `inventory/host_vars/matrix.example.com/vars.yml`:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:36 +msgid "The first user account that registers becomes a server admin and is automatically invited to the admin room. See [Creating the first user account](#creating-the-first-user-account) below for the bootstrap procedure." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:38 +msgid "Wiring done for you" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:40 +msgid "When `matrix_homeserver_implementation: tuwunel` is set, the playbook automatically integrates Tuwunel with the rest of your stack:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:42 +msgid "**Federation.** Toggled by `matrix_homeserver_federation_enabled`. The federation virtual host (port 8448 in the default setup) is wired up via Traefik labels." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:43 +msgid "**Well-known.** `matrix_tuwunel_config_well_known_client` is set to your public homeserver URL whenever SSL is enabled. Matrix clients use this for delegated-domain server discovery; identity-provider entries below can also omit their `callback_url`, since Tuwunel derives `/_matrix/client/unstable/login/sso/callback/` automatically." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:44 +msgid "**Element Call / MatrixRTC.** When the [LiveKit JWT service](configuring-playbook-matrix-rtc.md) is enabled, Tuwunel publishes its public URL through `.well-known/matrix/client` per [MSC4143](https://github.com/matrix-org/matrix-spec-proposals/pull/4143)." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:45 +msgid "**Legacy calls (TURN).** When [Coturn](configuring-playbook-turn.md) is enabled, its URIs and shared secret (or username/password, depending on `coturn_authentication_method`) are wired automatically." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:47 +msgid "Extending the configuration" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:49 +msgid "Tuwunel exposes a large configuration surface. The role surfaces commonly used options as Ansible variables under `matrix_tuwunel_config_*`. See [`roles/custom/matrix-tuwunel/defaults/main.yml`](../roles/custom/matrix-tuwunel/defaults/main.yml) for the complete list, and [`roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2`](../roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2) for the rendered configuration." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:51 +msgid "For options that aren't surfaced as a dedicated variable, [environment variables](https://matrix-construct.github.io/tuwunel/configuration.html#environment-variables) are the recommended override mechanism. They take priority over the rendered TOML, are scoped to the running container, and require no template patching:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:59 +msgid "Keys nested under a TOML section use `__` (double underscore) to descend, e.g. `TUWUNEL_WELL_KNOWN__SERVER`. User-named sections become path segments too: `TUWUNEL_STORAGE_PROVIDER__ARCHIVE__S3__URL` overrides the `url` field of the `archive` storage provider in the example below." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:61 +msgid "If you need wholesale control of the configuration file, copy [`roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2`](../roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2) into your inventory and point `matrix_tuwunel_template_tuwunel_config` at your copy." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:63 +msgid "The container image published as `:latest` is built with `io_uring`, `jemalloc`, LDAP, blurhashing, URL preview, sentry telemetry, and zstd compression all enabled, so most opt-in features are simply a configuration toggle away." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:65 +msgid "Identity providers (OAuth2 / OIDC)" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:67 +msgid "Configure one or more `[[global.identity_provider]]` entries via a list. Each entry maps directly to Tuwunel's [identity-provider fields](https://matrix-construct.github.io/tuwunel/authentication/providers.html); only the fields you set are emitted. GitHub, GitLab, and Google have built-in `issuer_url` defaults so a `client_id` plus `client_secret` is enough; for any other `brand` (Apple, Facebook, Keycloak, MAS, Twitter, etc.) you must supply `issuer_url` explicitly:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:82 +msgid "Self-hosted providers must supply both `client_id` and `issuer_url`. Set `trusted: true` only on providers you operate yourself; trusting a public provider (GitHub, Google, etc.) is an account-takeover risk." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:84 +msgid "LDAP" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:86 +msgid "Tuwunel can authenticate `m.login.password` requests against an LDAP directory and, in search-then-bind mode, keep admin status in sync with directory membership. The shipped image already includes the `ldap` build feature." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:98 +msgid "`bind_password_file` is read **inside the container**. The role bind-mounts `/matrix/tuwunel/config` to `/etc/tuwunel` (read-only) and `/matrix/tuwunel/data` to `/var/lib/tuwunel`. To make the file available at the path above, drop it on the host at `/matrix/tuwunel/config/ldap.pw` (owned by `matrix:matrix`) before running the playbook; the role does not template secret files for you." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:100 +msgid "For direct-bind, anonymous-search, and admin-sync details, see [LDAP authentication](https://matrix-construct.github.io/tuwunel/authentication/ldap.html)." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:102 +msgid "JWT login" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:104 +msgid "Tuwunel can accept signed JSON Web Tokens both as a login flow and as a User-Interactive Authentication step:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:115 +msgid "The defaults match Synapse's `experimental_features.jwt_config` semantics, so a key + algorithm port should authenticate the same set of tokens. See [Enterprise JWT](https://matrix-construct.github.io/tuwunel/authentication/jwt.html) for the full reference, including the asymmetric (ECDSA / EdDSA) formats and the operator-controlled UIAA override flow." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:117 +msgid "Media storage providers" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:119 +msgid "Each entry becomes a `[global.storage_provider..]` block. `kind` is `local` or `s3`; the remaining keys map directly to the fields documented in [Storage providers](https://matrix-construct.github.io/tuwunel/media/storage.html):" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:136 +msgid "The S3 backend ships with native multipart upload, so no goofys/rclone sidecar is required. MinIO, Cloudflare R2, and DigitalOcean Spaces all work; set `endpoint` and `use_vhost_request: false` as appropriate." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:139 +msgid "Local provider paths must live under `/var/lib/tuwunel` (the container's data mount, persisted on the host at `/matrix/tuwunel/data`), or you must mount the target directory into the container yourself via `matrix_tuwunel_container_extra_arguments`. The container otherwise runs read-only." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:141 +msgid "RocksDB and cache tuning" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:143 +msgid "Tuwunel embeds RocksDB. The defaults (`rocksdb_compression_algo: zstd`) suit most deployments. For high-throughput servers you may want to enable direct I/O, raise parallelism, and configure a backup path:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:151 +msgid "`matrix_tuwunel_config_cache_capacity_modifier` is left empty by default, so Tuwunel picks a value (`1.0` since v1.7.0, with rebalanced per-cache sizes that already raise memory use). Set it to `2.0` only on small hosts with four or fewer cores; on larger machines the default is recommended." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:153 +msgid "If you run on ZFS, the [Tuwunel maintenance guide](https://matrix-construct.github.io/tuwunel/maintenance.html#zfs) lists the dataset properties (`recordsize`, `primarycache`, `compression`, `atime`, `logbias`) and config flags (`rocksdb_direct_io`, `rocksdb_allow_fallocate`) you need to adjust to avoid severe write amplification." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:155 +msgid "To enable Sentry crash reporting, set `matrix_tuwunel_config_sentry_enabled: true`." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:157 +msgid "Federation gating" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:159 +msgid "Tuwunel accepts regular-expression patterns at every level of remote-server filtering:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:170 +msgid "Tuwunel additionally implements [MSC4284 policy servers](https://github.com/matrix-org/matrix-spec-proposals/pull/4284) for room-level federation gating. The policy itself lives in room state, but enforcement is opt-in at the server level:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:177 +msgid "When enabled, rooms with a valid `m.room.policy` state event have outgoing events signed by the configured policy server before federation. Transient network or timeout failures fail open (with a warn log), so a policy-server outage will not silently take the room offline." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:179 +msgid "Default room version" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:181 +msgid "The role sets `default_room_version: '12'`, so newly created rooms default to Matrix [room version 12](https://github.com/matrix-org/matrix-spec-proposals/pull/4289) (\"Hydra\"). Override `matrix_tuwunel_config_default_room_version` if you need an earlier version for client compatibility." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:183 +msgid "The `/_tuwunel` API path" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:185 +msgid "Besides `/_matrix`, Tuwunel serves its own first-party routes under `/_tuwunel`. This namespace carries ad-hoc endpoints such as `/_tuwunel/server_version` and `/_tuwunel/local_user_count`, and the [native OpenID Connect provider](https://matrix-construct.github.io/tuwunel/authentication/oidc-server.html) endpoints (`/_tuwunel/oidc/...`) that clients use when Tuwunel handles OIDC login itself, rather than delegating to an upstream provider as described above. The role routes `/_tuwunel` on the public entrypoint by default so these features work out of the box." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:187 +msgid "To keep this namespace off the public entrypoint and expose it only on the internal one, set:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:194 +msgid "Exposing the Administration API" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:196 +msgid "Tuwunel serves a Synapse-compatible Administration API under the `/_synapse/admin` path, so administration dashboards (such as synapse-admin and ketesa) and moderation bots (such as Draupnir and Meowlnir) work against it. The served endpoints are listed on the [Tuwunel Synapse Admin API page](https://matrix-construct.github.io/tuwunel/development/compliance/synapse-admin.html)." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:198 +msgid "The API is not routed through the reverse proxy by default. Every endpoint requires an administrator access token, but you may still prefer to keep it off the public entrypoint. To reach it only from trusted networks, expose it on the internal Traefik entrypoint:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:204 +msgid "To expose it publicly instead (for example, when a dashboard runs in the browser), set:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:210 +msgid "Creating the first user account" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:212 +msgid "Unlike Synapse and Dendrite, Tuwunel does not register users from the command line or via the playbook. On first startup it logs a one-time-use registration token to its journal:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:219 +msgid "Use the token to create your first account from any client that supports token-gated registration (e.g. [Element Web](configuring-playbook-client-element-web.md)). The account is auto-promoted to admin and invited to the admin room together with the `@conduit:` server bot. The bot keeps the legacy `conduit` localpart due to the project's lineage from Conduit." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:221 +msgid "Configuring bridges and appservices" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:223 +msgid "The playbook does not auto-register appservices for Tuwunel. After your bridge has produced its `registration.yaml` (e.g. `/matrix/mautrix-signal/bridge/registration.yaml`), register it manually by sending the contents to the admin room, prefixed with `!admin appservices register` and wrapped in a fenced code block:" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:244 +msgid "Registrations stored this way are persisted in the database and survive restarts. Re-running the command with the same `id` replaces the existing entry. See [Application services](https://matrix-construct.github.io/tuwunel/appservices.html) for the full reference and admin commands." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:246 +msgid "Migrating from conduwuit" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:248 +msgid "Tuwunel is a \"binary swap\" for conduwuit; it reads conduwuit's RocksDB layout directly, so migration is a data move, not an export/import." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:250 +msgid "Set `matrix_homeserver_implementation: tuwunel` on `vars.yml` and remove any `matrix_conduwuit_*` overrides." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:251 +msgid "Run a full installation so that the new service is created and the old one removed (e.g. `just setup-all`)." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:252 +msgid "Run `just run-tags tuwunel-migrate-from-conduwuit`." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:254 +msgid "The migration stops `matrix-conduwuit.service`, copies `/matrix/conduwuit` into `/matrix/tuwunel`, renames the config file, and starts `matrix-tuwunel.service`. The freshly generated tuwunel data directory is preserved alongside as `/matrix/tuwunel_old` until you remove it manually." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:257 +msgid "Migrating from any other Conduit derivative (Conduit itself, Continuwuity, or any other fork) is **not supported** and will corrupt your database. All Conduit forks share the same linear database version with no awareness of each other; switching between them produces unrecoverable damage. See the [upstream migration table](https://matrix-construct.github.io/tuwunel/#migrating-to-tuwunel)." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:259 +msgid "Troubleshooting" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:261 +msgid "As with all other services, the logs are available via [systemd-journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html):" +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:267 +msgid "Logging verbosity is controlled by `matrix_tuwunel_config_log` in [`tracing-subscriber` env-filter syntax](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html). The default (`info,state_res=warn`) is reasonable for production; for debugging, try `debug` or scope it tighter, e.g. `info,tuwunel_service::sending=debug`." +msgstr "" + +#: ../../../docs/configuring-playbook-tuwunel.md:269 +msgid "For RocksDB-level issues, online backups, and offline backup procedures, see the [Tuwunel maintenance guide](https://matrix-construct.github.io/tuwunel/maintenance.html). For protocol-compliance state across MSCs, the spec, and Complement, the project's [compliance dashboard](https://matrix-construct.github.io/tuwunel/development/compliance.html) is the authoritative tracker." +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-playbook-user-verification-service.pot b/i18n/translation-templates/docs/configuring-playbook-user-verification-service.pot index 3b6463eb2..38c594d04 100644 --- a/i18n/translation-templates/docs/configuring-playbook-user-verification-service.pot +++ b/i18n/translation-templates/docs/configuring-playbook-user-verification-service.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -100,8 +100,8 @@ msgstr "" msgid "UVS requires an access token as an admin user to verify RoomMembership and PowerLevel against `matrix_user_verification_service_uvs_homeserver_url`. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." msgstr "" -#: ../../../docs/configuring-playbook-user-verification-service.md:53 -msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." +#: ../../../docs/configuring-playbook-user-verification-service.md:54 +msgid "Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" #: ../../../docs/configuring-playbook-user-verification-service.md:56 diff --git a/i18n/translation-templates/docs/configuring-playbook.pot b/i18n/translation-templates/docs/configuring-playbook.pot index 1edeb1fb8..f6ac8307d 100644 --- a/i18n/translation-templates/docs/configuring-playbook.pot +++ b/i18n/translation-templates/docs/configuring-playbook.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-13 05:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -97,481 +97,517 @@ msgid "[Configuring continuwuity](configuring-playbook-continuwuity.md), if you' msgstr "" #: ../../../docs/configuring-playbook.md:56 -msgid "[Configuring Dendrite](configuring-playbook-dendrite.md), if you've switched to the [Dendrite](https://matrix-org.github.io/dendrite) homeserver implementation" +msgid "[Configuring Tuwunel](configuring-playbook-tuwunel.md), if you've switched to the [Tuwunel](https://matrix-construct.github.io/tuwunel/) homeserver implementation" msgstr "" #: ../../../docs/configuring-playbook.md:58 -msgid "Server components:" +msgid "[Configuring Dendrite](configuring-playbook-dendrite.md), if you've switched to the [Dendrite](https://matrix-org.github.io/dendrite) homeserver implementation" msgstr "" -#: ../../../docs/configuring-playbook.md:59 -msgid "[Using an external PostgreSQL server](configuring-playbook-external-postgres.md)" +#: ../../../docs/configuring-playbook.md:60 +msgid "Server components:" msgstr "" #: ../../../docs/configuring-playbook.md:61 -msgid "[Configuring a TURN server](configuring-playbook-turn.md) (advanced)" +msgid "[Using an external PostgreSQL server](configuring-playbook-external-postgres.md)" msgstr "" #: ../../../docs/configuring-playbook.md:63 -msgid "[Configuring the Traefik reverse-proxy](configuring-playbook-traefik.md) (advanced)" +msgid "[Configuring a TURN server](configuring-playbook-turn.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:65 -msgid "[Using your own webserver, instead of this playbook's Traefik reverse-proxy](configuring-playbook-own-webserver.md) (advanced)" +msgid "[Configuring the Traefik reverse-proxy](configuring-playbook-traefik.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:67 -msgid "[Adjusting SSL certificate retrieval](configuring-playbook-ssl-certificates.md) (advanced)" +msgid "[Using your own webserver, instead of this playbook's Traefik reverse-proxy](configuring-playbook-own-webserver.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:69 -msgid "[Adjusting email-sending settings](configuring-playbook-email.md)" +msgid "[Adjusting SSL certificate retrieval](configuring-playbook-ssl-certificates.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:71 -msgid "[Setting up Dynamic DNS](configuring-playbook-dynamic-dns.md)" +msgid "[Adjusting email-sending settings](configuring-playbook-email.md)" msgstr "" #: ../../../docs/configuring-playbook.md:73 -msgid "Server connectivity:" +msgid "[Setting up Dynamic DNS](configuring-playbook-dynamic-dns.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:74 -msgid "[Enabling Telemetry for your Matrix server](configuring-playbook-telemetry.md)" +#: ../../../docs/configuring-playbook.md:75 +msgid "Server connectivity:" msgstr "" #: ../../../docs/configuring-playbook.md:76 -msgid "[Controlling Matrix federation](configuring-playbook-federation.md)" +msgid "[Enabling Telemetry for your Matrix server](configuring-playbook-telemetry.md)" msgstr "" #: ../../../docs/configuring-playbook.md:78 -msgid "[Configuring IPv6](./configuring-ipv6.md)" +msgid "[Controlling Matrix federation](configuring-playbook-federation.md)" msgstr "" #: ../../../docs/configuring-playbook.md:80 -msgid "Clients" +msgid "[Configuring IPv6](./configuring-ipv6.md)" msgstr "" #: ../../../docs/configuring-playbook.md:82 -msgid "Web clients for Matrix that you can host on your own domains." +msgid "Clients" msgstr "" #: ../../../docs/configuring-playbook.md:84 -msgid "[Configuring Element Web](configuring-playbook-client-element-web.md), if you're going with the default/recommended client" +msgid "Web clients for Matrix that you can host on your own domains." msgstr "" #: ../../../docs/configuring-playbook.md:86 -msgid "[Setting up Hydrogen](configuring-playbook-client-hydrogen.md), if you've enabled [Hydrogen](https://github.com/element-hq/hydrogen-web), a lightweight Matrix client with legacy and mobile browser support" +msgid "[Configuring Element Web](configuring-playbook-client-element-web.md), if you're going with the default/recommended client" msgstr "" #: ../../../docs/configuring-playbook.md:88 -msgid "[Setting up Cinny](configuring-playbook-client-cinny.md), if you've enabled [Cinny](https://github.com/ajbura/cinny), a web client focusing primarily on simple, elegant and secure interface" +msgid "[Setting up Hydrogen](configuring-playbook-client-hydrogen.md), if you've enabled [Hydrogen](https://github.com/element-hq/hydrogen-web), a lightweight Matrix client with legacy and mobile browser support" msgstr "" #: ../../../docs/configuring-playbook.md:90 -msgid "[Setting up SchildiChat Web](configuring-playbook-client-schildichat-web.md), if you've enabled [SchildiChat Web](https://schildi.chat/), a web client based on [Element Web](https://element.io/) with some extras and tweaks" +msgid "[Setting up Cinny](configuring-playbook-client-cinny.md), if you've enabled [Cinny](https://github.com/ajbura/cinny), a web client focusing primarily on simple, elegant and secure interface" msgstr "" #: ../../../docs/configuring-playbook.md:92 -msgid "[Setting up FluffyChat Web](configuring-playbook-client-fluffychat-web.md), if you've enabled [FluffyChat Web](https://github.com/krille-chan/fluffychat), a cute cross-platform messenger (web, iOS, Android) for Matrix written in [Flutter](https://flutter.dev/)" +msgid "[Setting up Sable](configuring-playbook-client-sable.md), if you've enabled [Sable](https://github.com/SableClient/Sable), a web client focusing primarily on simple, elegant and secure interface" msgstr "" -#: ../../../docs/configuring-playbook.md:95 -msgid "Authentication and user-related" +#: ../../../docs/configuring-playbook.md:94 +msgid "[Setting up SchildiChat Web](configuring-playbook-client-schildichat-web.md), if you've enabled [SchildiChat Web](https://schildi.chat/), a web client based on [Element Web](https://element.io/) with some extras and tweaks" msgstr "" -#: ../../../docs/configuring-playbook.md:97 -msgid "Extend and modify how users are authenticated on your homeserver." +#: ../../../docs/configuring-playbook.md:96 +msgid "[Setting up FluffyChat Web](configuring-playbook-client-fluffychat-web.md), if you've enabled [FluffyChat Web](https://github.com/krille-chan/fluffychat), a cute cross-platform messenger (web, iOS, Android) for Matrix written in [Flutter](https://flutter.dev/)" msgstr "" -#: ../../../docs/configuring-playbook.md:99 -msgid "[Setting up Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) (Next-generation auth for Matrix, based on OAuth 2.0/OIDC)" +#: ../../../docs/configuring-playbook.md:98 +msgid "[Setting up Commet](configuring-playbook-client-commet.md), if you've enabled [Commet](https://github.com/commetchat/commet), a Matrix web client" msgstr "" #: ../../../docs/configuring-playbook.md:101 -msgid "[Setting up Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md)" +msgid "Authentication and user-related" msgstr "" #: ../../../docs/configuring-playbook.md:103 -msgid "[Setting up Synapse Admin](configuring-playbook-synapse-admin.md)" +msgid "Extend and modify how users are authenticated on your homeserver." msgstr "" #: ../../../docs/configuring-playbook.md:105 -msgid "[Setting up matrix-registration](configuring-playbook-matrix-registration.md)" +msgid "[Setting up Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md) (Next-generation auth for Matrix, based on OAuth 2.0/OIDC)" msgstr "" #: ../../../docs/configuring-playbook.md:107 -msgid "[Setting up the REST authentication password provider module](configuring-playbook-rest-auth.md) (advanced)" +msgid "[Setting up Appservice Double Puppet](configuring-playbook-appservice-double-puppet.md)" msgstr "" #: ../../../docs/configuring-playbook.md:109 -msgid "[Setting up the Shared Secret Auth password provider module](configuring-playbook-shared-secret-auth.md) (advanced)" +msgid "[Setting up Ketesa](configuring-playbook-ketesa.md)" msgstr "" #: ../../../docs/configuring-playbook.md:111 -msgid "[Setting up the LDAP authentication password provider module](configuring-playbook-ldap-auth.md) (advanced)" +msgid "[Setting up the REST authentication password provider module](configuring-playbook-rest-auth.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:113 -msgid "[Setting up matrix-ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md) (advanced)" +msgid "[Setting up the Shared Secret Auth password provider module](configuring-playbook-shared-secret-auth.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:115 -msgid "[Setting up Synapse Simple Antispam](configuring-playbook-synapse-simple-antispam.md) (advanced)" +msgid "[Setting up the LDAP authentication password provider module](configuring-playbook-ldap-auth.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:117 -msgid "[Setting up Matrix User Verification Service](configuring-playbook-user-verification-service.md) (advanced)" +msgid "[Setting up Synapse Simple Antispam](configuring-playbook-synapse-simple-antispam.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:119 -msgid "File Storage" +msgid "[Setting up Matrix User Verification Service](configuring-playbook-user-verification-service.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:121 -msgid "Use alternative file storage to the default `media_store` folder." +msgid "File Storage" msgstr "" #: ../../../docs/configuring-playbook.md:123 -msgid "[Storing Matrix media files using matrix-media-repo](configuring-playbook-matrix-media-repo.md)" +msgid "Use alternative file storage to the default `media_store` folder." msgstr "" #: ../../../docs/configuring-playbook.md:125 -msgid "[Storing Synapse media files on Amazon S3 or another compatible Object Storage](configuring-playbook-s3.md)" +msgid "[Storing Matrix media files using matrix-media-repo](configuring-playbook-matrix-media-repo.md)" msgstr "" #: ../../../docs/configuring-playbook.md:127 -msgid "[Storing Synapse media files on Amazon S3 with Goofys](configuring-playbook-s3-goofys.md)" +msgid "[Storing Synapse media files on Amazon S3 or another compatible Object Storage](configuring-playbook-s3.md)" msgstr "" #: ../../../docs/configuring-playbook.md:129 -msgid "[Storing Synapse media files on Amazon S3 with synapse-s3-storage-provider](configuring-playbook-synapse-s3-storage-provider.md)" +msgid "[Storing Synapse media files on Amazon S3 with Goofys](configuring-playbook-s3-goofys.md)" msgstr "" #: ../../../docs/configuring-playbook.md:131 -msgid "Bridging other networks" +msgid "[Storing Synapse media files on Amazon S3 with synapse-s3-storage-provider](configuring-playbook-synapse-s3-storage-provider.md)" msgstr "" #: ../../../docs/configuring-playbook.md:133 -msgid "Bridges can be used to connect your Matrix installation with third-party communication networks." +msgid "Bridging other networks" msgstr "" #: ../../../docs/configuring-playbook.md:135 -msgid "[Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md) — a common guide for configuring mautrix bridges" +msgid "Bridges can be used to connect your Matrix installation with third-party communication networks." msgstr "" #: ../../../docs/configuring-playbook.md:137 -msgid "[Setting up Mautrix Bluesky bridging](configuring-playbook-bridge-mautrix-bluesky.md)" +msgid "[Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md) — a common guide for configuring mautrix bridges" msgstr "" #: ../../../docs/configuring-playbook.md:139 -msgid "[Setting up Mautrix Discord bridging](configuring-playbook-bridge-mautrix-discord.md)" +msgid "[Setting up Mautrix Bluesky bridging](configuring-playbook-bridge-mautrix-bluesky.md)" msgstr "" #: ../../../docs/configuring-playbook.md:141 -msgid "[Setting up Mautrix Telegram bridging](configuring-playbook-bridge-mautrix-telegram.md)" +msgid "[Setting up Mautrix Discord bridging](configuring-playbook-bridge-mautrix-discord.md)" msgstr "" #: ../../../docs/configuring-playbook.md:143 -msgid "[Setting up Mautrix Slack bridging](configuring-playbook-bridge-mautrix-slack.md)" +msgid "[Setting up Mautrix Telegram bridging](configuring-playbook-bridge-mautrix-telegram.md)" msgstr "" #: ../../../docs/configuring-playbook.md:145 -msgid "[Setting up Mautrix Google Messages bridging](configuring-playbook-bridge-mautrix-gmessages.md)" +msgid "[Setting up Mautrix Slack bridging](configuring-playbook-bridge-mautrix-slack.md)" msgstr "" #: ../../../docs/configuring-playbook.md:147 -msgid "[Setting up Mautrix Whatsapp bridging](configuring-playbook-bridge-mautrix-whatsapp.md)" +msgid "[Setting up Mautrix Google Messages bridging](configuring-playbook-bridge-mautrix-gmessages.md)" msgstr "" #: ../../../docs/configuring-playbook.md:149 -msgid "[Setting up Instagram bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-instagram.md)" +msgid "[Setting up Mautrix Google Voice bridging](configuring-playbook-bridge-mautrix-gvoice.md)" msgstr "" #: ../../../docs/configuring-playbook.md:151 -msgid "[Setting up Messenger bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-messenger.md)" +msgid "[Setting up Mautrix LinkedIn bridging](configuring-playbook-bridge-mautrix-linkedin.md)" msgstr "" #: ../../../docs/configuring-playbook.md:153 -msgid "[Setting up Mautrix Google Chat bridging](configuring-playbook-bridge-mautrix-googlechat.md)" +msgid "[Setting up Mautrix Whatsapp bridging](configuring-playbook-bridge-mautrix-whatsapp.md)" msgstr "" #: ../../../docs/configuring-playbook.md:155 -msgid "[Setting up Mautrix Twitter bridging](configuring-playbook-bridge-mautrix-twitter.md)" +msgid "[Setting up Instagram bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-instagram.md)" msgstr "" #: ../../../docs/configuring-playbook.md:157 -msgid "[Setting up Mautrix Signal bridging](configuring-playbook-bridge-mautrix-signal.md)" +msgid "[Setting up Messenger bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-messenger.md)" msgstr "" #: ../../../docs/configuring-playbook.md:159 -msgid "[Setting up Mautrix wsproxy for bridging Android SMS or Apple iMessage](configuring-playbook-bridge-mautrix-wsproxy.md)" +msgid "[Setting up Mautrix Google Chat bridging](configuring-playbook-bridge-mautrix-googlechat.md)" msgstr "" #: ../../../docs/configuring-playbook.md:161 -msgid "[Setting up Appservice IRC bridging](configuring-playbook-bridge-appservice-irc.md)" +msgid "[Setting up Mautrix Twitter bridging](configuring-playbook-bridge-mautrix-twitter.md)" msgstr "" #: ../../../docs/configuring-playbook.md:163 -msgid "[Setting up Appservice Discord bridging](configuring-playbook-bridge-appservice-discord.md)" +msgid "[Setting up Mautrix Signal bridging](configuring-playbook-bridge-mautrix-signal.md)" msgstr "" #: ../../../docs/configuring-playbook.md:165 -msgid "[Setting up Appservice Slack bridging](configuring-playbook-bridge-appservice-slack.md)" +msgid "[Setting up Mautrix wsproxy for bridging Android SMS or Apple iMessage](configuring-playbook-bridge-mautrix-wsproxy.md)" msgstr "" #: ../../../docs/configuring-playbook.md:167 -msgid "[Setting up Appservice Kakaotalk bridging](configuring-playbook-bridge-appservice-kakaotalk.md)" +msgid "[Setting up RustPush (iMessage) bridging](configuring-playbook-bridge-rustpush.md)" msgstr "" #: ../../../docs/configuring-playbook.md:169 -msgid "[Setting up Beeper LinkedIn bridging](configuring-playbook-bridge-beeper-linkedin.md)" +msgid "[Setting up Appservice IRC bridging](configuring-playbook-bridge-appservice-irc.md)" msgstr "" #: ../../../docs/configuring-playbook.md:171 -msgid "[Setting up matrix-hookshot](configuring-playbook-bridge-hookshot.md) — a bridge between Matrix and multiple project management services, such as [GitHub](https://github.com), [GitLab](https://about.gitlab.com) and [JIRA](https://www.atlassian.com/software/jira)." +msgid "[Setting up Appservice Discord bridging](configuring-playbook-bridge-appservice-discord.md)" msgstr "" #: ../../../docs/configuring-playbook.md:173 -msgid "[Setting up MX Puppet GroupMe bridging](configuring-playbook-bridge-mx-puppet-groupme.md)" +msgid "[Setting up Beeper LINE bridging](configuring-playbook-bridge-beeper-line.md)" msgstr "" #: ../../../docs/configuring-playbook.md:175 -msgid "[Setting up Steam bridging](configuring-playbook-bridge-steam.md)" +msgid "[Setting up matrix-hookshot](configuring-playbook-bridge-hookshot.md) — a bridge between Matrix and multiple project management services, such as [GitHub](https://github.com), [GitLab](https://about.gitlab.com) and [JIRA](https://www.atlassian.com/software/jira)." msgstr "" #: ../../../docs/configuring-playbook.md:177 -msgid "[Setting up MX Puppet Steam bridging](configuring-playbook-bridge-mx-puppet-steam.md)" +msgid "[Setting up MX Puppet GroupMe bridging](configuring-playbook-bridge-mx-puppet-groupme.md)" msgstr "" #: ../../../docs/configuring-playbook.md:179 -msgid "[Setting up Postmoogle email bridging](configuring-playbook-bridge-postmoogle.md)" +msgid "[Setting up Steam bridging](configuring-playbook-bridge-steam.md)" msgstr "" #: ../../../docs/configuring-playbook.md:181 -msgid "[Setting up Matrix SMS bridging](configuring-playbook-bridge-matrix-bridge-sms.md)" +msgid "[Setting up MX Puppet Steam bridging](configuring-playbook-bridge-mx-puppet-steam.md)" msgstr "" #: ../../../docs/configuring-playbook.md:183 -msgid "[Setting up Heisenbridge bouncer-style IRC bridging](configuring-playbook-bridge-heisenbridge.md)" +msgid "[Setting up Postmoogle email bridging](configuring-playbook-bridge-postmoogle.md)" msgstr "" #: ../../../docs/configuring-playbook.md:185 -msgid "[Setting up WeChat bridging](configuring-playbook-bridge-wechat.md)" +msgid "[Setting up Matrix SMS bridging](configuring-playbook-bridge-matrix-bridge-sms.md)" msgstr "" #: ../../../docs/configuring-playbook.md:187 -msgid "Bots" +msgid "[Setting up Heisenbridge bouncer-style IRC bridging](configuring-playbook-bridge-heisenbridge.md)" msgstr "" #: ../../../docs/configuring-playbook.md:189 -msgid "Bots provide various additional functionality to your installation." +msgid "[Setting up a Matrix <-> Meshtastic bridge](configuring-playbook-bridge-meshtastic-relay.md)" msgstr "" #: ../../../docs/configuring-playbook.md:191 -msgid "[Setting up baibot](configuring-playbook-bot-baibot.md) — a bot through which you can talk to various [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) services ([OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/) and [others](https://github.com/etkecc/baibot/blob/main/docs/providers.md))" +msgid "[Setting up WeChat bridging](configuring-playbook-bridge-wechat.md)" msgstr "" #: ../../../docs/configuring-playbook.md:193 -msgid "[Setting up matrix-reminder-bot](configuring-playbook-bot-matrix-reminder-bot.md) — a bot to remind you about stuff" +msgid "Bots" msgstr "" #: ../../../docs/configuring-playbook.md:195 -msgid "[Setting up matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md) — a bot to create and manage registration tokens to invite users" +msgid "Bots provide various additional functionality to your installation." msgstr "" #: ../../../docs/configuring-playbook.md:197 -msgid "[Setting up maubot](configuring-playbook-bot-maubot.md) — a plugin-based Matrix bot system" +msgid "[Setting up baibot](configuring-playbook-bot-baibot.md) — a bot through which you can talk to various [AI](https://en.wikipedia.org/wiki/Artificial_intelligence) / [Large Language Models](https://en.wikipedia.org/wiki/Large_language_model) services (the privacy-first [Venice](configuring-playbook-bot-baibot.md#venice) we recommend, [OpenAI](https://openai.com/)'s [ChatGPT](https://openai.com/blog/chatgpt/), and [others](https://github.com/etkecc/baibot/blob/main/docs/providers.md))" msgstr "" #: ../../../docs/configuring-playbook.md:199 -msgid "[Setting up Honoroit](configuring-playbook-bot-honoroit.md) — a helpdesk bot" +msgid "[Setting up matrix-reminder-bot](configuring-playbook-bot-matrix-reminder-bot.md) — a bot to remind you about stuff" msgstr "" #: ../../../docs/configuring-playbook.md:201 -msgid "[Setting up Mjolnir](configuring-playbook-bot-mjolnir.md) — a moderation tool/bot" +msgid "[Setting up maubot](configuring-playbook-bot-maubot.md) — a plugin-based Matrix bot system" msgstr "" #: ../../../docs/configuring-playbook.md:203 -msgid "[Setting up Draupnir](configuring-playbook-bot-draupnir.md) — a moderation tool/bot, forked from Mjolnir and maintained by its former leader developer" +msgid "[Setting up Honoroit](configuring-playbook-bot-honoroit.md) — a helpdesk bot" msgstr "" #: ../../../docs/configuring-playbook.md:205 -msgid "[Setting up Draupnir for all/D4A](configuring-playbook-appservice-draupnir-for-all.md) — like the [Draupnir bot](configuring-playbook-bot-draupnir.md) mentioned above, but running in appservice mode and supporting multiple instances" +msgid "[Setting up Mjolnir](configuring-playbook-bot-mjolnir.md) — a moderation tool/bot" msgstr "" #: ../../../docs/configuring-playbook.md:207 -msgid "[Setting up Buscarron](configuring-playbook-bot-buscarron.md) — a bot you can use to send any form (HTTP POST, HTML) to a (encrypted) Matrix room" +msgid "[Setting up Draupnir](configuring-playbook-bot-draupnir.md) — a moderation tool/bot, forked from Mjolnir and maintained by its former leader developer" msgstr "" #: ../../../docs/configuring-playbook.md:209 -msgid "Administration" +msgid "[Setting up Draupnir for all/D4A](configuring-playbook-appservice-draupnir-for-all.md) — like the [Draupnir bot](configuring-playbook-bot-draupnir.md) mentioned above, but running in appservice mode and supporting multiple instances" msgstr "" #: ../../../docs/configuring-playbook.md:211 -msgid "Services that help you in administrating and monitoring your Matrix installation." +msgid "[Setting up Meowlnir](configuring-playbook-bot-meowlnir.md) — a moderation tool/bot which speaks the same policy list protocol as Draupnir and Mjolnir, but runs in appservice mode and can override policies coming from lists you do not control" msgstr "" #: ../../../docs/configuring-playbook.md:213 -msgid "[Setting up Prometheus Alertmanager integration via matrix-alertmanager-receiver](configuring-playbook-alertmanager-receiver.md)" +msgid "[Setting up Buscarron](configuring-playbook-bot-buscarron.md) — a bot you can use to send any form (HTTP POST, HTML) to a (encrypted) Matrix room" msgstr "" #: ../../../docs/configuring-playbook.md:215 -msgid "[Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md)" +msgid "Administration" msgstr "" #: ../../../docs/configuring-playbook.md:217 -msgid "[Setting up the rageshake bug report server](configuring-playbook-rageshake.md)" +msgid "Services that help you in administrating and monitoring your Matrix installation." msgstr "" #: ../../../docs/configuring-playbook.md:219 -msgid "[Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md)" +msgid "[Setting up Prometheus Alertmanager integration via matrix-alertmanager-receiver](configuring-playbook-alertmanager-receiver.md)" msgstr "" #: ../../../docs/configuring-playbook.md:221 -msgid "Backups:" +msgid "[Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:222 -msgid "[Setting up BorgBackup](configuring-playbook-backup-borg.md) — a full Matrix server backup solution, including the Postgres database" +#: ../../../docs/configuring-playbook.md:223 +msgid "[Setting up the rageshake bug report server](configuring-playbook-rageshake.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:224 -msgid "[Setting up Postgres backup](configuring-playbook-postgres-backup.md) — a Postgres-database backup solution (note: does not include other files)" +#: ../../../docs/configuring-playbook.md:225 +msgid "[Enabling synapse-usage-exporter for Synapse usage statistics](configuring-playbook-synapse-usage-exporter.md)" msgstr "" -#: ../../../docs/configuring-playbook.md:226 -msgid "Other specialized services" +#: ../../../docs/configuring-playbook.md:227 +msgid "Backups:" msgstr "" #: ../../../docs/configuring-playbook.md:228 -msgid "Various services that don't fit any other categories." +msgid "[Setting up BorgBackup](configuring-playbook-backup-borg.md) — a full Matrix server backup solution, including the Postgres database" msgstr "" #: ../../../docs/configuring-playbook.md:230 -msgid "[Setting up Element Call](configuring-playbook-element-call.md) — a native Matrix video conferencing application, built on top of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" +msgid "[Setting up Postgres backup](configuring-playbook-postgres-backup.md) — a Postgres-database backup solution (note: does not include other files)" msgstr "" #: ../../../docs/configuring-playbook.md:232 -msgid "[Setting up LiveKit JWT Service](configuring-playbook-livekit-jwt-service.md) - a component of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" +msgid "Other specialized services" msgstr "" #: ../../../docs/configuring-playbook.md:234 -msgid "[Setting up LiveKit Server](configuring-playbook-livekit-server.md) - a component of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" +msgid "Various services that don't fit any other categories." msgstr "" #: ../../../docs/configuring-playbook.md:236 -msgid "[Setting up Matrix RTC](configuring-playbook-matrix-rtc.md) (optional)" +msgid "[Setting up Element Call](configuring-playbook-element-call.md) — a native Matrix video conferencing application, built on top of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" msgstr "" #: ../../../docs/configuring-playbook.md:238 -msgid "[Setting up Synapse Auto Invite Accept](configuring-playbook-synapse-auto-accept-invite.md)" +msgid "[Setting up LiveKit JWT Service](configuring-playbook-livekit-jwt-service.md) - a component of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" msgstr "" #: ../../../docs/configuring-playbook.md:240 -msgid "[Setting up synapse-auto-compressor](configuring-playbook-synapse-auto-compressor.md) for compressing the database on Synapse homeservers" +msgid "[Setting up LiveKit Server](configuring-playbook-livekit-server.md) - a component of the [Matrix RTC stack](configuring-playbook-matrix-rtc.md) (optional)" msgstr "" #: ../../../docs/configuring-playbook.md:242 -msgid "[Setting up Matrix Corporal](configuring-playbook-matrix-corporal.md) (advanced)" +msgid "[Setting up Matrix RTC](configuring-playbook-matrix-rtc.md) (optional)" msgstr "" #: ../../../docs/configuring-playbook.md:244 -msgid "[Setting up Matrix.to](configuring-playbook-matrixto.md)" +msgid "[Setting up synapse-auto-compressor](configuring-playbook-synapse-auto-compressor.md) for compressing the database on Synapse homeservers" msgstr "" #: ../../../docs/configuring-playbook.md:246 -msgid "[Setting up Etherpad](configuring-playbook-etherpad.md)" +msgid "[Setting up Matrix Corporal](configuring-playbook-matrix-corporal.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:248 -msgid "[Setting up the Jitsi video-conferencing platform](configuring-playbook-jitsi.md)" +msgid "[Setting up Matrix.to](configuring-playbook-matrixto.md)" msgstr "" #: ../../../docs/configuring-playbook.md:250 -msgid "[Setting up Cactus Comments](configuring-playbook-cactus-comments.md) — a federated comment system built on Matrix" +msgid "[Setting up Etherpad](configuring-playbook-etherpad.md)" msgstr "" #: ../../../docs/configuring-playbook.md:252 -msgid "[Setting up Pantalaimon (E2EE aware proxy daemon)](configuring-playbook-pantalaimon.md) (advanced)" +msgid "[Setting up the Jitsi video-conferencing platform](configuring-playbook-jitsi.md)" msgstr "" #: ../../../docs/configuring-playbook.md:254 -msgid "[Setting up the Sygnal push gateway](configuring-playbook-sygnal.md)" +msgid "[Setting up Cactus Comments](configuring-playbook-cactus-comments.md) — a federated comment system built on Matrix" msgstr "" #: ../../../docs/configuring-playbook.md:256 -msgid "[Setting up the ntfy push notifications server](configuring-playbook-ntfy.md)" +msgid "[Setting up Pantalaimon (E2EE aware proxy daemon)](configuring-playbook-pantalaimon.md) (advanced)" msgstr "" #: ../../../docs/configuring-playbook.md:258 -msgid "Deprecated / unmaintained / removed services" +msgid "[Setting up the Sygnal push gateway](configuring-playbook-sygnal.md)" msgstr "" #: ../../../docs/configuring-playbook.md:260 -msgid "**Note**: since a deprecated or unmaintained service will not be updated, its bug or vulnerability will be unlikely to get patched. It is recommended to migrate from the service to an alternative if any, and make sure to do your own research before you decide to keep it running nonetheless." +msgid "[Setting up the ntfy push notifications server](configuring-playbook-ntfy.md)" msgstr "" #: ../../../docs/configuring-playbook.md:262 -msgid "[Configuring conduwuit](configuring-playbook-conduwuit.md) (removed; this component has been abandoned and unmaintained)" +msgid "Deprecated / unmaintained / removed services" msgstr "" #: ../../../docs/configuring-playbook.md:264 -msgid "[Setting up the Sliding Sync proxy](configuring-playbook-sliding-sync-proxy.md) for clients which require Sliding Sync support (like old Element X versions, before it got switched to Simplified Sliding Sync)" +msgid "**Note**: since a deprecated or unmaintained service will not be updated, its bug or vulnerability will be unlikely to get patched. It is recommended to migrate from the service to an alternative if any, and make sure to do your own research before you decide to keep it running nonetheless." msgstr "" #: ../../../docs/configuring-playbook.md:266 -msgid "[Setting up Appservice Webhooks bridging](configuring-playbook-bridge-appservice-webhooks.md) (deprecated; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md))" +msgid "[Configuring conduwuit](configuring-playbook-conduwuit.md) (removed; this component has been abandoned and unmaintained)" msgstr "" #: ../../../docs/configuring-playbook.md:268 -msgid "[Setting up the Dimension integration manager](configuring-playbook-dimension.md) ([unmaintained](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2806#issuecomment-1673559299); after [installing](installing.md))" +msgid "[Setting up the Sliding Sync proxy](configuring-playbook-sliding-sync-proxy.md) for clients which require Sliding Sync support (like old Element X versions, before it got switched to Simplified Sliding Sync)" msgstr "" #: ../../../docs/configuring-playbook.md:270 -msgid "[Setting up Email2Matrix](configuring-playbook-email2matrix.md) (removed; the author suggests taking a look at [Postmoogle](https://github.com/etkecc/postmoogle) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-postmoogle.md))" +msgid "[Setting up Appservice Kakaotalk bridging](configuring-playbook-bridge-appservice-kakaotalk.md) (removed; the upstream repository has become unreachable and the component could only be installed by self-building it)" msgstr "" #: ../../../docs/configuring-playbook.md:272 -msgid "[Setting up Go-NEB](configuring-playbook-bot-go-neb.md) (unmaintained; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md))" +msgid "[Setting up Appservice Slack bridging](configuring-playbook-bridge-appservice-slack.md) (removed; this component has been discontinued)" msgstr "" #: ../../../docs/configuring-playbook.md:274 -msgid "[Setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md) (removed; Skype has been discontinued since May 2025)" +msgid "[Setting up Appservice Webhooks bridging](configuring-playbook-bridge-appservice-webhooks.md) (deprecated; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md))" msgstr "" #: ../../../docs/configuring-playbook.md:276 -msgid "[Setting up ma1sd Identity Server](configuring-playbook-ma1sd.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook.)" +msgid "[Setting up Beeper LinkedIn bridging](configuring-playbook-bridge-beeper-linkedin.md) (unmaintained; the [upstream repository](https://github.com/beeper/linkedin) has been archived. Consider [setting up Mautrix LinkedIn bridging](configuring-playbook-bridge-mautrix-linkedin.md))" msgstr "" #: ../../../docs/configuring-playbook.md:278 -msgid "[Setting up matrix-bot-chatgpt](configuring-playbook-bot-chatgpt.md) (unmaintained; the bridge's author suggests taking a look at [baibot](https://github.com/etkecc/baibot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bot-baibot.md))" +msgid "[Setting up the Dimension integration manager](configuring-playbook-dimension.md) ([unmaintained](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2806#issuecomment-1673559299); after [installing](installing.md))" msgstr "" #: ../../../docs/configuring-playbook.md:280 -msgid "[Setting up Mautrix Facebook bridging](configuring-playbook-bridge-mautrix-facebook.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-messenger](configuring-playbook-bridge-mautrix-meta-messenger.md))" +msgid "[Setting up Email2Matrix](configuring-playbook-email2matrix.md) (removed; the author suggests taking a look at [Postmoogle](https://github.com/etkecc/postmoogle) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-postmoogle.md))" msgstr "" #: ../../../docs/configuring-playbook.md:282 -msgid "[Setting up Mautrix Instagram bridging](configuring-playbook-bridge-mautrix-instagram.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-instagram](configuring-playbook-bridge-mautrix-meta-instagram.md))" +msgid "[Setting up Go-NEB](configuring-playbook-bot-go-neb.md) (unmaintained; the bridge's author suggests taking a look at [matrix-hookshot](https://github.com/matrix-org/matrix-hookshot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bridge-hookshot.md))" msgstr "" #: ../../../docs/configuring-playbook.md:284 -msgid "[Setting up MX Puppet Discord bridging](configuring-playbook-bridge-mx-puppet-discord.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Discord bridging](configuring-playbook-bridge-mautrix-discord.md))" +msgid "[Setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md) (removed; Skype has been discontinued since May 2025)" msgstr "" #: ../../../docs/configuring-playbook.md:286 -msgid "[Setting up MX Puppet Instagram bridging](configuring-playbook-bridge-mx-puppet-instagram.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Instagram bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-instagram.md))" +msgid "[Setting up ma1sd Identity Server](configuring-playbook-ma1sd.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook.)" msgstr "" #: ../../../docs/configuring-playbook.md:288 -msgid "[Setting up MX Puppet Skype bridging](configuring-playbook-bridge-mx-puppet-skype.md) (removed; this component has been broken for a long time, so it has been removed from the playbook. Consider [setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md))" +msgid "[Setting up matrix-bot-chatgpt](configuring-playbook-bot-chatgpt.md) (unmaintained; the bridge's author suggests taking a look at [baibot](https://github.com/etkecc/baibot) as a replacement, which can also be [installed using this playbook](configuring-playbook-bot-baibot.md))" msgstr "" #: ../../../docs/configuring-playbook.md:290 -msgid "[Setting up MX Puppet Slack bridging](configuring-playbook-bridge-mx-puppet-slack.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Slack bridging](configuring-playbook-bridge-mautrix-slack.md))" +msgid "[Setting up matrix-ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md) (removed; the repository of the source code has been removed)" msgstr "" #: ../../../docs/configuring-playbook.md:292 +msgid "[Setting up matrix-registration](configuring-playbook-matrix-registration.md) (removed; this component has been unmaintained)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:294 +msgid "[Setting up matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md) (removed; this component has been unmaintained)" +msgstr "" + +#: ../../../docs/configuring-playbook.md:296 +msgid "[Setting up Mautrix Facebook bridging](configuring-playbook-bridge-mautrix-facebook.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-messenger](configuring-playbook-bridge-mautrix-meta-messenger.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:298 +msgid "[Setting up Mautrix Instagram bridging](configuring-playbook-bridge-mautrix-instagram.md) (deprecated in favor of the Messenger/Instagram bridge with [mautrix-meta-instagram](configuring-playbook-bridge-mautrix-meta-instagram.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:300 +msgid "[Setting up MX Puppet Discord bridging](configuring-playbook-bridge-mx-puppet-discord.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Discord bridging](configuring-playbook-bridge-mautrix-discord.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:302 +msgid "[Setting up MX Puppet Instagram bridging](configuring-playbook-bridge-mx-puppet-instagram.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Instagram bridging via Mautrix Meta](configuring-playbook-bridge-mautrix-meta-instagram.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:304 +msgid "[Setting up MX Puppet Skype bridging](configuring-playbook-bridge-mx-puppet-skype.md) (removed; this component has been broken for a long time, so it has been removed from the playbook. Consider [setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:306 +msgid "[Setting up MX Puppet Slack bridging](configuring-playbook-bridge-mx-puppet-slack.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Slack bridging](configuring-playbook-bridge-mautrix-slack.md))" +msgstr "" + +#: ../../../docs/configuring-playbook.md:308 msgid "[Setting up MX Puppet Twitter bridging](configuring-playbook-bridge-mx-puppet-twitter.md) (removed; this component has been unmaintained for a long time, so it has been removed from the playbook. Consider [setting up Mautrix Twitter bridging](configuring-playbook-bridge-mautrix-twitter.md))" msgstr "" + +#: ../../../docs/configuring-playbook.md:310 +msgid "[Setting up Synapse Auto Invite Accept](configuring-playbook-synapse-auto-accept-invite.md) (removed; since Synapse [v1.109.0](https://github.com/element-hq/synapse/releases/tag/v1.109.0) the same feature is available natively.)" +msgstr "" diff --git a/i18n/translation-templates/docs/configuring-well-known.pot b/i18n/translation-templates/docs/configuring-well-known.pot index 704a96399..4df099e4f 100644 --- a/i18n/translation-templates/docs/configuring-well-known.pot +++ b/i18n/translation-templates/docs/configuring-well-known.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-21 04:48+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -165,89 +165,101 @@ msgid "set up the server at your base domain (e.g. `example.com`) so that it add msgstr "" #: ../../../docs/configuring-well-known.md:107 +msgid "make sure the files are served with a `Content-Type: application/json` HTTP header. You can verify this by running `curl -i https://example.com/.well-known/matrix/client`. Some web servers serve extensionless files as plain text or even offer them as downloads, which breaks stricter clients such as Element X ([manifesting as errors like `MISSING_MATRIX_RTC_FOCUS`](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/4763)). On Apache-based hosting, you can force the correct content type by placing an `.htaccess` file next to the files:" +msgstr "" + +#: ../../../docs/configuring-well-known.md:115 msgid "This is relatively easy to do and possibly your only choice if you can only host static files from the base domain's server. It is, however, **a little fragile**, as future updates performed by this playbook may regenerate the well-known files and you may need to notice that and copy them over again." msgstr "" -#: ../../../docs/configuring-well-known.md:109 +#: ../../../docs/configuring-well-known.md:117 msgid "(Option 2): **Setting up reverse-proxying** of the well-known files from the base domain's server to the Matrix server" msgstr "" -#: ../../../docs/configuring-well-known.md:111 +#: ../../../docs/configuring-well-known.md:119 msgid "This option is less fragile and generally better." msgstr "" -#: ../../../docs/configuring-well-known.md:113 +#: ../../../docs/configuring-well-known.md:121 msgid "On the base domain's server (e.g. `example.com`), you can set up reverse-proxying (or simply a 302 redirect), so that any access for the `/.well-known/matrix` location prefix is forwarded to the Matrix domain's server (e.g. `matrix.example.com`)." msgstr "" -#: ../../../docs/configuring-well-known.md:115 -msgid "With this method, you **don't need** to add special HTTP headers for [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) reasons (like `Access-Control-Allow-Origin`), because your Matrix server (where requests ultimately go) will be configured by this playbook correctly." +#: ../../../docs/configuring-well-known.md:123 +msgid "With reverse-proxying, you **don't need** to add special HTTP headers for [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) reasons (like `Access-Control-Allow-Origin`), because your Matrix server (where requests ultimately go) will be configured by this playbook correctly." msgstr "" -#: ../../../docs/configuring-well-known.md:117 +#: ../../../docs/configuring-well-known.md:125 +msgid "If you use a 302 redirect instead, be aware that browsers apply CORS checks to every response in the redirect chain, so the redirect response itself must also carry an `Access-Control-Allow-Origin: *` header. Otherwise, web-based Matrix clients (like Element Web) may fail to work even though the final destination sets the header correctly." +msgstr "" + +#: ../../../docs/configuring-well-known.md:127 msgid "**For nginx**, it would be something like this:" msgstr "" -#: ../../../docs/configuring-well-known.md:134 +#: ../../../docs/configuring-well-known.md:144 msgid "**For Apache2**, it would be something like this:" msgstr "" -#: ../../../docs/configuring-well-known.md:148 +#: ../../../docs/configuring-well-known.md:158 msgid "**For Caddy 2**, it would be something like this:" msgstr "" -#: ../../../docs/configuring-well-known.md:158 +#: ../../../docs/configuring-well-known.md:168 +msgid "**Note**: Caddy does not process directives in the order they appear in the Caddyfile, but according to its own [directive order](https://caddyserver.com/docs/caddyfile/directives#directive-order). Notably, `redir` is evaluated before `reverse_proxy`, so a `redir` elsewhere in the same site block (a common way to send the base domain to `www.example.com` or to another site) takes precedence and breaks the well-known reverse-proxying. In such cases, wrap the directives in [`handle`](https://caddyserver.com/docs/caddyfile/directives/handle) blocks to enforce the intended priority:" +msgstr "" + +#: ../../../docs/configuring-well-known.md:185 msgid "**For HAProxy**, it would be something like this:" msgstr "" -#: ../../../docs/configuring-well-known.md:177 +#: ../../../docs/configuring-well-known.md:204 msgid "**For Netlify**, configure a [redirect](https://docs.netlify.com/routing/redirects/) using a `_redirects` file in the [publish directory](https://docs.netlify.com/configure-builds/overview/#definitions) with contents like this:" msgstr "" -#: ../../../docs/configuring-well-known.md:183 +#: ../../../docs/configuring-well-known.md:210 msgid "**For AWS CloudFront**" msgstr "" -#: ../../../docs/configuring-well-known.md:185 +#: ../../../docs/configuring-well-known.md:212 msgid "Add a custom origin with matrix.example.com to your distribution" msgstr "" -#: ../../../docs/configuring-well-known.md:186 +#: ../../../docs/configuring-well-known.md:213 msgid "Add two behaviors, one for `.well-known/matrix/client` and one for `.well-known/matrix/server` and point them to your new origin." msgstr "" -#: ../../../docs/configuring-well-known.md:188 +#: ../../../docs/configuring-well-known.md:215 msgid "Make sure to:" msgstr "" -#: ../../../docs/configuring-well-known.md:190 +#: ../../../docs/configuring-well-known.md:217 msgid "**replace `example.com`** in the server configuration with your actual domain name" msgstr "" -#: ../../../docs/configuring-well-known.md:191 +#: ../../../docs/configuring-well-known.md:218 msgid "and: to **do this for the HTTPS-enabled server block**, as that's where Matrix expects the file to be" msgstr "" -#: ../../../docs/configuring-well-known.md:193 +#: ../../../docs/configuring-well-known.md:220 msgid "Confirming it works" msgstr "" -#: ../../../docs/configuring-well-known.md:195 +#: ../../../docs/configuring-well-known.md:222 msgid "No matter which method you've used to set up the well-known files, if you've done it correctly you should be able to see a JSON file at these URLs:" msgstr "" -#: ../../../docs/configuring-well-known.md:197 +#: ../../../docs/configuring-well-known.md:224 msgid "`https://example.com/.well-known/matrix/server`" msgstr "" -#: ../../../docs/configuring-well-known.md:198 +#: ../../../docs/configuring-well-known.md:225 msgid "`https://example.com/.well-known/matrix/client`" msgstr "" -#: ../../../docs/configuring-well-known.md:199 +#: ../../../docs/configuring-well-known.md:226 msgid "`https://example.com/.well-known/matrix/support`" msgstr "" -#: ../../../docs/configuring-well-known.md:201 +#: ../../../docs/configuring-well-known.md:228 msgid "You can also check if everything is configured correctly, by [checking if services work](maintenance-and-troubleshooting.md#how-to-check-if-services-work)." msgstr "" diff --git a/i18n/translation-templates/docs/container-images.pot b/i18n/translation-templates/docs/container-images.pot index 40a15eb74..503adb47f 100644 --- a/i18n/translation-templates/docs/container-images.pot +++ b/i18n/translation-templates/docs/container-images.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-13 05:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -92,6 +92,18 @@ msgstr "" msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. continuwuity is a continuation of conduwuit." msgstr "" +#: ../../../docs/container-images.md:0 +msgid "[Tuwunel](configuring-playbook-tuwunel.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[matrix-construct/tuwunel](https://ghcr.io/matrix-construct/tuwunel)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Tuwunel is the official successor to conduwuit." +msgstr "" + #: ../../../docs/container-images.md:0 msgid "[Dendrite](configuring-playbook-dendrite.md)" msgstr "" @@ -104,11 +116,11 @@ msgstr "" msgid "Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Dendrite is a second-generation Matrix homeserver written in Go, an alternative to Synapse." msgstr "" -#: ../../../docs/container-images.md:33 +#: ../../../docs/container-images.md:34 msgid "Clients" msgstr "" -#: ../../../docs/container-images.md:35 +#: ../../../docs/container-images.md:36 msgid "Web clients for Matrix that you can host on your own domains." msgstr "" @@ -148,6 +160,14 @@ msgstr "" msgid "Simple, elegant and secure web client" msgstr "" +#: ../../../docs/container-images.md:0 +msgid "[Sable](configuring-playbook-client-sable.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[7w1/sable](https://ghcr.io/7w1/sable)" +msgstr "" + #: ../../../docs/container-images.md:0 msgid "[SchildiChat Web](configuring-playbook-client-schildichat-web.md)" msgstr "" @@ -160,11 +180,11 @@ msgstr "" msgid "Based on Element Web, with a more traditional instant messaging experience" msgstr "" -#: ../../../docs/container-images.md:44 +#: ../../../docs/container-images.md:46 msgid "Server Components" msgstr "" -#: ../../../docs/container-images.md:46 +#: ../../../docs/container-images.md:48 msgid "Services that run on the server to make the various parts of your installation work." msgstr "" @@ -264,11 +284,11 @@ msgstr "" msgid "JWT service for integrating [Element Call](./configuring-playbook-element-call.md) with [LiveKit Server](./configuring-playbook-livekit-server.md)" msgstr "" -#: ../../../docs/container-images.md:59 +#: ../../../docs/container-images.md:61 msgid "Authentication" msgstr "" -#: ../../../docs/container-images.md:61 +#: ../../../docs/container-images.md:63 msgid "Extend and modify how users are authenticated on your homeserver." msgstr "" @@ -300,30 +320,6 @@ msgstr "" msgid "LDAP Auth password provider module" msgstr "" -#: ../../../docs/container-images.md:0 -msgid "[matrix-ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md)" -msgstr "" - -#: ../../../docs/container-images.md:0 -msgid "[activism.international/matrix_ldap_registration_proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy/container_registry)" -msgstr "" - -#: ../../../docs/container-images.md:0 -msgid "Proxy that handles Matrix registration requests and forwards them to LDAP" -msgstr "" - -#: ../../../docs/container-images.md:0 -msgid "[matrix-registration](configuring-playbook-matrix-registration.md)" -msgstr "" - -#: ../../../docs/container-images.md:0 -msgid "[zeratax/matrix-registration](https://hub.docker.com/r/devture/zeratax-matrix-registration/)" -msgstr "" - -#: ../../../docs/container-images.md:0 -msgid "Simple python application to have a token based Matrix registration" -msgstr "" - #: ../../../docs/container-images.md:0 msgid "[Matrix User Verification Service](configuring-playbook-user-verification-service.md)" msgstr "" @@ -448,6 +444,30 @@ msgstr "" msgid "Bridge to [Google Messages](https://messages.google.com/)" msgstr "" +#: ../../../docs/container-images.md:0 +msgid "[mautrix-gvoice](configuring-playbook-bridge-mautrix-gvoice.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[mautrix/gvoice](https://mau.dev/mautrix/gvoice/container_registry)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "Bridge to [Google Voice](https://voice.google.com/)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[mautrix-linkedin](configuring-playbook-bridge-mautrix-linkedin.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[mautrix/linkedin](https://mau.dev/mautrix/linkedin/container_registry)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "Bridge to [LinkedIn](https://www.linkedin.com/)" +msgstr "" + #: ../../../docs/container-images.md:0 msgid "[mautrix-whatsapp](configuring-playbook-bridge-mautrix-whatsapp.md)" msgstr "" @@ -529,31 +549,27 @@ msgid "[beeper/linkedin](https://ghcr.io/beeper/linkedin)" msgstr "" #: ../../../docs/container-images.md:0 -msgid "Bridge to [LinkedIn](https://www.linkedin.com/)" +msgid "[beeper-line](configuring-playbook-bridge-beeper-line.md)" msgstr "" #: ../../../docs/container-images.md:0 -msgid "[matrix-appservice-irc](configuring-playbook-bridge-appservice-irc.md)" +msgid "[crispyduck/beeper-line](https://hub.docker.com/r/crispyduck/beeper-line)" msgstr "" #: ../../../docs/container-images.md:0 -msgid "[matrixdotorg/matrix-appservice-irc](https://hub.docker.com/r/matrixdotorg/matrix-appservice-irc)" -msgstr "" - -#: ../../../docs/container-images.md:0 -msgid "Bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat)" +msgid "Bridge to [LINE](https://line.me/)" msgstr "" #: ../../../docs/container-images.md:0 -msgid "[matrix-appservice-kakaotalk](configuring-playbook-bridge-appservice-kakaotalk.md)" +msgid "[matrix-appservice-irc](configuring-playbook-bridge-appservice-irc.md)" msgstr "" #: ../../../docs/container-images.md:0 -msgid "Self-building" +msgid "[matrixdotorg/matrix-appservice-irc](https://hub.docker.com/r/matrixdotorg/matrix-appservice-irc)" msgstr "" #: ../../../docs/container-images.md:0 -msgid "Bridge to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG)" +msgid "Bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat)" msgstr "" #: ../../../docs/container-images.md:0 @@ -568,14 +584,6 @@ msgstr "" msgid "Bridge to [Discord](https://discordapp.com/)" msgstr "" -#: ../../../docs/container-images.md:0 -msgid "[matrix-appservice-slack](configuring-playbook-bridge-appservice-slack.md)" -msgstr "" - -#: ../../../docs/container-images.md:0 -msgid "[matrixdotorg/matrix-appservice-slack](https://hub.docker.com/r/matrixdotorg/matrix-appservice-slack)" -msgstr "" - #: ../../../docs/container-images.md:0 msgid "[matrix-hookshot](configuring-playbook-bridge-hookshot.md)" msgstr "" @@ -648,6 +656,18 @@ msgstr "" msgid "Bridge to [Steam](https://steampowered.com/)" msgstr "" +#: ../../../docs/container-images.md:0 +msgid "[matrix-rustpush-bridge](configuring-playbook-bridge-rustpush.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[jasonlaguidice/imessage](https://github.com/jasonlaguidice/imessage/pkgs/container/imessage)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "Bridge to [iMessage](https://support.apple.com/messages) via Apple Push Notification service" +msgstr "" + #: ../../../docs/container-images.md:0 msgid "[mx-puppet-steam](configuring-playbook-bridge-mx-puppet-steam.md)" msgstr "" @@ -672,11 +692,11 @@ msgstr "" msgid "Email to Matrix bridge" msgstr "" -#: ../../../docs/container-images.md:114 +#: ../../../docs/container-images.md:116 msgid "Bots" msgstr "" -#: ../../../docs/container-images.md:116 +#: ../../../docs/container-images.md:118 msgid "Bots provide various additional functionality to your installation." msgstr "" @@ -704,18 +724,6 @@ msgstr "" msgid "Bot for scheduling one-off & recurring reminders and alarms" msgstr "" -#: ../../../docs/container-images.md:0 -msgid "[matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md)" -msgstr "" - -#: ../../../docs/container-images.md:0 -msgid "[moanos/matrix-registration-bot](https://hub.docker.com/r/moanos/matrix-registration-bot/)" -msgstr "" - -#: ../../../docs/container-images.md:0 -msgid "Bot for invitations by creating and managing registration tokens" -msgstr "" - #: ../../../docs/container-images.md:0 msgid "[maubot](configuring-playbook-bot-maubot.md)" msgstr "" @@ -764,6 +772,18 @@ msgstr "" msgid "Moderation tool for Matrix (Fork of Mjolnir)" msgstr "" +#: ../../../docs/container-images.md:0 +msgid "[Meowlnir](configuring-playbook-bot-meowlnir.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[maunium/meowlnir](https://mau.dev/maunium/meowlnir/container_registry)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "Moderation tool for Matrix, running in appservice mode" +msgstr "" + #: ../../../docs/container-images.md:0 msgid "[Buscarron](configuring-playbook-bot-buscarron.md)" msgstr "" @@ -776,11 +796,11 @@ msgstr "" msgid "Web forms (HTTP POST) to Matrix" msgstr "" -#: ../../../docs/container-images.md:129 +#: ../../../docs/container-images.md:131 msgid "Administration" msgstr "" -#: ../../../docs/container-images.md:131 +#: ../../../docs/container-images.md:133 msgid "Services that help you in administrating and monitoring your Matrix installation." msgstr "" @@ -809,15 +829,15 @@ msgid "OAuth 2.0 and OpenID Provider server" msgstr "" #: ../../../docs/container-images.md:0 -msgid "[synapse-admin](configuring-playbook-synapse-admin.md)" +msgid "[Ketesa](configuring-playbook-ketesa.md)" msgstr "" #: ../../../docs/container-images.md:0 -msgid "[etke.cc/synapse-admin](https://ghcr.io/etkecc/synapse-admin)" +msgid "[etkecc/ketesa](https://ghcr.io/etkecc/ketesa)" msgstr "" #: ../../../docs/container-images.md:0 -msgid "Web UI tool for administrating users and rooms on your Matrix server" +msgid "Fully-featured web UI for administrating your Matrix homeserver — users, rooms, media, sessions, and more" msgstr "" #: ../../../docs/container-images.md:0 @@ -897,23 +917,19 @@ msgid "[synapse-usage-exporter](configuring-playbook-synapse-usage-exporter.md)" msgstr "" #: ../../../docs/container-images.md:0 -msgid "Export the usage statistics of a Synapse homeserver to be scraped by Prometheus." +msgid "Self-building" msgstr "" -#: ../../../docs/container-images.md:147 -msgid "Misc" +#: ../../../docs/container-images.md:0 +msgid "Export the usage statistics of a Synapse homeserver to be scraped by Prometheus." msgstr "" #: ../../../docs/container-images.md:149 -msgid "Various services that don't fit any other categories." -msgstr "" - -#: ../../../docs/container-images.md:0 -msgid "[synapse_auto_accept_invite](configuring-playbook-synapse-auto-accept-invite.md)" +msgid "Misc" msgstr "" -#: ../../../docs/container-images.md:0 -msgid "Synapse module to automatically accept invites" +#: ../../../docs/container-images.md:151 +msgid "Various services that don't fit any other categories." msgstr "" #: ../../../docs/container-images.md:0 @@ -957,7 +973,7 @@ msgid "[Jitsi](configuring-playbook-jitsi.md)" msgstr "" #: ../../../docs/container-images.md:0 -msgid "[jitsi/web](https://hub.docker.com/r/jitsi/web)" +msgid "[jitsi/web](https://github.com/jitsi/docker-jitsi-meet/pkgs/container/web)" msgstr "" #: ../../../docs/container-images.md:0 @@ -965,7 +981,7 @@ msgid "[Jitsi](https://jitsi.org/) web UI" msgstr "" #: ../../../docs/container-images.md:0 -msgid "[jitsi/jicofo](https://hub.docker.com/r/jitsi/jicofo)" +msgid "[jitsi/jicofo](https://github.com/jitsi/docker-jitsi-meet/pkgs/container/jicofo)" msgstr "" #: ../../../docs/container-images.md:0 @@ -973,7 +989,7 @@ msgid "[Jitsi](https://jitsi.org/) Focus component" msgstr "" #: ../../../docs/container-images.md:0 -msgid "[jitsi/prosody](https://hub.docker.com/r/jitsi/prosody)" +msgid "[jitsi/prosody](https://github.com/jitsi/docker-jitsi-meet/pkgs/container/prosody)" msgstr "" #: ../../../docs/container-images.md:0 @@ -981,7 +997,7 @@ msgid "[Jitsi](https://jitsi.org/) Prosody XMPP server component" msgstr "" #: ../../../docs/container-images.md:0 -msgid "[jitsi/jvb](https://hub.docker.com/r/jitsi/jvb)" +msgid "[jitsi/jvb](https://github.com/jitsi/docker-jitsi-meet/pkgs/container/jvb)" msgstr "" #: ../../../docs/container-images.md:0 @@ -1052,11 +1068,11 @@ msgstr "" msgid "A native Matrix video conferencing application" msgstr "" -#: ../../../docs/container-images.md:168 +#: ../../../docs/container-images.md:169 msgid "Container images of deprecated / unmaintained services" msgstr "" -#: ../../../docs/container-images.md:170 +#: ../../../docs/container-images.md:171 msgid "The list of the deprecated or unmaintained services is available [here](configuring-playbook.md#deprecated--unmaintained--removed-services)." msgstr "" @@ -1120,6 +1136,14 @@ msgstr "" msgid "Matrix Identity Server" msgstr "" +#: ../../../docs/container-images.md:0 +msgid "[matrix-appservice-slack](configuring-playbook-bridge-appservice-slack.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[matrixdotorg/matrix-appservice-slack](https://hub.docker.com/r/matrixdotorg/matrix-appservice-slack)" +msgstr "" + #: ../../../docs/container-images.md:0 msgid "[matrix-appservice-webhooks](configuring-playbook-bridge-appservice-webhooks.md)" msgstr "" @@ -1144,6 +1168,42 @@ msgstr "" msgid "Accessing ChatGPT via your favourite Matrix client" msgstr "" +#: ../../../docs/container-images.md:0 +msgid "[matrix-ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[activism.international/matrix_ldap_registration_proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy/container_registry)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "Proxy that handles Matrix registration requests and forwards them to LDAP" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[matrix-registration](configuring-playbook-matrix-registration.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[zeratax/matrix-registration](https://hub.docker.com/r/devture/zeratax-matrix-registration/)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "Simple python application to have a token based Matrix registration" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[moanos/matrix-registration-bot](https://hub.docker.com/r/moanos/matrix-registration-bot/)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "Bot for invitations by creating and managing registration tokens" +msgstr "" + #: ../../../docs/container-images.md:0 msgid "[mautrix-facebook](configuring-playbook-bridge-mautrix-facebook.md)" msgstr "" @@ -1223,3 +1283,11 @@ msgstr "" #: ../../../docs/container-images.md:0 msgid "Sliding Sync support for clients which require it (like old Element X versions, before it got switched to Simplified Sliding Sync)" msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "[synapse_auto_accept_invite](configuring-playbook-synapse-auto-accept-invite.md)" +msgstr "" + +#: ../../../docs/container-images.md:0 +msgid "Synapse module to automatically accept invites" +msgstr "" diff --git a/i18n/translation-templates/docs/faq.pot b/i18n/translation-templates/docs/faq.pot index a5b376804..a494bffd5 100644 --- a/i18n/translation-templates/docs/faq.pot +++ b/i18n/translation-templates/docs/faq.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-12 11:50+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -573,254 +573,278 @@ msgid "How do I optimize this setup for a low-power server?" msgstr "" #: ../../../docs/faq.md:308 -msgid "You can disable some not-so-important services to save on memory." +msgid "For a low-power server, it's best to use an alternative homeserver implementation (other than [Synapse](configuring-playbook-synapse.md))." msgstr "" -#: ../../../docs/faq.md:327 -msgid "You can also consider implementing a restriction on room complexity, in order to prevent users from joining very heavy rooms:" +#: ../../../docs/faq.md:310 +msgid "You can disable some not-so-important services to save on memory." msgstr "" -#: ../../../docs/faq.md:337 +#: ../../../docs/faq.md:317 msgid "If you've installed [Jitsi](configuring-playbook-jitsi.md) (not installed by default), there are additional optimizations listed on its documentation page that you can perform." msgstr "" -#: ../../../docs/faq.md:339 +#: ../../../docs/faq.md:320 +msgid "Synapse-specific optimizations" +msgstr "" + +#: ../../../docs/faq.md:322 +msgid "If you're using [Synapse](configuring-playbook-synapse.md), you can also consider the following optimizations:" +msgstr "" + +#: ../../../docs/faq.md:332 +msgid "You can also consider [implementing a restriction on room complexity](configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts), in order to prevent users from joining very heavy rooms:" +msgstr "" + +#: ../../../docs/faq.md:340 msgid "I already have Docker on my server. Can you stop installing Docker via the playbook?" msgstr "" -#: ../../../docs/faq.md:341 +#: ../../../docs/faq.md:342 msgid "Yes, we can stop installing Docker ourselves. Just use this in your `vars.yml` file:" msgstr "" -#: ../../../docs/faq.md:347 +#: ../../../docs/faq.md:348 msgid "I run another webserver on the same server where I wish to install Matrix. What now?" msgstr "" -#: ../../../docs/faq.md:349 +#: ../../../docs/faq.md:350 msgid "By default, we install a webserver for you ([Traefik](https://doc.traefik.io/traefik/)), but you can also use [your own webserver](configuring-playbook-own-webserver.md)." msgstr "" -#: ../../../docs/faq.md:351 +#: ../../../docs/faq.md:352 msgid "How is the effective configuration determined?" msgstr "" -#: ../../../docs/faq.md:353 +#: ../../../docs/faq.md:354 msgid "Configuration variables are defined in multiple places in this playbook and are considered in this order:" msgstr "" -#: ../../../docs/faq.md:355 +#: ../../../docs/faq.md:356 msgid "there are defaults coming from each role's defaults file (`role/matrix*/defaults/main.yml`). These variable values aim to be good defaults for when the role is used standalone (outside of this collection of roles, also called playbook)." msgstr "" -#: ../../../docs/faq.md:357 +#: ../../../docs/faq.md:358 msgid "then, there are overrides in `group_vars/matrix_servers`, which aim to adjust these \"standalone role defaults\" to something which better fits the playbook in its entirety." msgstr "" -#: ../../../docs/faq.md:359 +#: ../../../docs/faq.md:360 msgid "finally, there's your `inventory/host_vars/matrix.example.com/vars.yml` file, which is the ultimate override" msgstr "" -#: ../../../docs/faq.md:361 +#: ../../../docs/faq.md:362 msgid "What configuration variables are available?" msgstr "" -#: ../../../docs/faq.md:363 +#: ../../../docs/faq.md:364 msgid "You can discover the variables you can override in each role (`roles/*/*/defaults/main.yml`)." msgstr "" -#: ../../../docs/faq.md:365 +#: ../../../docs/faq.md:366 msgid "As described in [How is the effective configuration determined?](#how-is-the-effective-configuration-determined), these role-defaults may be overridden by values defined in `group_vars/matrix_servers`." msgstr "" -#: ../../../docs/faq.md:367 +#: ../../../docs/faq.md:368 msgid "Refer to both of these for inspiration. Still, as mentioned in [Configuring the playbook](configuring-playbook.md), you're only ever supposed to edit your own `inventory/host_vars/matrix.example.com/vars.yml` file and nothing else inside the playbook (unless you're meaning to contribute new features)." msgstr "" -#: ../../../docs/faq.md:369 -#: ../../../docs/faq.md:381 +#: ../../../docs/faq.md:370 +#: ../../../docs/faq.md:382 msgid "**Note**: some of the roles (`roles/galaxy/*`) live in separate repositories and are only installed after your run `just roles` (or `make roles`) or `just update` (which automatically does `git pull` and `just roles`)." msgstr "" -#: ../../../docs/faq.md:371 +#: ../../../docs/faq.md:372 msgid "I'd like to adjust some configuration which doesn't have a corresponding variable. How do I do it?" msgstr "" -#: ../../../docs/faq.md:373 +#: ../../../docs/faq.md:374 msgid "The playbook doesn't aim to expose all configuration settings for all services using variables. Doing so would amount to hundreds of variables that we have to create and maintain." msgstr "" -#: ../../../docs/faq.md:375 +#: ../../../docs/faq.md:376 msgid "Instead, we only try to make some important basics configurable using dedicated variables you can see in each role. See [What configuration variables are available?](#what-configuration-variables-are-available)." msgstr "" -#: ../../../docs/faq.md:377 +#: ../../../docs/faq.md:378 msgid "Besides that, each role (component) aims to provide a `matrix_SOME_COMPONENT_configuration_extension_yaml` (or `matrix_SOME_COMPONENT_configuration_extension_json`) variable, which can be used to override the configuration." msgstr "" -#: ../../../docs/faq.md:379 +#: ../../../docs/faq.md:380 msgid "Check each role's `roles/*/*/defaults/main.yml` for the corresponding variable and an example for how use it." msgstr "" -#: ../../../docs/faq.md:383 +#: ../../../docs/faq.md:384 msgid "Installation" msgstr "" -#: ../../../docs/faq.md:385 +#: ../../../docs/faq.md:386 msgid "How do I run the installation?" msgstr "" -#: ../../../docs/faq.md:387 +#: ../../../docs/faq.md:388 msgid "See [Installing](installing.md) to learn how to use Ansible to install Matrix services." msgstr "" -#: ../../../docs/faq.md:389 +#: ../../../docs/faq.md:390 msgid "However, we recommend you to follow our installation guide, instead of jumping straight to installing." msgstr "" -#: ../../../docs/faq.md:391 +#: ../../../docs/faq.md:392 msgid "There are two guides available:" msgstr "" -#: ../../../docs/faq.md:393 +#: ../../../docs/faq.md:394 msgid "⚡ **[Quick start](quick-start.md)** (for beginners): this is recommended for those who do not have an existing Matrix server and want to start quickly with \"opinionated defaults\"." msgstr "" -#: ../../../docs/faq.md:395 +#: ../../../docs/faq.md:396 msgid "**Full installation guide (for advanced users)**: if you need to import an existing Matrix server's data into the new server or want to learn more while setting up the server, follow this guide by starting with the **[Prerequisites](prerequisites.md)** documentation page." msgstr "" -#: ../../../docs/faq.md:397 +#: ../../../docs/faq.md:398 msgid "I installed Synapse some other way. Can I migrate such a setup to the playbook?" msgstr "" -#: ../../../docs/faq.md:399 +#: ../../../docs/faq.md:400 msgid "Yes, you can." msgstr "" -#: ../../../docs/faq.md:401 +#: ../../../docs/faq.md:402 msgid "You generally need to do a playbook installation. It's recommended to follow the full installation guide (starting at the [Prerequisites](prerequisites.md) page), not the [Quick start](quick-start.md) guide. The full installation guide will tell you when it's time to import your existing data into the newly-prepared server." msgstr "" -#: ../../../docs/faq.md:403 +#: ../../../docs/faq.md:404 msgid "This Ansible playbook guides you into installing a server for `example.com` (user IDs are like this: `@alice:example.com`), while the server is at `matrix.example.com`. If your existing setup has a server name (`server_name` configuration setting in Synapse's `homeserver.yaml` file) other than the base `example.com`, you may need to tweak some additional variables. This FAQ entry may be of use if you're dealing with a more complicated setup — [How do I install on matrix.example.com without involving the base domain?](#how-do-i-install-on-matrixexamplecom-without-involving-the-base-domain)" msgstr "" -#: ../../../docs/faq.md:405 +#: ../../../docs/faq.md:406 msgid "After configuring the playbook and installing and **before starting** services (done with `ansible-playbook … --tags=start`) you'd import [your SQLite](importing-synapse-sqlite.md) (or [Postgres](importing-postgres.md)) database and also [import your media store](importing-synapse-media-store.md)." msgstr "" -#: ../../../docs/faq.md:407 +#: ../../../docs/faq.md:408 msgid "I've downloaded Ansible and the playbook on the server. It can't connect using SSH." msgstr "" -#: ../../../docs/faq.md:409 +#: ../../../docs/faq.md:410 msgid "If you're using the playbook directly on the server, then Ansible doesn't need to connect using SSH." msgstr "" -#: ../../../docs/faq.md:411 +#: ../../../docs/faq.md:412 msgid "It can perform a local connection instead. Just set `ansible_connection=local` at the end of the server line in `inventory/hosts` and re-run the playbook." msgstr "" -#: ../../../docs/faq.md:413 +#: ../../../docs/faq.md:414 msgid "If you're running Ansible from within a container (one of the possibilities we list on our [dedicated Ansible documentation page](ansible.md)), then using `ansible_connection=local` is not possible." msgstr "" -#: ../../../docs/faq.md:415 +#: ../../../docs/faq.md:416 msgid "Maintenance and Troubleshooting" msgstr "" -#: ../../../docs/faq.md:417 +#: ../../../docs/faq.md:418 msgid "💡 Also see this page for generic information about maintaining the services and troubleshooting: [Maintenance and Troubleshooting](maintenance-and-troubleshooting.md)" msgstr "" -#: ../../../docs/faq.md:419 +#: ../../../docs/faq.md:420 msgid "Do I need to do anything to keep my Matrix server updated?" msgstr "" -#: ../../../docs/faq.md:421 +#: ../../../docs/faq.md:422 msgid "Yes. We don't update anything for you automatically." msgstr "" -#: ../../../docs/faq.md:423 +#: ../../../docs/faq.md:424 msgid "See our [documentation page about upgrading services](maintenance-upgrading-services.md)." msgstr "" -#: ../../../docs/faq.md:425 +#: ../../../docs/faq.md:426 msgid "How do I move my existing installation to another (VM) server?" msgstr "" -#: ../../../docs/faq.md:427 +#: ../../../docs/faq.md:428 msgid "If you have an existing installation done using this Ansible playbook, you can easily migrate that to another server following [our dedicated server migration guide](maintenance-migrating.md)." msgstr "" -#: ../../../docs/faq.md:429 +#: ../../../docs/faq.md:430 msgid "If your previous installation is done in some other way (not using this Ansible playbook), see [I installed Synapse some other way. Can I migrate such a setup to the playbook?](#i-installed-synapse-some-other-way-can-i-migrate-such-a-setup-to-the-playbook)." msgstr "" -#: ../../../docs/faq.md:431 +#: ../../../docs/faq.md:432 msgid "What is this `/matrix/postgres/data-auto-upgrade-backup` directory that is taking up so much space?" msgstr "" -#: ../../../docs/faq.md:433 +#: ../../../docs/faq.md:434 msgid "When you [perform a major Postgres upgrade](maintenance-postgres.md#upgrading-postgresql), we save the the old data files in `/matrix/postgres/data-auto-upgrade-backup`, just so you could easily restore them should something have gone wrong." msgstr "" -#: ../../../docs/faq.md:435 +#: ../../../docs/faq.md:436 msgid "After verifying that everything still works after the Postgres upgrade, you can safely delete `/matrix/postgres/data-auto-upgrade-backup`" msgstr "" -#: ../../../docs/faq.md:437 +#: ../../../docs/faq.md:438 msgid "I get \"Error response from daemon: configured logging driver does not support reading\" when I run `docker logs matrix-synapse`. Why?" msgstr "" -#: ../../../docs/faq.md:439 +#: ../../../docs/faq.md:440 msgid "To prevent double-logging, Docker logging is disabled by explicitly passing `--log-driver=none` to all containers. Due to this, you cannot view logs using `docker logs matrix-*`." msgstr "" -#: ../../../docs/faq.md:441 +#: ../../../docs/faq.md:442 msgid "See [this section](maintenance-and-troubleshooting.md#how-to-see-the-logs) on the page for maintenance and troubleshooting for more details to see the logs." msgstr "" -#: ../../../docs/faq.md:443 +#: ../../../docs/faq.md:444 msgid "The server fails to start due to the `Unable to start service matrix-coturn.service` error. Why and how to solve it?" msgstr "" -#: ../../../docs/faq.md:445 +#: ../../../docs/faq.md:446 msgid "The error is most likely because Traefik cannot obtain SSL certificates due to certain reasons such as wrong domain name configuration or port 80 being unavailable due to other services." msgstr "" -#: ../../../docs/faq.md:447 +#: ../../../docs/faq.md:448 msgid "If Traefik fails to obtain an SSL certificate for domain names such as `matrix.`, Traefik Certs Dumper cannot extract the SSL certificate out of there, and coturn cannot be started and the error occurs. Refer to these comments for details:" msgstr "" -#: ../../../docs/faq.md:449 +#: ../../../docs/faq.md:450 msgid "" msgstr "" -#: ../../../docs/faq.md:450 +#: ../../../docs/faq.md:451 msgid "" msgstr "" -#: ../../../docs/faq.md:452 +#: ../../../docs/faq.md:453 msgid "If you are not sure what the problem is, at first make sure that you have set the \"base domain\" (`example.com`, **not `matrix.example.com`**) to `matrix_domain`. You should be able to find it at the top of your `vars.yml`." msgstr "" -#: ../../../docs/faq.md:454 +#: ../../../docs/faq.md:455 msgid "If it is correctly specified, look Traefik's logs (`journalctl -fu matrix-traefik.service`) for errors by Let's Encrypt for troubleshooting." msgstr "" -#: ../../../docs/faq.md:456 +#: ../../../docs/faq.md:457 msgid "Miscellaneous" msgstr "" -#: ../../../docs/faq.md:458 +#: ../../../docs/faq.md:459 +msgid "The role to manage the service which I deploy has been removed from the playbook. Does this mean that the service can no longer be used on my server?" +msgstr "" + +#: ../../../docs/faq.md:461 +msgid "Not necessarily. Removing the role from the playbook does not always mean that the service has been deprecated by the upstream developers, so as long as the resource such as the Docker image is available, you should be able to keep running it by reverting the specific commit which has removed the role. This essentially means that you will need to maintain your own version of the playbook." +msgstr "" + +#: ../../../docs/faq.md:463 +msgid "Please keep in mind that you will occasionally need to fix code conflicts if any." +msgstr "" + +#: ../../../docs/faq.md:465 msgid "I would like to see this favorite service of mine integrated and become available on my Matrix server. How can I request it?" msgstr "" -#: ../../../docs/faq.md:460 +#: ../../../docs/faq.md:467 msgid "You can freely create an issue for feature request on the repository at GitHub [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/new/choose). Note this is a community project with no financial backing, and there is not assurance that your request would be eventually picked up by others and the requested feature would become available. The easiest way to get a feature into this project is to just develop it yourself." msgstr "" -#: ../../../docs/faq.md:462 +#: ../../../docs/faq.md:469 msgid "Also, please note that this playbook intends to focus solely on Matrix and Matrix-related services. If your request is not specific to Matrix, you may as well to consider to submit it to the [mash-playbook](https://github.com/mother-of-all-self-hosting/mash-playbook), maintained by the members behind this matrix-docker-ansible-deploy project. [This document on the interoperability](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/interoperability.md) describes how to deploy services along with the Matrix services easily." msgstr "" diff --git a/i18n/translation-templates/docs/howto-server-delegation.pot b/i18n/translation-templates/docs/howto-server-delegation.pot index cf3d1f5c8..96c33435f 100644 --- a/i18n/translation-templates/docs/howto-server-delegation.pot +++ b/i18n/translation-templates/docs/howto-server-delegation.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-06-29 17:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -45,7 +45,7 @@ msgid "For simplicity reasons, this playbook recommends you to set up server del msgstr "" #: ../../../docs/howto-server-delegation.md:26 -msgid "**Note**: as an alternative, it is possible to install the server such that it uses only the `matrix.example.com` domain (instead of identifying as the shorter base domain — `example.com`). This should be helpful if you are not in control of anything on the base domain (`example.com`). In this case, you would not need to configure server delegation, but you would need to add other configuration. For more information, see [How do I install on matrix.example.com without involving the base domain?](faq.md#how-do-i-install-on-matrix-example-com-without-involving-the-base-domain) on our FAQ." +msgid "**Note**: as an alternative, it is possible to install the server such that it uses only the `matrix.example.com` domain (instead of identifying as the shorter base domain — `example.com`). This should be helpful if you are not in control of anything on the base domain (`example.com`). In this case, you would not need to configure server delegation, but you would need to add other configuration. For more information, see [How do I install on matrix.example.com without involving the base domain?](faq.md#how-do-i-install-on-matrixexamplecom-without-involving-the-base-domain) on our FAQ." msgstr "" #: ../../../docs/howto-server-delegation.md:28 diff --git a/i18n/translation-templates/docs/howto-srv-server-delegation.pot b/i18n/translation-templates/docs/howto-srv-server-delegation.pot index 8c5fd36fa..f676f19ca 100644 --- a/i18n/translation-templates/docs/howto-srv-server-delegation.pot +++ b/i18n/translation-templates/docs/howto-srv-server-delegation.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-07 11:16+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -57,7 +57,7 @@ msgid "**Note**: the changes below instruct you how to do this for a basic Synap msgstr "" #: ../../../docs/howto-srv-server-delegation.md:29 -msgid "if you're using another homeserver implementation (e.g. [Conduit](./configuring-playbook-conduit.md), [continuwuity](./configuring-playbook-continuwuity.md) or [Dendrite](./configuring-playbook-dendrite.md))" +msgid "if you're using another homeserver implementation (e.g. [Conduit](./configuring-playbook-conduit.md), [continuwuity](./configuring-playbook-continuwuity.md), [Tuwunel](./configuring-playbook-tuwunel.md) or [Dendrite](./configuring-playbook-dendrite.md))" msgstr "" #: ../../../docs/howto-srv-server-delegation.md:30 diff --git a/i18n/translation-templates/docs/importing-postgres.pot b/i18n/translation-templates/docs/importing-postgres.pot index 193b66d34..cb130c3ff 100644 --- a/i18n/translation-templates/docs/importing-postgres.pot +++ b/i18n/translation-templates/docs/importing-postgres.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -25,7 +25,7 @@ msgid "You can manually import your database from a previous default installatio msgstr "" #: ../../../docs/importing-postgres.md:14 -#: ../../../docs/importing-postgres.md:38 +#: ../../../docs/importing-postgres.md:43 msgid "**Notes**:" msgstr "" @@ -57,98 +57,106 @@ msgstr "" msgid "Before doing the actual import, **you need to upload your Postgres dump file to the server** (any path is okay)." msgstr "" -#: ../../../docs/importing-postgres.md:28 +#: ../../../docs/importing-postgres.md:29 +msgid "Do not import into a database that already contains tables (e.g. one that a service has already initialized and used). As the [official Synapse backup guide](https://element-hq.github.io/synapse/latest/usage/administration/backups.html) puts it: at best this will error, at worst it will lead to subtle database inconsistencies. Import into an empty (freshly created) database instead." +msgstr "" + +#: ../../../docs/importing-postgres.md:31 +msgid "**Note for Synapse users restoring an older backup**: if the server kept running (and users kept chatting) after the backup you are restoring was made, truncate the `e2e_one_time_keys_json` table after importing and before starting Synapse. Restoring an older backup can otherwise cause already-used one-time keys to be re-issued, leading to message decryption errors for your users. You can do this by [getting a database terminal](maintenance-postgres.md#getting-a-database-terminal), connecting to the Synapse database (`\\c synapse`) and running `TRUNCATE e2e_one_time_keys_json;`. Clients will generate and upload fresh one-time keys automatically." +msgstr "" + +#: ../../../docs/importing-postgres.md:33 msgid "Importing" msgstr "" -#: ../../../docs/importing-postgres.md:30 +#: ../../../docs/importing-postgres.md:35 msgid "To import, run this command (make sure to replace `SERVER_PATH_TO_POSTGRES_DUMP_FILE` with a file path on your server):" msgstr "" -#: ../../../docs/importing-postgres.md:40 +#: ../../../docs/importing-postgres.md:45 msgid "`SERVER_PATH_TO_POSTGRES_DUMP_FILE` must be a file path to a Postgres dump file on the server (not on your local machine!)" msgstr "" -#: ../../../docs/importing-postgres.md:41 +#: ../../../docs/importing-postgres.md:46 msgid "`postgres_default_import_database` defaults to `matrix`, which is useful for importing multiple databases (for dumps made with `pg_dumpall`). If you're importing a single database (e.g. `synapse`), consider changing `postgres_default_import_database` accordingly" msgstr "" -#: ../../../docs/importing-postgres.md:42 +#: ../../../docs/importing-postgres.md:47 msgid "after importing a large database, it's a good idea to run [an `ANALYZE` operation](https://www.postgresql.org/docs/current/sql-analyze.html) to make Postgres rebuild its database statistics and optimize its query planner. You can easily do this via the playbook by running `just run-tags run-postgres-vacuum -e postgres_vacuum_preset=analyze` (see [Vacuuming PostgreSQL](maintenance-postgres.md#vacuuming-postgresql) for more details)." msgstr "" -#: ../../../docs/importing-postgres.md:44 +#: ../../../docs/importing-postgres.md:49 msgid "Troubleshooting" msgstr "" -#: ../../../docs/importing-postgres.md:46 +#: ../../../docs/importing-postgres.md:51 msgid "Table Ownership" msgstr "" -#: ../../../docs/importing-postgres.md:48 +#: ../../../docs/importing-postgres.md:53 msgid "A table ownership issue can occur if you are importing from a Synapse installation which was both:" msgstr "" -#: ../../../docs/importing-postgres.md:50 +#: ../../../docs/importing-postgres.md:55 msgid "migrated from SQLite to Postgres, and" msgstr "" -#: ../../../docs/importing-postgres.md:51 +#: ../../../docs/importing-postgres.md:56 msgid "used a username other than 'synapse'" msgstr "" -#: ../../../docs/importing-postgres.md:53 +#: ../../../docs/importing-postgres.md:58 msgid "In this case you may run into the following error during the import task:" msgstr "" -#: ../../../docs/importing-postgres.md:59 +#: ../../../docs/importing-postgres.md:64 msgid "where `synapse_user` is the database username from the previous Synapse installation." msgstr "" -#: ../../../docs/importing-postgres.md:61 +#: ../../../docs/importing-postgres.md:66 msgid "This can be verified by examining the dump for ALTER TABLE statements which set OWNER TO that username:" msgstr "" -#: ../../../docs/importing-postgres.md:73 +#: ../../../docs/importing-postgres.md:78 msgid "It can be worked around by changing the username to `synapse`, for example by using `sed`:" msgstr "" -#: ../../../docs/importing-postgres.md:79 +#: ../../../docs/importing-postgres.md:84 msgid "This uses sed to perform an 'in-place' (`-i`) replacement globally (`/g`), searching for `synapse_user` and replacing with `synapse` (`s/synapse_user/synapse`). If your database username was different, change `synapse_user` to that username instead. Expand search/replace statement as shown in example above, in case of old user name like `matrix` — replacing `matrix` only would… well — you can imagine." msgstr "" -#: ../../../docs/importing-postgres.md:81 +#: ../../../docs/importing-postgres.md:86 msgid "Note that if the previous import failed with an error it may have made changes which are incompatible with re-running the import task right away; if you do so it may fail with an error such as:" msgstr "" -#: ../../../docs/importing-postgres.md:87 +#: ../../../docs/importing-postgres.md:92 msgid "Repeat import" msgstr "" -#: ../../../docs/importing-postgres.md:89 +#: ../../../docs/importing-postgres.md:94 msgid "In this case you can use the command suggested in the import task to clear the database before retrying the import:" msgstr "" -#: ../../../docs/importing-postgres.md:97 +#: ../../../docs/importing-postgres.md:102 msgid "Now on your local machine run `just run-tags setup-postgres` to prepare the database roles etc." msgstr "" -#: ../../../docs/importing-postgres.md:99 +#: ../../../docs/importing-postgres.md:104 msgid "If not, you probably get this error. `synapse` is the correct table owner, but the role is missing in database." msgstr "" -#: ../../../docs/importing-postgres.md:105 +#: ../../../docs/importing-postgres.md:110 msgid "Once the database is clear and the ownership of the tables has been fixed in the SQL file, the import task should succeed." msgstr "" -#: ../../../docs/importing-postgres.md:107 +#: ../../../docs/importing-postgres.md:112 msgid "Check, if `--dbname` is set to `synapse` (not `matrix`) and replace paths (or even better, copy this line from your terminal)" msgstr "" -#: ../../../docs/importing-postgres.md:113 +#: ../../../docs/importing-postgres.md:118 msgid "Hints" msgstr "" -#: ../../../docs/importing-postgres.md:115 +#: ../../../docs/importing-postgres.md:120 msgid "To open psql terminal run `/matrix/postgres/bin/cli`" msgstr "" diff --git a/i18n/translation-templates/docs/importing-synapse-media-store.pot b/i18n/translation-templates/docs/importing-synapse-media-store.pot index 08f0e8809..27f8e1054 100644 --- a/i18n/translation-templates/docs/importing-synapse-media-store.pot +++ b/i18n/translation-templates/docs/importing-synapse-media-store.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -33,25 +33,29 @@ msgid "Before doing the actual data restore, **you need to upload your media sto msgstr "" #: ../../../docs/importing-synapse-media-store.md:16 -msgid "If you are [storing Matrix media files on Amazon S3](configuring-playbook-s3.md) (optional), restoring with this tool is not possible right now." +msgid "You also need the [rsync](https://rsync.samba.org/) utility installed **on the server**, as the import performs a server-side `rsync` synchronization. The playbook does not install it for you. On most distributions, it is available as a package called `rsync`." msgstr "" #: ../../../docs/importing-synapse-media-store.md:18 -msgid "As an alternative, you can perform a manual restore using the [AWS CLI tool](https://aws.amazon.com/cli/) (e.g. `aws s3 sync /path/to/server/media_store/. s3://name-of-bucket/`)" +msgid "If you are [storing Matrix media files on Amazon S3](configuring-playbook-s3.md) (optional), restoring with this tool is not possible right now." msgstr "" #: ../../../docs/importing-synapse-media-store.md:20 -msgid "**Note for Mac users**: Due to case-sensitivity issues on certain Mac filesystems (HFS or HFS+), filename corruption may occur if you copy a `media_store` directory to your Mac. If you're transferring a `media_store` directory between 2 servers, make sure you do it directly (from server to server with a tool such as [rsync](https://rsync.samba.org/)), and not by downloading the files to your Mac." +msgid "As an alternative, you can perform a manual restore using the [AWS CLI tool](https://aws.amazon.com/cli/) (e.g. `aws s3 sync /path/to/server/media_store/. s3://name-of-bucket/`)" msgstr "" #: ../../../docs/importing-synapse-media-store.md:22 -msgid "Importing" +msgid "**Note for Mac users**: Due to case-sensitivity issues on certain Mac filesystems (HFS or HFS+), filename corruption may occur if you copy a `media_store` directory to your Mac. If you're transferring a `media_store` directory between 2 servers, make sure you do it directly (from server to server with a tool such as [rsync](https://rsync.samba.org/)), and not by downloading the files to your Mac." msgstr "" #: ../../../docs/importing-synapse-media-store.md:24 +msgid "Importing" +msgstr "" + +#: ../../../docs/importing-synapse-media-store.md:26 msgid "Run this command (make sure to replace `` with a path on your server):" msgstr "" -#: ../../../docs/importing-synapse-media-store.md:30 +#: ../../../docs/importing-synapse-media-store.md:32 msgid "**Note**: `` must be a file path to a `media_store` directory on the server (not on your local machine!)." msgstr "" diff --git a/i18n/translation-templates/docs/installing.pot b/i18n/translation-templates/docs/installing.pot index a13419bd2..bf9b35f4a 100644 --- a/i18n/translation-templates/docs/installing.pot +++ b/i18n/translation-templates/docs/installing.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-12 15:37+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -49,7 +49,7 @@ msgid "or: a combination of `git pull` and `just roles` (or `make roles` if you msgstr "" #: ../../../docs/installing.md:30 -msgid "If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly: `rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force`" +msgid "If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly after updating the playbook: `git pull; rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force`" msgstr "" #: ../../../docs/installing.md:32 @@ -77,233 +77,249 @@ msgid "If you **do** use SSH keys for authentication, **and** use a non-root use msgstr "" #: ../../../docs/installing.md:44 -msgid "There 2 ways to start the installation process — depending on whether you're [Installing a brand new server (without importing data)](#installing-a-brand-new-server-without-importing-data) or [Installing a server into which you'll import old data](#installing-a-server-into-which-youll-import-old-data)." +msgid "Instead of typing the sudo password on each run (`-K`) or storing it in plain text in the inventory hosts file, you can also pull it from the [pass](https://www.passwordstore.org/) password manager by adding `ansible_become_password='{{ lookup(\"community.general.passwordstore\", \"path/to/password\") }}'` to your host line. See the [passwordstore lookup documentation](https://docs.ansible.com/ansible/latest/collections/community/general/passwordstore_lookup.html) for more details." msgstr "" #: ../../../docs/installing.md:46 -msgid "**Note**: if you are migrating from an old server to a new one, take a look at [this guide](maintenance-migrating.md) instead. This is an easier and more straightforward way than installing a server and importing old data into it." +msgid "There 2 ways to start the installation process — depending on whether you're [Installing a brand new server (without importing data)](#installing-a-brand-new-server-without-importing-data) or [Installing a server into which you'll import old data](#installing-a-server-into-which-youll-import-old-data)." msgstr "" #: ../../../docs/installing.md:48 -msgid "Installing a brand new server (without importing data)" +msgid "**Note**: if you are migrating from an old server to a new one, take a look at [this guide](maintenance-migrating.md) instead. This is an easier and more straightforward way than installing a server and importing old data into it." msgstr "" #: ../../../docs/installing.md:50 +msgid "Installing a brand new server (without importing data)" +msgstr "" + +#: ../../../docs/installing.md:52 msgid "If this is **a brand new** Matrix server and you **won't be importing old data into it**, run all these tags:" msgstr "" -#: ../../../docs/installing.md:56 +#: ../../../docs/installing.md:58 msgid "This will do a full installation and start all Matrix services." msgstr "" -#: ../../../docs/installing.md:58 +#: ../../../docs/installing.md:60 msgid "**Note**: if the command does not work as expected, make sure that you have properly installed and configured software required to run the playbook, as described on [Prerequisites](prerequisites.md)." msgstr "" -#: ../../../docs/installing.md:60 +#: ../../../docs/installing.md:62 msgid "Installing a server into which you'll import old data" msgstr "" -#: ../../../docs/installing.md:62 +#: ../../../docs/installing.md:64 msgid "If you will be importing data into your newly created Matrix server, install it, but **do not** start its services just yet. Starting its services or messing with its database now will affect your data import later on." msgstr "" -#: ../../../docs/installing.md:64 +#: ../../../docs/installing.md:66 msgid "To do the installation **without** starting services, run `ansible-playbook` with the `install-all` tag only:" msgstr "" -#: ../../../docs/installing.md:70 -msgid "[!WARNING] Do not run the just \"recipe\" `just install-all` instead, because it automatically starts services at the end of execution. See: [Difference between playbook tags and shortcuts](just.md#difference-between-playbook-tags-and-shortcuts)" +#: ../../../docs/installing.md:73 +msgid "Do not run the just \"recipe\" `just install-all` instead, because it automatically starts services at the end of execution. See: [Difference between playbook tags and shortcuts](just.md#difference-between-playbook-tags-and-shortcuts)" msgstr "" -#: ../../../docs/installing.md:73 +#: ../../../docs/installing.md:75 msgid "When this command completes, services won't be running yet." msgstr "" -#: ../../../docs/installing.md:75 +#: ../../../docs/installing.md:77 msgid "You can now:" msgstr "" -#: ../../../docs/installing.md:77 +#: ../../../docs/installing.md:79 msgid "[Importing an existing SQLite database (from another Synapse installation)](importing-synapse-sqlite.md) (optional)" msgstr "" -#: ../../../docs/installing.md:79 +#: ../../../docs/installing.md:81 msgid "[Importing an existing Postgres database (from another installation)](importing-postgres.md) (optional)" msgstr "" -#: ../../../docs/installing.md:81 +#: ../../../docs/installing.md:83 msgid "[Importing `media_store` data files from an existing Synapse installation](importing-synapse-media-store.md) (optional)" msgstr "" -#: ../../../docs/installing.md:83 +#: ../../../docs/installing.md:85 msgid "… and then proceed to starting all services:" msgstr "" -#: ../../../docs/installing.md:89 +#: ../../../docs/installing.md:91 msgid "Create your user account" msgstr "" -#: ../../../docs/installing.md:91 +#: ../../../docs/installing.md:93 msgid "ℹ️ *You can skip this step if you have installed a server and imported old data to it.*" msgstr "" -#: ../../../docs/installing.md:93 +#: ../../../docs/installing.md:95 msgid "As you have configured your brand new server and the client, you need to **create your user account** on your Matrix server." msgstr "" -#: ../../../docs/installing.md:95 +#: ../../../docs/installing.md:97 msgid "After creating the user account, you can log in to it with [Element Web](configuring-playbook-client-element-web.md) that this playbook has installed for you at this URL: `https://element.example.com/`." msgstr "" -#: ../../../docs/installing.md:97 +#: ../../../docs/installing.md:99 msgid "To create your user account (as an administrator of the server) via this Ansible playbook, run the command below on your local computer." msgstr "" -#: ../../../docs/installing.md:99 +#: ../../../docs/installing.md:101 msgid "**Notes**:" msgstr "" -#: ../../../docs/installing.md:100 +#: ../../../docs/installing.md:102 msgid "Make sure to adjust `YOUR_USERNAME_HERE` and `YOUR_PASSWORD_HERE`" msgstr "" -#: ../../../docs/installing.md:101 +#: ../../../docs/installing.md:103 msgid "For `YOUR_USERNAME_HERE`, use a plain username like `alice`, not your full ID (`@alice:example.com`)" msgstr "" -#: ../../../docs/installing.md:102 +#: ../../../docs/installing.md:104 msgid "Use `admin=yes` to make your user account an administrator of the Matrix server" msgstr "" -#: ../../../docs/installing.md:110 +#: ../../../docs/installing.md:112 msgid "Feel free to create as many accounts (for friends, family, etc.) as you want. Still, perhaps you should grant full administrative access to your account only (with `admin=yes`), and others should be created with `admin=no`." msgstr "" -#: ../../../docs/installing.md:112 +#: ../../../docs/installing.md:114 msgid "For more information, see the documentation for [registering users](registering-users.md)." msgstr "" -#: ../../../docs/installing.md:114 +#: ../../../docs/installing.md:116 msgid "Finalize the installation" msgstr "" -#: ../../../docs/installing.md:116 +#: ../../../docs/installing.md:118 msgid "Now you've configured Matrix services and your user account, you need to **finalize the installation process** by [setting up Matrix delegation (redirection)](howto-server-delegation.md), so that your Matrix server (`matrix.example.com`) can present itself as the base domain (`example.com`) in the Matrix network." msgstr "" -#: ../../../docs/installing.md:118 +#: ../../../docs/installing.md:120 msgid "This is required for federation to work! Without a proper configuration, your server will effectively not be part of the Matrix network." msgstr "" -#: ../../../docs/installing.md:120 +#: ../../../docs/installing.md:122 msgid "To configure the delegation, you have these two options. Choose one of them according to your situation." msgstr "" -#: ../../../docs/installing.md:122 +#: ../../../docs/installing.md:124 msgid "If you can afford to point the base domain at the Matrix server, follow the instructions below which guide you into [serving the base domain](configuring-playbook-base-domain-serving.md) from the integrated web server. It will enable you to use a Matrix user ID like `@alice:example.com` while hosting services on a subdomain like `matrix.example.com`." msgstr "" -#: ../../../docs/installing.md:123 +#: ../../../docs/installing.md:125 msgid "Alternatively, if you're using the base domain for other purposes and cannot point it to the Matrix server (and thus cannot \"serve the base domain\" from it), you most likely need to [manually install well-known files on the base domain's server](configuring-well-known.md#manually-installing-well-known-files-on-the-base-domains-server), but feel free to familiarize yourself with all [server delegation (redirection) options](howto-server-delegation.md)." msgstr "" -#: ../../../docs/installing.md:125 +#: ../../../docs/installing.md:127 msgid "To have the base domain served from the integrated web server, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/installing.md:131 +#: ../../../docs/installing.md:133 msgid "After configuring the playbook, run the command below:" msgstr "" -#: ../../../docs/installing.md:137 +#: ../../../docs/installing.md:139 msgid "**If an error is not returned, the installation has completed and the services have been started successfully**🎉" msgstr "" -#: ../../../docs/installing.md:139 +#: ../../../docs/installing.md:141 msgid "Things to do next" msgstr "" -#: ../../../docs/installing.md:141 +#: ../../../docs/installing.md:143 msgid "After completing the installation, you can:" msgstr "" -#: ../../../docs/installing.md:143 +#: ../../../docs/installing.md:145 msgid "[check if services work](maintenance-and-troubleshooting.md#how-to-check-if-services-work)" msgstr "" -#: ../../../docs/installing.md:144 +#: ../../../docs/installing.md:146 msgid "or [set up additional services](configuring-playbook.md#other-configuration-options) (bridges to other chat networks, bots, etc.)" msgstr "" -#: ../../../docs/installing.md:145 +#: ../../../docs/installing.md:147 msgid "or learn how to [upgrade services when new versions are released](maintenance-upgrading-services.md)" msgstr "" -#: ../../../docs/installing.md:146 +#: ../../../docs/installing.md:148 msgid "or learn how to [maintain your server](faq.md#maintenance)" msgstr "" -#: ../../../docs/installing.md:147 +#: ../../../docs/installing.md:149 msgid "or join some Matrix rooms:" msgstr "" -#: ../../../docs/installing.md:148 -msgid "via the *Explore rooms* feature in Element Web or some other clients, or by discovering them using this [matrix-static list](https://view.matrix.org). **Note**: joining large rooms may overload small servers." +#: ../../../docs/installing.md:150 +msgid "via the *Explore rooms* feature in Element Web or some other clients, or by discovering them using this [matrix-static list](https://view.matrix.org). **Note**: joining large rooms may overload small servers. For tuning guidance on constrained hosts, see [Limit joining heavy rooms on constrained hosts](configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts)." msgstr "" -#: ../../../docs/installing.md:149 +#: ../../../docs/installing.md:152 msgid "or come say Hi in our support room — [#matrix-docker-ansible-deploy:devture.com](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com). You might learn something or get to help someone else new to Matrix hosting." msgstr "" -#: ../../../docs/installing.md:150 +#: ../../../docs/installing.md:153 msgid "or help make this playbook better by contributing (code, documentation, or [coffee/beer](https://liberapay.com/s.pantaleev/donate))" msgstr "" -#: ../../../docs/installing.md:152 +#: ../../../docs/installing.md:155 +msgid "Installing native Matrix clients on your computer" +msgstr "" + +#: ../../../docs/installing.md:157 +msgid "As the playbook's aim is to help you to install and manage Matrix services on your server, if you are looking for dedicated native Matrix clients which run on your computer, you need to install ones by yourself. There is a convenient list which introduces known Matrix clients on this page: " +msgstr "" + +#: ../../../docs/installing.md:159 +msgid "If you feel overwhelmed by the variety and the number of the available clients, you might want to install [**Komai**](https://github.com/etkecc/komai), a desktop-first Matrix chat application maintained by the team behind the playbook. It is stable, and just works without quirks!" +msgstr "" + +#: ../../../docs/installing.md:161 msgid "⚠️ Keep the playbook and services up-to-date" msgstr "" -#: ../../../docs/installing.md:154 +#: ../../../docs/installing.md:163 msgid "While this playbook helps you to set up Matrix services and maintain them, it will **not** automatically run the maintenance task for you. You will need to update the playbook and re-run it **manually**." msgstr "" -#: ../../../docs/installing.md:156 +#: ../../../docs/installing.md:165 msgid "The upstream projects, which this playbook makes use of, occasionally if not often suffer from security vulnerabilities." msgstr "" -#: ../../../docs/installing.md:158 +#: ../../../docs/installing.md:167 msgid "Since it is unsafe to keep outdated services running on the server connected to the internet, please consider to update the playbook and re-run it periodically, in order to keep the services up-to-date." msgstr "" -#: ../../../docs/installing.md:160 +#: ../../../docs/installing.md:169 msgid "Also, do not forget to update your system regularly. While this playbook may install basic services, such as Docker, it will not interfere further with system maintenance. Keeping the system itself up-to-date is out of scope for this playbook." msgstr "" -#: ../../../docs/installing.md:162 +#: ../../../docs/installing.md:171 msgid "For more information about upgrading or maintaining services with the playbook, take a look at this page: [Upgrading the Matrix services](maintenance-upgrading-services.md)" msgstr "" -#: ../../../docs/installing.md:164 +#: ../../../docs/installing.md:173 msgid "Feel free to **re-run the setup command any time** you think something is wrong with the server configuration. Ansible will take your configuration and update your server to match." msgstr "" -#: ../../../docs/installing.md:170 +#: ../../../docs/installing.md:179 msgid "**Note**: see [this page on the playbook tags](playbook-tags.md) for more information about those tags." msgstr "" -#: ../../../docs/installing.md:172 +#: ../../../docs/installing.md:181 msgid "Make full use of `just` shortcut commands" msgstr "" -#: ../../../docs/installing.md:174 +#: ../../../docs/installing.md:183 msgid "After you get familiar with reconfiguring and re-running the playbook to maintain the server, upgrade its services, etc., you probably would like to make use of `just` shortcut commands for faster input." msgstr "" -#: ../../../docs/installing.md:176 +#: ../../../docs/installing.md:185 msgid "For example, `just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed." msgstr "" -#: ../../../docs/installing.md:178 +#: ../../../docs/installing.md:187 msgid "You can learn about the shortcut commands on this page: [Running `just` commands](just.md)" msgstr "" diff --git a/i18n/translation-templates/docs/just.pot b/i18n/translation-templates/docs/just.pot index 5d0ad118b..0edb6241d 100644 --- a/i18n/translation-templates/docs/just.pot +++ b/i18n/translation-templates/docs/just.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-15 09:10+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -162,17 +162,17 @@ msgid "Conditional service restart" msgstr "" #: ../../../docs/just.md:49 -msgid "When using `just install-all` or `just install-service`, only services whose configuration or container image actually changed during the playbook run will be restarted. Unchanged services are left running (or get started if they were stopped). This reduces unnecessary downtime." +msgid "When running `install-all` or `install-service` (whether via `just` or raw `ansible-playbook`), only services whose configuration or container image actually changed during the playbook run will be restarted. Unchanged services are left running (or get started if they were stopped). This reduces unnecessary downtime." msgstr "" #: ../../../docs/just.md:51 -msgid "When using `just setup-all`, all services are unconditionally restarted regardless of whether changes were detected. This is appropriate for `setup-all`'s thorough \"full setup\" semantics." +msgid "When running with `setup-*` tags (e.g. `setup-all`, `setup-synapse`), all services are unconditionally restarted regardless of whether changes were detected. This is appropriate for setup's thorough \"full setup\" semantics." msgstr "" #: ../../../docs/just.md:53 -msgid "`just start-all` and `just start-group` always restart all targeted services, since no installation tasks run during these commands." +msgid "`start-all` and `start-group` always restart all targeted services, since no installation tasks run during these commands." msgstr "" #: ../../../docs/just.md:55 -msgid "This behavior is controlled by the `devture_systemd_service_manager_conditional_restart_enabled` variable (default: `true`). To force unconditional restarts during installation, pass: `just install-all --extra-vars='devture_systemd_service_manager_conditional_restart_enabled=false'`" +msgid "This behavior is automatically determined based on the playbook tags in use. It can be overridden with the `devture_systemd_service_manager_conditional_restart_enabled` variable. For example, to force unconditional restarts during installation: `just install-all --extra-vars='devture_systemd_service_manager_conditional_restart_enabled=false'`" msgstr "" diff --git a/i18n/translation-templates/docs/maintenance-migrating.pot b/i18n/translation-templates/docs/maintenance-migrating.pot index d2fae4e3c..5ee7e42dd 100644 --- a/i18n/translation-templates/docs/maintenance-migrating.pot +++ b/i18n/translation-templates/docs/maintenance-migrating.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-01 17:14+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -73,7 +73,7 @@ msgid "Copy data directory to the new server" msgstr "" #: ../../../docs/maintenance-migrating.md:40 -msgid "After you've confirmed that all services were stopped, copy the `/matrix` directory from the old server to the new server. When copying, make sure to preserve ownership and permissions (use `cp -p` or `rsync -ar`)!" +msgid "After you've confirmed that all services were stopped, copy the `/matrix` directory from the old server to the new server. When copying, make sure to preserve ownership and permissions (use `cp -p` or `rsync -a`)!" msgstr "" #: ../../../docs/maintenance-migrating.md:42 diff --git a/i18n/translation-templates/docs/maintenance-postgres.pot b/i18n/translation-templates/docs/maintenance-postgres.pot index 2c7dea86c..5c89e1759 100644 --- a/i18n/translation-templates/docs/maintenance-postgres.pot +++ b/i18n/translation-templates/docs/maintenance-postgres.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -76,8 +76,8 @@ msgstr "" msgid "You can then proceed to write queries. Example: `SELECT COUNT(*) FROM users;`" msgstr "" -#: ../../../docs/maintenance-postgres.md:38 -msgid "[!WARNING] **Modifying the database directly (especially as services are running) is dangerous and may lead to irreversible database corruption.** When in doubt, consider [making a backup](#backing-up-postgresql)." +#: ../../../docs/maintenance-postgres.md:39 +msgid "**Modifying the database directly (especially as services are running) is dangerous and may lead to irreversible database corruption.** When in doubt, consider [making a backup](#backing-up-postgresql)." msgstr "" #: ../../../docs/maintenance-postgres.md:41 @@ -149,69 +149,73 @@ msgid "Restoring a backup made this way can be done by [importing it](importing- msgstr "" #: ../../../docs/maintenance-postgres.md:79 -msgid "Upgrading PostgreSQL" +msgid "**Note for Synapse users**: the [official Synapse backup guide](https://element-hq.github.io/synapse/latest/usage/administration/backups.html) recommends that the `e2e_one_time_keys_json` table either not be backed up, or be truncated after restoring (before Synapse is started). The full-server dump command above does include it, so if you ever restore a backup that is older than the server's current state, remember to truncate that table as described in [the importing guide](importing-postgres.md)." msgstr "" #: ../../../docs/maintenance-postgres.md:81 -msgid "Unless you are using an [external Postgres server](configuring-playbook-external-postgres.md), this playbook initially installs Postgres for you." +msgid "Upgrading PostgreSQL" msgstr "" #: ../../../docs/maintenance-postgres.md:83 -msgid "Once installed, the playbook attempts to preserve the Postgres version it starts with. This is because newer Postgres versions cannot start with data generated by older Postgres versions." +msgid "Unless you are using an [external Postgres server](configuring-playbook-external-postgres.md), this playbook initially installs Postgres for you." msgstr "" #: ../../../docs/maintenance-postgres.md:85 -msgid "Upgrades must be performed manually." +msgid "Once installed, the playbook attempts to preserve the Postgres version it starts with. This is because newer Postgres versions cannot start with data generated by older Postgres versions." msgstr "" #: ../../../docs/maintenance-postgres.md:87 +msgid "Upgrades must be performed manually." +msgstr "" + +#: ../../../docs/maintenance-postgres.md:89 msgid "The playbook can upgrade your existing Postgres setup with the following command:" msgstr "" -#: ../../../docs/maintenance-postgres.md:93 +#: ../../../docs/maintenance-postgres.md:95 msgid "**The old Postgres data directory is backed up** automatically, by renaming it to `/matrix/postgres/data-auto-upgrade-backup`. To rename to a different path, pass some extra flags to the command above, like this: `--extra-vars=\"postgres_auto_upgrade_backup_data_path=/another/disk/matrix-postgres-before-upgrade\"`" msgstr "" -#: ../../../docs/maintenance-postgres.md:95 +#: ../../../docs/maintenance-postgres.md:97 msgid "The auto-upgrade-backup directory stays around forever, until you **manually decide to delete it**." msgstr "" -#: ../../../docs/maintenance-postgres.md:97 +#: ../../../docs/maintenance-postgres.md:99 msgid "As part of the upgrade, the database is dumped to `/tmp`, an upgraded and empty Postgres server is started, and then the dump is restored into the new server. To use a different directory for the dump, pass some extra flags to the command above, like this: `--extra-vars=\"postgres_dump_dir=/directory/to/dump/here\"`" msgstr "" -#: ../../../docs/maintenance-postgres.md:99 +#: ../../../docs/maintenance-postgres.md:101 msgid "To save disk space in `/tmp`, the dump file is gzipped on the fly at the expense of CPU usage. If you have plenty of space in `/tmp` and would rather avoid gzipping, you can explicitly pass a dump filename which doesn't end in `.gz`. Example: `--extra-vars=\"postgres_dump_name=matrix-postgres-dump.sql\"`" msgstr "" -#: ../../../docs/maintenance-postgres.md:101 +#: ../../../docs/maintenance-postgres.md:103 msgid "**All databases, roles, etc. on the Postgres server are migrated**. However, other components that depend on specific Postgres versions (like the [Postgres Backup](configuring-playbook-postgres-backup.md) service) may need to be updated after the upgrade by using `just install-all`" msgstr "" -#: ../../../docs/maintenance-postgres.md:103 +#: ../../../docs/maintenance-postgres.md:105 msgid "Tuning PostgreSQL" msgstr "" -#: ../../../docs/maintenance-postgres.md:105 +#: ../../../docs/maintenance-postgres.md:107 msgid "PostgreSQL can be [tuned](https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server) to make it run faster. This is done by passing extra arguments to the Postgres process." msgstr "" -#: ../../../docs/maintenance-postgres.md:107 +#: ../../../docs/maintenance-postgres.md:109 msgid "The [Postgres Ansible role](https://github.com/mother-of-all-self-hosting/ansible-role-postgres) **already does some tuning by default**, which matches the [tuning logic](https://github.com/le0pard/pgtune/blob/master/src/features/configuration/configurationSlice.js) done by websites like https://pgtune.leopard.in.ua/. You can manually influence some of the tuning variables. These parameters (variables) are injected via the `postgres_postgres_process_extra_arguments_default` variable." msgstr "" -#: ../../../docs/maintenance-postgres.md:109 +#: ../../../docs/maintenance-postgres.md:111 msgid "Most users should be fine with the automatically-done tuning. However, you may wish to:" msgstr "" -#: ../../../docs/maintenance-postgres.md:111 +#: ../../../docs/maintenance-postgres.md:113 msgid "**adjust the automatically-determined tuning parameters manually**: change the values for the tuning variables defined in the Postgres role's [default configuration file](https://github.com/mother-of-all-self-hosting/ansible-role-postgres/blob/main/defaults/main.yml) (see `postgres_max_connections`, `postgres_data_storage` etc). These variables are ultimately passed to Postgres via a `postgres_postgres_process_extra_arguments_default` variable" msgstr "" -#: ../../../docs/maintenance-postgres.md:113 +#: ../../../docs/maintenance-postgres.md:115 msgid "**turn automatically-performed tuning off**: override it like this: `postgres_postgres_process_extra_arguments_default: []`" msgstr "" -#: ../../../docs/maintenance-postgres.md:115 +#: ../../../docs/maintenance-postgres.md:117 msgid "**add additional tuning parameters**: define your additional Postgres configuration parameters in `postgres_postgres_process_extra_arguments_custom`. See `postgres_postgres_process_extra_arguments_default` defined in the Postgres role's [default configuration file](https://github.com/mother-of-all-self-hosting/ansible-role-postgres/blob/main/defaults/main.yml) for inspiration" msgstr "" diff --git a/i18n/translation-templates/docs/maintenance-synapse.pot b/i18n/translation-templates/docs/maintenance-synapse.pot index 5889aa790..b8d77eb47 100644 --- a/i18n/translation-templates/docs/maintenance-synapse.pot +++ b/i18n/translation-templates/docs/maintenance-synapse.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-16 13:47+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -60,8 +60,8 @@ msgstr "" msgid "To make use of this Synapse Admin API, **you'll need an admin access token** first. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md)." msgstr "" -#: ../../../docs/maintenance-synapse.md:30 -msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." +#: ../../../docs/maintenance-synapse.md:31 +msgid "Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" #: ../../../docs/maintenance-synapse.md:33 @@ -145,57 +145,65 @@ msgid "Synapse's presence feature which tracks which users are online and which msgstr "" #: ../../../docs/maintenance-synapse.md:86 -msgid "If you have enough compute resources (CPU & RAM), you can make Synapse better use of them by [enabling load-balancing with workers](configuring-playbook-synapse.md#load-balancing-with-workers)." +msgid "On smaller servers, consider limiting joins to very complex rooms with [the room complexity guard](configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts)." msgstr "" #: ../../../docs/maintenance-synapse.md:88 -msgid "[Tuning your PostgreSQL database](maintenance-postgres.md#tuning-postgresql) could also improve Synapse performance. The playbook tunes the integrated Postgres database automatically, but based on your needs you may wish to adjust tuning variables manually. If you're using an [external Postgres database](configuring-playbook-external-postgres.md), you will also need to tune Postgres manually." +msgid "If you have enough compute resources (CPU & RAM), you can make Synapse better use of them by [enabling load-balancing with workers](configuring-playbook-synapse.md#load-balancing-with-workers)." msgstr "" #: ../../../docs/maintenance-synapse.md:90 -msgid "Tuning caches and cache autotuning" +msgid "[Tuning your PostgreSQL database](maintenance-postgres.md#tuning-postgresql) could also improve Synapse performance. The playbook tunes the integrated Postgres database automatically, but based on your needs you may wish to adjust tuning variables manually. If you're using an [external Postgres database](configuring-playbook-external-postgres.md), you will also need to tune Postgres manually." msgstr "" #: ../../../docs/maintenance-synapse.md:92 -msgid "Tuning Synapse's cache factor is useful for performance increases but also as part of controlling Synapse's memory use. Use the variable `matrix_synapse_caches_global_factor` to set the cache factor as part of this process." +msgid "Tuning caches and cache autotuning" msgstr "" #: ../../../docs/maintenance-synapse.md:94 -msgid "**The playbook defaults the global cache factor to a large value** (e.g. `10`). A smaller value (e.g. `0.5`) will decrease the amount used for caches, but will [not necessarily decrease RAM usage as a whole](https://github.com/matrix-org/synapse/issues/3939)." +msgid "Tuning Synapse's cache factor is useful for performance increases but also as part of controlling Synapse's memory use. Use the variable `matrix_synapse_caches_global_factor` to set the cache factor as part of this process." msgstr "" #: ../../../docs/maintenance-synapse.md:96 -msgid "Tuning the cache factor is useful only to a limited degree (as its crude to do in isolation) and therefore users who are tuning their cache factor should likely look into tuning autotune variables as well (see below)." +msgid "**The playbook defaults the global cache factor to a large value** (e.g. `10`). A smaller value (e.g. `0.5`) will decrease the amount used for caches, but will [not necessarily decrease RAM usage as a whole](https://github.com/matrix-org/synapse/issues/3939)." msgstr "" #: ../../../docs/maintenance-synapse.md:98 -msgid "Cache autotuning is **enabled by default** and controlled via the following variables:" +msgid "Tuning the cache factor is useful only to a limited degree (as its crude to do in isolation) and therefore users who are tuning their cache factor should likely look into tuning autotune variables as well (see below)." msgstr "" #: ../../../docs/maintenance-synapse.md:100 +msgid "Cache autotuning is **enabled by default** and controlled via the following variables:" +msgstr "" + +#: ../../../docs/maintenance-synapse.md:102 msgid "`matrix_synapse_cache_autotuning_max_cache_memory_usage` — defaults to 1/8 of total RAM with a cap of 2GB; values are specified in bytes" msgstr "" -#: ../../../docs/maintenance-synapse.md:101 +#: ../../../docs/maintenance-synapse.md:103 msgid "`matrix_synapse_cache_autotuning_target_cache_memory_usage` — defaults to 1/16 of total RAM with a cap of 1GB; values are specified in bytes" msgstr "" -#: ../../../docs/maintenance-synapse.md:102 +#: ../../../docs/maintenance-synapse.md:104 msgid "`matrix_synapse_cache_autotuning_min_cache_ttl` — defaults to `30s`" msgstr "" -#: ../../../docs/maintenance-synapse.md:104 +#: ../../../docs/maintenance-synapse.md:106 msgid "You can **learn more about cache-autotuning and the global cache factor settings** in the [Synapse's documentation on caches and associated values](https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#caches-and-associated-values)." msgstr "" -#: ../../../docs/maintenance-synapse.md:106 +#: ../../../docs/maintenance-synapse.md:109 +msgid "These limits apply **per Synapse process**. If you have [workers](configuring-playbook-synapse.md#load-balancing-with-workers) enabled, the main process and every worker each apply the configured limits independently, so the theoretical aggregate cache memory usage gets multiplied by the number of processes. When running many workers on a memory-constrained server, consider setting these variables to lower, explicitly chosen values." +msgstr "" + +#: ../../../docs/maintenance-synapse.md:111 msgid "To **disable cache auto-tuning**, unset all values:" msgstr "" -#: ../../../docs/maintenance-synapse.md:114 +#: ../../../docs/maintenance-synapse.md:119 msgid "Users who wish to lower Synapse's RAM footprint should look into lowering the global cache factor and tweaking the autotune variables (or disabling auto-tuning). If your cache factor is too low for a given auto tune setting your caches will not reach autotune thresholds and autotune won't be able to do its job. Therefore, when auto-tuning is enabled (which it is by default), it's recommended to have your cache factor be large." msgstr "" -#: ../../../docs/maintenance-synapse.md:116 +#: ../../../docs/maintenance-synapse.md:121 msgid "See also [How do I optimize this setup for a low-power server?](faq.md#how-do-i-optimize-this-setup-for-a-low-power-server)." msgstr "" diff --git a/i18n/translation-templates/docs/maintenance-upgrading-services.pot b/i18n/translation-templates/docs/maintenance-upgrading-services.pot index f714867b2..a291e0eb4 100644 --- a/i18n/translation-templates/docs/maintenance-upgrading-services.pot +++ b/i18n/translation-templates/docs/maintenance-upgrading-services.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-07 11:16+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -73,7 +73,7 @@ msgid "or: a combination of `git pull` and `just roles` (or `make roles` if you msgstr "" #: ../../../docs/maintenance-upgrading-services.md:39 -msgid "If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly: `rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force`" +msgid "If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly after updating the playbook: `git pull; rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force`" msgstr "" #: ../../../docs/maintenance-upgrading-services.md:41 @@ -81,45 +81,69 @@ msgid "**Note**: for details about `just` commands, take a look at: [Running `ju msgstr "" #: ../../../docs/maintenance-upgrading-services.md:43 -msgid "Re-run the playbook setup" +msgid "Acknowledge breaking changes if any" msgstr "" #: ../../../docs/maintenance-upgrading-services.md:45 -msgid "After updating the Ansible roles, then re-run the [playbook setup](installing.md#maintaining-your-setup-in-the-future) and restart all services:" +msgid "The playbook uses a migration validation system that ensures you are aware of breaking changes before they'll affect your deployment. If there is one, you are required to acknowledge each breaking change." +msgstr "" + +#: ../../../docs/maintenance-upgrading-services.md:47 +msgid "Whenever a breaking change is introduced, the playbook will:" +msgstr "" + +#: ../../../docs/maintenance-upgrading-services.md:49 +msgid "bump its expected version value (`matrix_playbook_migration_expected_version`), causing a discrepancy with what you validated (`matrix_playbook_migration_validated_version`)" msgstr "" #: ../../../docs/maintenance-upgrading-services.md:51 -msgid "If you remove components from `vars.yml`, or if we switch some component from being installed by default to not being installed by default anymore, you'd need to run the setup command with the `setup-all` tag as below:" +msgid "fail when you run it with a helpful message listing what changed and linking to the relevant changelog entries" +msgstr "" + +#: ../../../docs/maintenance-upgrading-services.md:53 +msgid "After reviewing and adapting your setup, update the variable to the new version." +msgstr "" + +#: ../../../docs/maintenance-upgrading-services.md:55 +msgid "Re-run the playbook setup" msgstr "" #: ../../../docs/maintenance-upgrading-services.md:57 +msgid "After updating the Ansible roles and the variable for the validation system when necessary, re-run the [playbook setup](installing.md#maintaining-your-setup-in-the-future) and restart all services:" +msgstr "" + +#: ../../../docs/maintenance-upgrading-services.md:63 +msgid "If you remove components from `vars.yml`, or if we switch some component from being installed by default to not being installed by default anymore, you'd need to run the setup command with the `setup-all` tag as below:" +msgstr "" + +#: ../../../docs/maintenance-upgrading-services.md:69 msgid "**Notes**:" msgstr "" -#: ../../../docs/maintenance-upgrading-services.md:59 +#: ../../../docs/maintenance-upgrading-services.md:71 msgid "The `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account, if any." msgstr "" -#: ../../../docs/maintenance-upgrading-services.md:61 +#: ../../../docs/maintenance-upgrading-services.md:73 msgid "Our estimation is that running `--tags=install-all,start` is approximately from **2 to 5 times faster** than running `setup-all,ensure-matrix-users-created,start`. See [this entry](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) on `CHANGELOG.md` for more information." msgstr "" -#: ../../../docs/maintenance-upgrading-services.md:63 +#: ../../../docs/maintenance-upgrading-services.md:75 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/maintenance-upgrading-services.md:65 +#: ../../../docs/maintenance-upgrading-services.md:77 msgid "See [this page on the playbook tags](playbook-tags.md) for more information about those tags." msgstr "" -#: ../../../docs/maintenance-upgrading-services.md:67 +#: ../../../docs/maintenance-upgrading-services.md:79 msgid "PostgreSQL major version upgrade" msgstr "" -#: ../../../docs/maintenance-upgrading-services.md:69 +#: ../../../docs/maintenance-upgrading-services.md:81 msgid "Major version upgrades to the internal PostgreSQL database are not done automatically. Upgrades must be performed manually." msgstr "" -#: ../../../docs/maintenance-upgrading-services.md:71 +#: ../../../docs/maintenance-upgrading-services.md:83 msgid "For details about upgrading it, refer to the [upgrading PostgreSQL guide](maintenance-postgres.md#upgrading-postgresql)." msgstr "" diff --git a/i18n/translation-templates/docs/obtaining-access-tokens.pot b/i18n/translation-templates/docs/obtaining-access-tokens.pot index 33cbf79e2..adc5ce18f 100644 --- a/i18n/translation-templates/docs/obtaining-access-tokens.pot +++ b/i18n/translation-templates/docs/obtaining-access-tokens.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -24,8 +24,8 @@ msgstr "" msgid "When setting up some optional features like bots and bridges you will need to provide an access token for some user. This document provides documentation on how to obtain such an access token." msgstr "" -#: ../../../docs/obtaining-access-tokens.md:14 -msgid "[!WARNING] Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." +#: ../../../docs/obtaining-access-tokens.md:15 +msgid "Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone." msgstr "" #: ../../../docs/obtaining-access-tokens.md:17 diff --git a/i18n/translation-templates/docs/prerequisites.pot b/i18n/translation-templates/docs/prerequisites.pot index 5790801ea..ff919d725 100644 --- a/i18n/translation-templates/docs/prerequisites.pot +++ b/i18n/translation-templates/docs/prerequisites.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-04-15 09:10+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -125,33 +125,13 @@ msgid "`443/tcp` and `443/udp`: HTTPS webserver" msgstr "" #: ../../../docs/prerequisites.md:60 -msgid "`3478/tcp`: STUN/TURN over TCP (used by [coturn](./configuring-playbook-turn.md))" -msgstr "" - -#: ../../../docs/prerequisites.md:61 -msgid "`3478/udp`: STUN/TURN over UDP (used by [coturn](./configuring-playbook-turn.md))" -msgstr "" - -#: ../../../docs/prerequisites.md:62 -msgid "`5349/tcp`: TURN over TCP (used by [coturn](./configuring-playbook-turn.md))" -msgstr "" - -#: ../../../docs/prerequisites.md:63 -msgid "`5349/udp`: TURN over UDP (used by [coturn](./configuring-playbook-turn.md))" -msgstr "" - -#: ../../../docs/prerequisites.md:64 msgid "`8448/tcp` and `8448/udp`: Matrix Federation API HTTPS webserver. Some components like [Matrix User Verification Service](configuring-playbook-user-verification-service.md#open-matrix-federation-port) require this port to be opened **even with federation disabled**." msgstr "" -#: ../../../docs/prerequisites.md:65 -msgid "the range `49152-49172/udp`: TURN over UDP" -msgstr "" - -#: ../../../docs/prerequisites.md:66 +#: ../../../docs/prerequisites.md:61 msgid "potentially some other ports, depending on the additional (non-default) services that you enable in the **configuring the playbook** step (later on). Consult each service's documentation page in `docs/` for that." msgstr "" -#: ../../../docs/prerequisites.md:70 +#: ../../../docs/prerequisites.md:65 msgid "[▶️](configuring-dns.md) When ready to proceed, continue with [Configuring DNS](configuring-dns.md)." msgstr "" diff --git a/i18n/translation-templates/docs/quick-start.pot b/i18n/translation-templates/docs/quick-start.pot index fb266f0f8..c0d48de23 100644 --- a/i18n/translation-templates/docs/quick-start.pot +++ b/i18n/translation-templates/docs/quick-start.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-07-12 15:37+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -213,229 +213,265 @@ msgid "For your convenience, we have prepared example files of them ([`vars.yml` msgstr "" #: ../../../docs/quick-start.md:92 -msgid "To start quickly based on these example files, go into the `matrix-docker-ansible-deploy` directory and follow the instructions below:" +msgid "To start quickly based on these example files, go into the `matrix-docker-ansible-deploy` directory and initialize your configuration, either automatically or manually." msgstr "" #: ../../../docs/quick-start.md:94 +msgid "To initialize it automatically (with the base domain and server address pre-filled and secrets generated for you), run:" +msgstr "" + +#: ../../../docs/quick-start.md:96 +msgid "either: `just add-inventory-host example.com 1.2.3.4` (if you have the [`just`](just.md) tool)" +msgstr "" + +#: ../../../docs/quick-start.md:97 +msgid "or: `make add-inventory-host domain=example.com ip=1.2.3.4` (if you have the `make` program)" +msgstr "" + +#: ../../../docs/quick-start.md:99 +msgid "… where `example.com` is your \"base domain\" (not `matrix.example.com`) and `1.2.3.4` is your server's external IP address (or domain name)." +msgstr "" + +#: ../../../docs/quick-start.md:101 +msgid "Given a base domain of `example.com`, this creates:" +msgstr "" + +#: ../../../docs/quick-start.md:103 +msgid "an entry for `matrix.example.com` (the Matrix server's default hostname: `matrix.` + your base domain) in the inventory hosts file (`inventory/hosts`)" +msgstr "" + +#: ../../../docs/quick-start.md:104 +msgid "a configuration file (`inventory/host_vars/matrix.example.com/vars.yml`) containing `matrix_domain: example.com` and automatically generated secrets" +msgstr "" + +#: ../../../docs/quick-start.md:106 +msgid "Afterward, edit these 2 files to adjust them further, as necessary. Existing configuration is never overwritten (the command refuses to run if the host is already in your inventory), so it can also be used for adding more hosts later." +msgstr "" + +#: ../../../docs/quick-start.md:108 +msgid "To initialize it manually, follow the instructions below:" +msgstr "" + +#: ../../../docs/quick-start.md:110 msgid "Create a directory to hold your configuration: `mkdir -p inventory/host_vars/matrix.example.com` where `example.com` is your \"base domain\"" msgstr "" -#: ../../../docs/quick-start.md:95 +#: ../../../docs/quick-start.md:111 msgid "Copy the sample configuration file: `cp examples/vars.yml inventory/host_vars/matrix.example.com/vars.yml`" msgstr "" -#: ../../../docs/quick-start.md:96 +#: ../../../docs/quick-start.md:112 msgid "Copy the sample inventory hosts file: `cp examples/hosts inventory/hosts`" msgstr "" -#: ../../../docs/quick-start.md:97 +#: ../../../docs/quick-start.md:113 msgid "Edit the configuration file (`inventory/host_vars/matrix.example.com/vars.yml`)" msgstr "" -#: ../../../docs/quick-start.md:98 +#: ../../../docs/quick-start.md:114 msgid "Edit the inventory hosts file (`inventory/hosts`)" msgstr "" -#: ../../../docs/quick-start.md:100 +#: ../../../docs/quick-start.md:116 msgid "Before editing these 2 files, make sure to read explanations on them to understand what needs to be configured." msgstr "" -#: ../../../docs/quick-start.md:102 +#: ../../../docs/quick-start.md:118 msgid "**💡 Notes:**" msgstr "" -#: ../../../docs/quick-start.md:103 +#: ../../../docs/quick-start.md:119 msgid "If you are not in control of anything on the base domain, you would need to set additional configuration on `vars.yml`. For more information, see [How do I install on matrix.example.com without involving the base domain?](faq.md#how-do-i-install-on-matrix-example-com-without-involving-the-base-domain) on our FAQ." msgstr "" -#: ../../../docs/quick-start.md:104 +#: ../../../docs/quick-start.md:120 msgid "Certain configuration decisions (like the base domain configured in `matrix_domain` and homeserver implementation configured in `matrix_homeserver_implementation`) are final. If you make the wrong choice and wish to change it, you'll have to run the Uninstalling step and start over." msgstr "" -#: ../../../docs/quick-start.md:105 +#: ../../../docs/quick-start.md:121 msgid "Instead of configuring a lot of things all at once, we recommend starting with the basic (default) settings in order to get yourself familiar with how the playbook works. After making sure that everything works as expected, you can add (and remove) advanced settings / features and run the playbook as many times as you wish." msgstr "" -#: ../../../docs/quick-start.md:107 +#: ../../../docs/quick-start.md:123 msgid "Install" msgstr "" -#: ../../../docs/quick-start.md:109 +#: ../../../docs/quick-start.md:125 msgid "This section is optimized for this quick-start guide and is derived from the following full-documentation page: [Installing](installing.md)" msgstr "" -#: ../../../docs/quick-start.md:111 +#: ../../../docs/quick-start.md:127 msgid "After editing `vars.yml` and `hosts` files, let's start the **installation** procedure." msgstr "" -#: ../../../docs/quick-start.md:113 +#: ../../../docs/quick-start.md:129 msgid "Update Ansible roles" msgstr "" -#: ../../../docs/quick-start.md:115 +#: ../../../docs/quick-start.md:131 msgid "Before installing, you need to update the Ansible roles that this playbook uses and fetches from outside." msgstr "" -#: ../../../docs/quick-start.md:117 +#: ../../../docs/quick-start.md:133 msgid "To update your playbook directory and all upstream Ansible roles, run:" msgstr "" -#: ../../../docs/quick-start.md:119 +#: ../../../docs/quick-start.md:135 msgid "either: `just update`" msgstr "" -#: ../../../docs/quick-start.md:120 +#: ../../../docs/quick-start.md:136 msgid "or: a combination of `git pull` and `just roles` (or `make roles` if you have `make` program on your computer instead of `just`)" msgstr "" -#: ../../../docs/quick-start.md:122 -msgid "If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly: `rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force`" +#: ../../../docs/quick-start.md:138 +msgid "If you don't have either `just` tool or `make` program, you can run the `ansible-galaxy` tool directly after updating the playbook: `git pull; rm -rf roles/galaxy; ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force`" msgstr "" -#: ../../../docs/quick-start.md:124 +#: ../../../docs/quick-start.md:140 msgid "Run installation command" msgstr "" -#: ../../../docs/quick-start.md:126 +#: ../../../docs/quick-start.md:142 msgid "Then, run the command below to start installation:" msgstr "" -#: ../../../docs/quick-start.md:132 +#: ../../../docs/quick-start.md:148 msgid "If you **don't** use SSH keys for authentication, but rather a regular password, you may need to add `--ask-pass` to the command." msgstr "" -#: ../../../docs/quick-start.md:134 +#: ../../../docs/quick-start.md:150 msgid "If you **do** use SSH keys for authentication, **and** use a non-root user to *become* root (sudo), you may need to add `-K` (`--ask-become-pass`) to the command." msgstr "" -#: ../../../docs/quick-start.md:136 +#: ../../../docs/quick-start.md:152 msgid "Wait until the command completes. If it's all green, everything should be running properly." msgstr "" -#: ../../../docs/quick-start.md:138 +#: ../../../docs/quick-start.md:154 msgid "Create your user account" msgstr "" -#: ../../../docs/quick-start.md:140 +#: ../../../docs/quick-start.md:156 msgid "This section is optimized for this quick-start guide and is derived from the following full-documentation page: [Registering users](registering-users.md)" msgstr "" -#: ../../../docs/quick-start.md:142 +#: ../../../docs/quick-start.md:158 msgid "As you have configured your brand new server and the client, you need to **create your user account** on your Matrix server." msgstr "" -#: ../../../docs/quick-start.md:144 +#: ../../../docs/quick-start.md:160 msgid "To create your user account (as an administrator of the server) via this Ansible playbook, run the command below on your local computer." msgstr "" -#: ../../../docs/quick-start.md:146 +#: ../../../docs/quick-start.md:162 msgid "**💡 Notes**:" msgstr "" -#: ../../../docs/quick-start.md:147 +#: ../../../docs/quick-start.md:163 msgid "Make sure to adjust `YOUR_USERNAME_HERE` and `YOUR_PASSWORD_HERE`" msgstr "" -#: ../../../docs/quick-start.md:148 +#: ../../../docs/quick-start.md:164 msgid "For `YOUR_USERNAME_HERE`, use a plain username like `alice`, not your full ID (`@alice:example.com`)" msgstr "" -#: ../../../docs/quick-start.md:160 +#: ../../../docs/quick-start.md:176 msgid "Finalize server installation" msgstr "" -#: ../../../docs/quick-start.md:162 +#: ../../../docs/quick-start.md:178 msgid "This section is optimized for this quick-start guide and is derived from the following full-documentation page: [Server Delegation](howto-server-delegation.md)" msgstr "" -#: ../../../docs/quick-start.md:164 +#: ../../../docs/quick-start.md:180 msgid "Now that you've configured Matrix services and your user account, you need to **finalize the installation process** by [setting up Matrix delegation (redirection)](howto-server-delegation.md), so that your Matrix server (`matrix.example.com`) can present itself as the base domain (`example.com`) in the Matrix network." msgstr "" -#: ../../../docs/quick-start.md:166 +#: ../../../docs/quick-start.md:182 msgid "**This is required for federation to work!** Without a proper configuration, your server will effectively not be part of the Matrix network." msgstr "" -#: ../../../docs/quick-start.md:168 +#: ../../../docs/quick-start.md:184 msgid "To configure the delegation, you have these two options. Choose one of them according to your situation." msgstr "" -#: ../../../docs/quick-start.md:170 +#: ../../../docs/quick-start.md:186 msgid "If you can afford to point the base domain at the Matrix server, follow the instruction below which guides you into [serving the base domain](configuring-playbook-base-domain-serving.md) from the integrated web server." msgstr "" -#: ../../../docs/quick-start.md:171 +#: ../../../docs/quick-start.md:187 msgid "Alternatively, if you're using the base domain for other purposes and cannot point it to the Matrix server (and thus cannot \"serve the base domain\" from it), you most likely need to [manually install well-known files on the base domain's server](configuring-well-known.md#manually-installing-well-known-files-on-the-base-domains-server)." msgstr "" -#: ../../../docs/quick-start.md:173 +#: ../../../docs/quick-start.md:189 msgid "To have the base domain served from the integrated web server, add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/quick-start.md:179 +#: ../../../docs/quick-start.md:195 msgid "After configuring the playbook, run the command below and wait until it finishes:" msgstr "" -#: ../../../docs/quick-start.md:185 +#: ../../../docs/quick-start.md:201 msgid "💡 Running the `install-matrix-static-files` playbook tag (as done here) is an optimized version of running [the full setup command](#run-installation-command)." msgstr "" -#: ../../../docs/quick-start.md:187 +#: ../../../docs/quick-start.md:203 msgid "After the command finishes, you can also check whether your server federates with the Matrix network by using the [Federation Tester](https://federationtester.matrix.org/) against your base domain (`example.com`), not the `matrix.example.com` subdomain." msgstr "" -#: ../../../docs/quick-start.md:189 +#: ../../../docs/quick-start.md:205 msgid "Re-run the full setup command any time" msgstr "" -#: ../../../docs/quick-start.md:191 +#: ../../../docs/quick-start.md:207 msgid "If you think something is wrong with the server configuration, feel free to re-run the setup command any time:" msgstr "" -#: ../../../docs/quick-start.md:197 +#: ../../../docs/quick-start.md:213 msgid "Log in to your user account" msgstr "" -#: ../../../docs/quick-start.md:199 +#: ../../../docs/quick-start.md:215 msgid "Finally, let's make sure that you can log in to the created account with the specified password." msgstr "" -#: ../../../docs/quick-start.md:201 +#: ../../../docs/quick-start.md:217 msgid "You should be able to log in to it with your own [Element Web](configuring-playbook-client-element-web.md) client which you have set up at `element.example.com` by running the playbook. Open the URL (`https://element.example.com`) in a web browser and enter your credentials to log in." msgstr "" -#: ../../../docs/quick-start.md:203 +#: ../../../docs/quick-start.md:219 msgid "**If you successfully logged in to your account, the installation and configuration have completed successfully**🎉" msgstr "" -#: ../../../docs/quick-start.md:205 +#: ../../../docs/quick-start.md:221 msgid "Come say Hi👋 in our support room — [#matrix-docker-ansible-deploy:devture.com](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com). You might learn something or get to help someone else new to Matrix hosting." msgstr "" -#: ../../../docs/quick-start.md:207 +#: ../../../docs/quick-start.md:223 msgid "Things to do next" msgstr "" -#: ../../../docs/quick-start.md:209 +#: ../../../docs/quick-start.md:225 msgid "Once you get familiar with the playbook, you might probably want to set up additional services such as a bridge on your server." msgstr "" -#: ../../../docs/quick-start.md:211 +#: ../../../docs/quick-start.md:227 msgid "As this page intends to be a quick start guide which explains how to start the core Matrix services, it does not cover a topic like how to set them up. Take a look at the list of [things to do next](installing.md#things-to-do-next) to learn more." msgstr "" -#: ../../../docs/quick-start.md:213 +#: ../../../docs/quick-start.md:229 msgid "⚠️Keep the playbook and services up-to-date" msgstr "" -#: ../../../docs/quick-start.md:215 +#: ../../../docs/quick-start.md:231 msgid "While this playbook helps you to set up Matrix services and maintain them, it will **not** automatically run the maintenance task for you. You will need to update the playbook and re-run it **manually**." msgstr "" -#: ../../../docs/quick-start.md:217 +#: ../../../docs/quick-start.md:233 msgid "Since it is unsafe to keep outdated services running on the server connected to the internet, please consider to update the playbook and re-run it periodically, in order to keep the services up-to-date." msgstr "" -#: ../../../docs/quick-start.md:219 +#: ../../../docs/quick-start.md:235 msgid "For more information about upgrading or maintaining services with the playbook, take a look at this page: [Upgrading the Matrix services](maintenance-upgrading-services.md)" msgstr "" diff --git a/i18n/translation-templates/docs/registering-users.pot b/i18n/translation-templates/docs/registering-users.pot index 079c29b2c..1d8be2102 100644 --- a/i18n/translation-templates/docs/registering-users.pot +++ b/i18n/translation-templates/docs/registering-users.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -57,7 +57,7 @@ msgid "Registering users manually" msgstr "" #: ../../../docs/registering-users.md:25 -#: ../../../docs/registering-users.md:130 +#: ../../../docs/registering-users.md:123 msgid "**Notes**:" msgstr "" @@ -97,8 +97,8 @@ msgstr "" msgid "Feel free to register as many users (for friends, family, etc.) as you want. Still, perhaps you should grant full administrative access to your user account only (with `admin=yes`), and others should be created with `admin=no`." msgstr "" -#: ../../../docs/registering-users.md:54 -msgid "[!WARNING] If you're registering users against Matrix Authentication Service, do note that it [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user. Upon a user's first login, they will be asked to confirm their email address. This requires that email sending is [configured](./configuring-playbook-email.md). You can also consult the [Working around email deliverability issues](./configuring-playbook-matrix-authentication-service.md#working-around-email-deliverability-issues) section for more information." +#: ../../../docs/registering-users.md:55 +msgid "If you're registering users against Matrix Authentication Service, do note that it [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user. Upon a user's first login, they will be asked to confirm their email address. This requires that email sending is [configured](./configuring-playbook-email.md). You can also consult the [Working around email deliverability issues](./configuring-playbook-matrix-authentication-service.md#working-around-email-deliverability-issues) section for more information." msgstr "" #: ../../../docs/registering-users.md:57 @@ -129,8 +129,8 @@ msgstr "" msgid "This `register-user` script actually invokes the `mas-cli manage register-user` command under the hood. If you'd like more control over the registration process, consider invoking the `mas-cli` command directly:" msgstr "" -#: ../../../docs/registering-users.md:93 -msgid "[!WARNING] Matrix Authentication Service [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user. Upon a user's first login, they will be asked to confirm their email address. This requires that email sending is [configured](./configuring-playbook-email.md). You can also consult the [Working around email deliverability issues](./configuring-playbook-matrix-authentication-service.md#working-around-email-deliverability-issues) section for more information." +#: ../../../docs/registering-users.md:94 +msgid "Matrix Authentication Service [still insists](https://github.com/element-hq/matrix-authentication-service/issues/1505) on having a verified email address for each user. Upon a user's first login, they will be asked to confirm their email address. This requires that email sending is [configured](./configuring-playbook-email.md). You can also consult the [Working around email deliverability issues](./configuring-playbook-matrix-authentication-service.md#working-around-email-deliverability-issues) section for more information." msgstr "" #: ../../../docs/registering-users.md:96 @@ -138,105 +138,93 @@ msgid "Managing users via a Web UI" msgstr "" #: ../../../docs/registering-users.md:98 -msgid "To manage users more easily (via a web user-interace), you can install [Synapse Admin](configuring-playbook-synapse-admin.md)." +msgid "To manage users and your homeserver more easily (via a web interface), you can install [Ketesa](configuring-playbook-ketesa.md) — a fully-featured admin UI covering users, rooms, media, sessions, and MAS management." msgstr "" #: ../../../docs/registering-users.md:100 -msgid "[!WARNING] If you're using [Matrix Authentication Service](configuring-playbook-matrix-authentication-service.md), note that user management via synapse-admin is not fully working yet. See the [Expectations](configuring-playbook-matrix-authentication-service.md#expectations) section for more information." -msgstr "" - -#: ../../../docs/registering-users.md:103 -msgid "Letting certain users register on your private server" -msgstr "" - -#: ../../../docs/registering-users.md:105 -msgid "If you'd rather **keep your server private** (public registration closed, as is the default), and **let certain people create accounts by themselves** (instead of creating user accounts manually like this), consider installing and making use of [matrix-registration](configuring-playbook-matrix-registration.md)." -msgstr "" - -#: ../../../docs/registering-users.md:107 msgid "Enabling public user registration" msgstr "" -#: ../../../docs/registering-users.md:109 +#: ../../../docs/registering-users.md:102 msgid "To **open up user registration publicly** (usually **not recommended**), add the following configuration to your `inventory/host_vars/matrix.example.com/vars.yml` file:" msgstr "" -#: ../../../docs/registering-users.md:111 +#: ../../../docs/registering-users.md:104 msgid "For Synapse:" msgstr "" -#: ../../../docs/registering-users.md:117 +#: ../../../docs/registering-users.md:110 msgid "For Dendrite:" msgstr "" -#: ../../../docs/registering-users.md:123 +#: ../../../docs/registering-users.md:116 msgid "After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below:" msgstr "" -#: ../../../docs/registering-users.md:132 +#: ../../../docs/registering-users.md:125 msgid "The shortcut commands with the [`just` program](just.md) are also available: `just install-all` or `just setup-all`" msgstr "" -#: ../../../docs/registering-users.md:134 +#: ../../../docs/registering-users.md:127 msgid "`just install-all` is useful for maintaining your setup quickly ([2x-5x faster](../CHANGELOG.md#2x-5x-performance-improvements-in-playbook-runtime) than `just setup-all`) when its components remain unchanged. If you adjust your `vars.yml` to remove other components, you'd need to run `just setup-all`, or these components will still remain installed. Note these shortcuts run the `ensure-matrix-users-created` tag too." msgstr "" -#: ../../../docs/registering-users.md:136 +#: ../../../docs/registering-users.md:129 msgid "If you're opening up registrations publicly like this, you might also wish to [configure CAPTCHA protection](configuring-captcha.md)." msgstr "" -#: ../../../docs/registering-users.md:138 +#: ../../../docs/registering-users.md:131 msgid "Adding/Removing Administrator privileges to an existing user" msgstr "" -#: ../../../docs/registering-users.md:140 +#: ../../../docs/registering-users.md:133 msgid "Adding/Removing Administrator privileges to an existing user in Synapse" msgstr "" -#: ../../../docs/registering-users.md:142 +#: ../../../docs/registering-users.md:135 msgid "To change the admin privileges for a user in Synapse's local database, you need to run an SQL query like this against the `synapse` database:" msgstr "" -#: ../../../docs/registering-users.md:148 +#: ../../../docs/registering-users.md:141 msgid "where:" msgstr "" -#: ../../../docs/registering-users.md:150 +#: ../../../docs/registering-users.md:143 msgid "`ADMIN_VALUE` being either `0` (regular user) or `1` (admin)" msgstr "" -#: ../../../docs/registering-users.md:151 +#: ../../../docs/registering-users.md:144 msgid "`USER` and `example.com` pointing to a valid user on your server" msgstr "" -#: ../../../docs/registering-users.md:153 +#: ../../../docs/registering-users.md:146 msgid "If you're using the integrated Postgres server and not an [external Postgres server](configuring-playbook-external-postgres.md), you can launch a Postgres into the `synapse` database by:" msgstr "" -#: ../../../docs/registering-users.md:155 +#: ../../../docs/registering-users.md:148 msgid "running `/matrix/postgres/bin/cli` — to launch [`psql`](https://www.postgresql.org/docs/current/app-psql.html)" msgstr "" -#: ../../../docs/registering-users.md:156 +#: ../../../docs/registering-users.md:149 msgid "running `\\c synapse` — to change to the `synapse` database" msgstr "" -#: ../../../docs/registering-users.md:158 +#: ../../../docs/registering-users.md:151 msgid "You can then proceed to run the query above." msgstr "" -#: ../../../docs/registering-users.md:160 +#: ../../../docs/registering-users.md:153 msgid "**Note**: directly modifying the raw data of Synapse (or any other software) could cause the software to break. You've been warned!" msgstr "" -#: ../../../docs/registering-users.md:162 +#: ../../../docs/registering-users.md:155 msgid "Adding/Removing Administrator privileges to an existing user in Matrix Authentication Service" msgstr "" -#: ../../../docs/registering-users.md:164 +#: ../../../docs/registering-users.md:157 msgid "Promoting/demoting a user in Matrix Authentication Service can be done using the [`mas-cli`](./configuring-playbook-matrix-authentication-service.md#management) management tool's [`manage promote-admin`](https://element-hq.github.io/matrix-authentication-service/reference/cli/manage.html#manage-promote-admin) and [`manage demote-admin`](https://element-hq.github.io/matrix-authentication-service/reference/cli/manage.html#manage-demote-admin) commands. For example: `/matrix/matrix-authentication-service/bin/mas-cli manage promote-admin some.username`." msgstr "" -#: ../../../docs/registering-users.md:166 +#: ../../../docs/registering-users.md:159 msgid "You can also do it via the [MAS Admin API](https://element-hq.github.io/matrix-authentication-service/api/index.html)'s `POST /api/admin/v1/users/{id}/set-admin` endpoint." msgstr "" diff --git a/i18n/translation-templates/docs/self-building.pot b/i18n/translation-templates/docs/self-building.pot index 41315f8ee..a2b69d55e 100644 --- a/i18n/translation-templates/docs/self-building.pot +++ b/i18n/translation-templates/docs/self-building.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-08-01 17:14+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -49,7 +49,7 @@ msgid "`matrix-synapse`" msgstr "" #: ../../../docs/self-building.md:29 -msgid "`matrix-synapse-admin`" +msgid "`matrix-ketesa`" msgstr "" #: ../../../docs/self-building.md:30 @@ -65,7 +65,7 @@ msgid "`cinny`" msgstr "" #: ../../../docs/self-building.md:33 -msgid "`matrix-registration`" +msgid "`sable`" msgstr "" #: ../../../docs/self-building.md:34 @@ -89,11 +89,11 @@ msgid "`matrix-bridge-appservice-irc`" msgstr "" #: ../../../docs/self-building.md:39 -msgid "`matrix-bridge-appservice-slack`" +msgid "`matrix-bridge-beeper-linkedin`" msgstr "" #: ../../../docs/self-building.md:40 -msgid "`matrix-bridge-beeper-linkedin`" +msgid "`matrix-bridge-beeper-line`" msgstr "" #: ../../../docs/self-building.md:41 @@ -113,37 +113,45 @@ msgid "`matrix-bridge-mautrix-gmessages`" msgstr "" #: ../../../docs/self-building.md:45 -msgid "`matrix-bridge-mautrix-whatsapp`" +msgid "`matrix-bridge-mautrix-gvoice`" msgstr "" #: ../../../docs/self-building.md:46 -msgid "`matrix-bridge-mx-puppet-steam`" +msgid "`matrix-bridge-mautrix-linkedin`" msgstr "" #: ../../../docs/self-building.md:47 -msgid "`matrix-bot-mjolnir`" +msgid "`matrix-bridge-mautrix-whatsapp`" msgstr "" #: ../../../docs/self-building.md:48 -msgid "`matrix-bot-honoroit`" +msgid "`matrix-bridge-mx-puppet-steam`" msgstr "" #: ../../../docs/self-building.md:49 -msgid "`matrix-bot-matrix-reminder-bot`" +msgid "`matrix-bot-mjolnir`" msgstr "" #: ../../../docs/self-building.md:50 -msgid "`matrix-bot-maubot`" +msgid "`matrix-bot-honoroit`" msgstr "" #: ../../../docs/self-building.md:51 -msgid "`matrix-pantalaimon`" +msgid "`matrix-bot-matrix-reminder-bot`" +msgstr "" + +#: ../../../docs/self-building.md:52 +msgid "`matrix-bot-maubot`" msgstr "" #: ../../../docs/self-building.md:53 -msgid "Adding self-building support to other roles is welcome. Feel free to contribute!" +msgid "`matrix-pantalaimon`" msgstr "" #: ../../../docs/self-building.md:55 +msgid "Adding self-building support to other roles is welcome. Feel free to contribute!" +msgstr "" + +#: ../../../docs/self-building.md:57 msgid "If you'd like **to force self-building** even if an image is available for your architecture, look into the `matrix_*_self_build` variables provided by individual roles." msgstr "" diff --git a/i18n/translation-templates/docs/style-guide.pot b/i18n/translation-templates/docs/style-guide.pot new file mode 100644 index 000000000..9d5b6e6ff --- /dev/null +++ b/i18n/translation-templates/docs/style-guide.pot @@ -0,0 +1,253 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2018-2026, Slavi Pantaleev, Aine Etke, MDAD community members +# This file is distributed under the same license as the matrix-docker-ansible-deploy package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: matrix-docker-ansible-deploy \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-07-18 04:11+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../docs/style-guide.md:8 +msgid "Style guide for playbook developers" +msgstr "" + +#: ../../../docs/style-guide.md:10 +msgid "This page describes the conventions used when developing this playbook and writing its documentation. Follow it when adding a new component (a role and its documentation page) or editing existing ones, so that everything stays consistent." +msgstr "" + +#: ../../../docs/style-guide.md:12 +msgid "The guide is meant for anyone preparing a contribution, humans and AI agents alike. If you find existing files that deviate from it, feel free to send a pull request bringing them in line." +msgstr "" + +#: ../../../docs/style-guide.md:14 +msgid "Language" +msgstr "" + +#: ../../../docs/style-guide.md:16 +msgid "Write in English, using American spelling (\"customize\", not \"customise\")." +msgstr "" + +#: ../../../docs/style-guide.md:17 +msgid "Proper nouns are capitalized: Matrix, Element, Synapse, Ansible, Docker, Traefik, Postgres, Grafana, etc. Some projects deliberately brand themselves in lowercase (e.g. `baibot`, `rageshake`, `coturn`, `mautrix-telegram`) and keep their lowercase name even at the start of a sentence. When in doubt, follow the upstream project's own spelling." +msgstr "" + +#: ../../../docs/style-guide.md:19 +msgid "Markdown style" +msgstr "" + +#: ../../../docs/style-guide.md:21 +msgid "Do not hard-wrap prose. Each paragraph is a single line in the source file, no matter how long. This keeps the source and the rendered result consistent and makes diffs and translations easier to work with." +msgstr "" + +#: ../../../docs/style-guide.md:22 +msgid "Number ordered lists sequentially (`1.`, `2.`, `3.`), instead of relying on the Markdown renderer to fix a repeated (`1.`, `1.`, `1.`) or wrong (`1.`, `2.`, `4.`) sequence." +msgstr "" + +#: ../../../docs/style-guide.md:23 +msgid "Use `-` for unordered lists." +msgstr "" + +#: ../../../docs/style-guide.md:24 +msgid "Wrap variable names, file paths, commands, domains, and service names in backticks (`` ` ``)." +msgstr "" + +#: ../../../docs/style-guide.md:25 +msgid "Use fenced code blocks with a language hint (```` ```yaml ````, ```` ```sh ````) for configuration and command examples." +msgstr "" + +#: ../../../docs/style-guide.md:26 +msgid "Use relative links when linking between documentation pages (e.g. `[Configuring DNS](configuring-dns.md)`)." +msgstr "" + +#: ../../../docs/style-guide.md:27 +msgid "Link to the upstream project's official documentation instead of duplicating its content (installation steps, distro-specific commands, etc.). Copied instructions go stale; links age much better." +msgstr "" + +#: ../../../docs/style-guide.md:29 +msgid "Example values" +msgstr "" + +#: ../../../docs/style-guide.md:31 +msgid "Use these placeholder values in documentation and code comments, so examples look the same everywhere:" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "What" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "Value" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "base domain" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "`example.com`" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "Matrix server domain" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "`matrix.example.com`" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "another (federated) server" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "`example.org`" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "user IDs" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "`@alice:example.com`, `@bob:example.com`" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "room ID" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "`!qporfwt:example.com`" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "room alias" +msgstr "" + +#: ../../../docs/style-guide.md:0 +msgid "`#room:example.com`" +msgstr "" + +#: ../../../docs/style-guide.md:42 +msgid "The user and room ID values follow the examples in the [Matrix specification](https://spec.matrix.org/latest/#room-structure). Never use real domains, usernames, or tokens in examples." +msgstr "" + +#: ../../../docs/style-guide.md:44 +msgid "Component-specific identifiers (e.g. a bridge bot like `@telegrambot:example.com`) are fine where they make an example clearer." +msgstr "" + +#: ../../../docs/style-guide.md:46 +msgid "Documentation page structure" +msgstr "" + +#: ../../../docs/style-guide.md:48 +msgid "Each component gets its own documentation page: `docs/configuring-playbook-.md` (bridges use a `configuring-playbook-bridge-.md` file name, bots use `configuring-playbook-bot-.md`)." +msgstr "" + +#: ../../../docs/style-guide.md:50 +msgid "A typical page looks like this, with sections appearing in this order (sections that do not apply can be omitted):" +msgstr "" + +#: ../../../docs/style-guide.md:74 +msgid "Notes:" +msgstr "" + +#: ../../../docs/style-guide.md:76 +msgid "Headings use sentence case (\"Adjusting the playbook configuration\", not \"Adjusting The Playbook Configuration\")." +msgstr "" + +#: ../../../docs/style-guide.md:77 +msgid "The \"Adjusting the playbook configuration\" section tells people to add configuration to their `inventory/host_vars/matrix.example.com/vars.yml` file and shows a minimal `yaml` example." +msgstr "" + +#: ../../../docs/style-guide.md:78 +msgid "The \"Installing\" section references [playbook tags](playbook-tags.md) and shows the `just` command or `ansible-playbook` invocation to run." +msgstr "" + +#: ../../../docs/style-guide.md:79 +msgid "Look at an existing page for a similar component (another bridge, bot, or service) and copy its structure. The mautrix bridge pages share common sections via [Setting up a Generic Mautrix Bridge](configuring-playbook-bridge-mautrix-bridges.md), so bridge pages link there instead of repeating the shared content." +msgstr "" + +#: ../../../docs/style-guide.md:81 +msgid "Adding a new component" +msgstr "" + +#: ../../../docs/style-guide.md:83 +msgid "First, consider where the component belongs:" +msgstr "" + +#: ../../../docs/style-guide.md:85 +msgid "Matrix-specific components are developed as roles in this repository, under `roles/custom/`." +msgstr "" + +#: ../../../docs/style-guide.md:86 +msgid "Components that are not Matrix-specific should live as external roles, preferably in the [MASH organization](https://github.com/mother-of-all-self-hosting/), and get wired into the playbook via `requirements.yml`." +msgstr "" + +#: ../../../docs/style-guide.md:87 +msgid "For components that are not Matrix-specific, also consider whether they belong in this Matrix playbook at all, or rather in [mash-playbook](https://github.com/mother-of-all-self-hosting/mash-playbook). Certain components (like Grafana or backup tools) are suitable for both playbooks. If something is too far away from general usefulness on a Matrix server, we prefer not to include it here, and to only have it in mash-playbook." +msgstr "" + +#: ../../../docs/style-guide.md:89 +msgid "Besides the role itself and its documentation page, a new component touches a few other places. Make sure a pull request adding one covers all of them:" +msgstr "" + +#: ../../../docs/style-guide.md:91 +msgid "The role, in `roles/custom/matrix-/` (or an external role wired via `requirements.yml`, as described above)." +msgstr "" + +#: ../../../docs/style-guide.md:92 +msgid "Role registration in `setup.yml`." +msgstr "" + +#: ../../../docs/style-guide.md:93 +msgid "Wiring in `group_vars/matrix_servers`. Wire the component to the rest of the playbook there (referencing variables of other roles), but keep values that the role can construct by itself in the role's own `defaults/main.yml`." +msgstr "" + +#: ../../../docs/style-guide.md:94 +msgid "The documentation page, `docs/configuring-playbook-.md`, linked from the table of contents in `docs/README.md`." +msgstr "" + +#: ../../../docs/style-guide.md:95 +msgid "An entry in the supported services list in `README.md`." +msgstr "" + +#: ../../../docs/style-guide.md:96 +msgid "A row in `docs/container-images.md`, if the component runs a container." +msgstr "" + +#: ../../../docs/style-guide.md:97 +msgid "A `CHANGELOG.md` entry announcing the new component." +msgstr "" + +#: ../../../docs/style-guide.md:98 +msgid "License headers: every new file carries `SPDX-FileCopyrightText` and `SPDX-License-Identifier` comments, as this project follows the [REUSE](https://reuse.software/) specification." +msgstr "" + +#: ../../../docs/style-guide.md:100 +msgid "Variable naming conventions:" +msgstr "" + +#: ../../../docs/style-guide.md:102 +msgid "The variable prefix matches the role directory name: the `matrix-bridge-mautrix-telegram` role uses `matrix_bridge_mautrix_telegram_*` variables, the `matrix-bot-mjolnir` role uses `matrix_bot_mjolnir_*` variables, and so on." +msgstr "" + +#: ../../../docs/style-guide.md:103 +msgid "List-type variables that the playbook may extend automatically follow the `_auto` + `_custom` split: the main variable combines an `_auto` component (managed by the playbook via `group_vars`) and a `_custom` component (reserved for users). Where it makes sense, there is also a `_default` component, containing sensible defaults provided by the role itself. See `matrix_bridge_hookshot_container_additional_networks` and `matrix_bridge_hookshot_systemd_required_services_list` for examples." +msgstr "" + +#: ../../../docs/style-guide.md:104 +msgid "When a variable is renamed or removed, deprecate it so that people with stale configuration get told about it instead of it being silently ignored. Each role deprecates its own variables, in its `validate_config.yml` tasks. The `matrix_playbook_migration` role handles the cases a role cannot: variables of completely eliminated roles (which no longer have their own `validate_config.yml`), and validation that needs to run very early for some reason." +msgstr "" + +#: ../../../docs/style-guide.md:105 +msgid "For breaking changes that require the user's attention (beyond a renamed variable that validation already catches), bump `matrix_playbook_migration_expected_version` and add a matching entry to the `matrix_playbook_migration_breaking_changes` list (a summary and a `CHANGELOG.md` link), in `roles/custom/matrix_playbook_migration/defaults/main.yml`. Users declare `matrix_playbook_migration_validated_version` in their configuration, and the playbook walks them through all breaking changes between their validated version and the expected one. Also update the recommended value in `examples/vars.yml`; a pre-commit check enforces that it matches the expected version." +msgstr "" diff --git a/i18n/translation-templates/docs/uninstalling.pot b/i18n/translation-templates/docs/uninstalling.pot index c41f1ebd1..dea4d87a4 100644 --- a/i18n/translation-templates/docs/uninstalling.pot +++ b/i18n/translation-templates/docs/uninstalling.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: matrix-docker-ansible-deploy \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-02-13 10:32+0000\n" +"POT-Creation-Date: 2026-05-19 07:40+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -20,10 +20,6 @@ msgstr "" msgid "Uninstalling" msgstr "" -#: ../../../docs/uninstalling.md:11 -msgid "[!WARNING]" -msgstr "" - #: ../../../docs/uninstalling.md:12 msgid "If your server federates with others, make sure to **leave any federated rooms before nuking your Matrix server's data**. Otherwise, the next time you set up a Matrix server for this domain (regardless of the installation method you use), you'll encounter trouble federating." msgstr "" diff --git a/jitsi_jvb.yml b/jitsi_jvb.yml index d57c15a97..cd05ece62 100644 --- a/jitsi_jvb.yml +++ b/jitsi_jvb.yml @@ -11,11 +11,11 @@ become: true roles: - - role: galaxy/com.devture.ansible.role.playbook_help - - role: galaxy/com.devture.ansible.role.systemd_docker_base + - role: galaxy/playbook_help + - role: galaxy/systemd_docker_base - when: matrix_playbook_docker_installation_enabled | bool - role: galaxy/geerlingguy.docker + role: galaxy/docker vars: docker_install_compose: false tags: @@ -26,7 +26,7 @@ - install-all - when: devture_docker_sdk_for_python_installation_enabled | bool - role: galaxy/com.devture.ansible.role.docker_sdk_for_python + role: galaxy/docker_sdk_for_python tags: - setup-docker - setup-all @@ -39,4 +39,4 @@ - custom/matrix-common-after - when: devture_systemd_service_manager_enabled | bool - role: galaxy/com.devture.ansible.role.systemd_service_manager + role: galaxy/systemd_service_manager diff --git a/justfile b/justfile index b92a8a52f..27a357b45 100644 --- a/justfile +++ b/justfile @@ -13,15 +13,19 @@ prek_home := env("PREK_HOME", justfile_directory() / "var/prek") default: @{{ just_executable() }} --list --justfile "{{ justfile() }}" +# Adds a new host to the inventory, creating the inventory files if necessary (e.g. `just add-inventory-host example.com 1.2.3.4`) +add-inventory-host domain server_address: + @{{ justfile_directory() }}/bin/add-inventory-host.sh {{ quote(domain) }} {{ quote(server_address) }} + # Pulls external Ansible roles roles: #!/usr/bin/env sh echo "[NOTE] This command just updates the roles, but if you want to update everything at once (playbook, roles, etc.) - use 'just update'" if [ -x "$(command -v agru)" ]; then - agru + agru -no-tui else - rm -rf roles/galaxy - ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force + rm -rf roles/galaxy + ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force fi # Updates the playbook and installs the necessary Ansible roles pinned in requirements.yml. If a -u flag is passed, also updates the requirements.yml file with new role versions (if available) @@ -29,7 +33,7 @@ update *flags: update-playbook-only #!/usr/bin/env sh if [ -x "$(command -v agru)" ]; then echo {{ if flags == "" { "Installing roles pinned in requirements.yml…" } else { if flags == "-u" { "Updating roles and pinning new versions in requirements.yml…" } else { "Unknown flags passed" } } }} - agru {{ flags }} + agru -no-tui {{ flags }} else echo "[NOTE] You are using the standard ansible-galaxy tool to install roles, which is slow and lacks other features. We recommend installing the 'agru' tool to speed up the process: https://github.com/etkecc/agru#where-to-get" echo "Installing roles…" @@ -70,13 +74,28 @@ prek-install-git-pre-commit-hook: _ensure_mise_tools_installed #!/usr/bin/env sh set -eu {{ just_executable() }} --justfile "{{ justfile() }}" mise exec -- prek install - hook="{{ justfile_directory() }}/.git/hooks/pre-commit" - # The installed git hook runs later under Git, outside this just/mise environment. - # Injecting PREK_HOME keeps prek's cache under var/prek instead of a global home dir, - # which is more predictable and works better in sandboxed tools like Codex/OpenCode. - if [ -f "$hook" ] && ! grep -q '^export PREK_HOME=' "$hook"; then - sed -i '2iexport PREK_HOME="{{ prek_home }}"' "$hook" - fi + # The installed git hooks run later under Git, outside this just/mise environment, + # so they need to be told how to find their tooling: + # + # - PREK_HOME keeps prek's cache under var/prek instead of a global home dir. + # - MISE_DATA_DIR / MISE_TRUSTED_CONFIG_PATHS make mise resolve against this project's + # own data directory. Without them mise falls back to the global one and silently + # installs a second copy of the tool there. + # - prek bakes the full path of the currently installed version into the hook + # (var/mise/installs/prek//...), which stops working as soon as the pinned + # version changes or old versions are pruned. Pointing at mise's shim instead makes + # the hook resolve whatever mise.toml pins, at the time it runs. + # + # Which hook files prek installs depends on `default_install_hook_types` in + # .pre-commit-config.yaml, so patch every hook file that prek generated. + for hook in "{{ justfile_directory() }}"/.git/hooks/*; do + [ -f "$hook" ] || continue + grep -q 'generated by prek' "$hook" || continue + grep -q '^export PREK_HOME=' "$hook" || sed -i '2iexport PREK_HOME="{{ prek_home }}"' "$hook" + grep -q '^export MISE_DATA_DIR=' "$hook" || sed -i '3iexport MISE_DATA_DIR="{{ mise_data_dir }}"' "$hook" + grep -q '^export MISE_TRUSTED_CONFIG_PATHS=' "$hook" || sed -i '4iexport MISE_TRUSTED_CONFIG_PATHS="{{ mise_trusted_config_paths }}"' "$hook" + sed -i 's#^PREK=".*"$#PREK="{{ mise_data_dir }}/shims/prek"#' "$hook" + done # Runs the playbook with --tags=install-all,ensure-matrix-users-created,start and optional arguments install-all *extra_args: (run-tags "install-all,ensure-matrix-users-created,start" extra_args) @@ -116,9 +135,13 @@ stop-all *extra_args: (run-tags "stop-all" extra_args) stop-group group *extra_args: @{{ just_executable() }} --justfile "{{ justfile() }}" run-tags stop-group --extra-vars="group={{ group }}" {{ extra_args }} -# Rebuilds the mautrix-meta-instagram Ansible role using the mautrix-meta-messenger role as a source -rebuild-mautrix-meta-instagram: - /bin/bash "{{ justfile_directory() }}/bin/rebuild-mautrix-meta-instagram.sh" "{{ justfile_directory() }}/roles/custom" +# Runs a role's Molecule scenario locally (no argument lists the roles that have one) +molecule *args: + @{{ justfile_directory() }}/bin/molecule.sh {{ args }} + +# Removes the Molecule virtualenv and per-role Ansible homes from var/ +molecule-clean *args: + @{{ justfile_directory() }}/bin/molecule-clean.sh {{ args }} # Internal - ensures var/mise and var/prek directories exist _ensure_mise_data_directory: diff --git a/mise.toml b/mise.toml index 00cee20f2..8822ebb19 100644 --- a/mise.toml +++ b/mise.toml @@ -3,7 +3,4 @@ # SPDX-License-Identifier: AGPL-3.0-or-later [tools] -prek = "0.3.2" - -[settings] -yes = true +prek = "0.5.2" diff --git a/molecule-shared/homeserver-stub.py b/molecule-shared/homeserver-stub.py new file mode 100644 index 000000000..16477e048 --- /dev/null +++ b/molecule-shared/homeserver-stub.py @@ -0,0 +1,203 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +"""A stand-in homeserver for Molecule scenarios. + +Most components talk to a homeserver while starting up and exit if it is unreachable, +so a scenario cannot get them running without one. A real Synapse for every role would +dominate the run time and drag in Postgres, and the scenarios are not testing Synapse. + +This answers the handful of endpoints components touch during startup, with the blandest +plausible response in each case. Deliberately permissive: an unknown path returns `{}` with +a 200 rather than a 404, because the goal is to get the component past its startup checks. + +What it is NOT: an authentication check, a room state machine, or anything a scenario should +assert *about*. Assert on what the role rendered and what the component reports about itself. +Scenarios may supply a small static room-state fixture when startup requires it, but the stub +does not model state changes. +""" + +import json +import os +import re +import sys +import time +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from urllib.parse import parse_qs, unquote, urlparse + +SERVER_NAME = os.environ.get("STUB_SERVER_NAME", "molecule.local") +PORT = int(os.environ.get("STUB_PORT", "8008")) + +# Rooms reported as already joined. Components that resolve a room mapping at startup +# (matrix-alertmanager-receiver, for one) fail if the rooms they were configured with +# are missing, so a scenario passes its own room IDs in. +JOINED_ROOMS = [r for r in os.environ.get("STUB_JOINED_ROOMS", "").split(",") if r] + +USER_ID = os.environ.get("STUB_USER_ID", f"@stub:{SERVER_NAME}") +ROOM_STATE = json.loads(os.environ.get("STUB_ROOM_STATE", "[]")) + +# Longest a /sync call is held open. Long-polling clients ask for a 30s timeout and +# immediately ask again when the call returns, so answering instantly spins them into a hot +# loop that eats the test machine. Honouring the requested timeout, capped here, keeps an +# idle bot idle. +SYNC_MAX_HOLD_SECONDS = 30 + + +class Handler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" + + def _send(self, payload, status=200): + body = json.dumps(payload).encode() + self.send_response(status) + self.send_header("Content-Type", "application/json") + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + + def _route(self): + parsed = urlparse(self.path) + path = parsed.path + + # A client that syncs (every bot here does) needs a `next_batch` back or + # the response will not deserialize, and it needs the call to block for + # the timeout it asked for or it will hammer this stub. Nothing is ever + # reported: an idle bot is what a scenario wants. + if path.endswith("/sync"): + requested_ms = parse_qs(parsed.query).get("timeout", ["0"])[0] + try: + hold = min(int(requested_ms) / 1000.0, SYNC_MAX_HOLD_SECONDS) + except ValueError: + hold = 0 + if hold > 0: + time.sleep(hold) + return {"next_batch": "molecule-stub-batch"} + + # Before the generic `/upload` below: this one is the end-to-end + # encryption key upload, and the client insists on the key counts. + if path.endswith("/keys/upload"): + return {"one_time_key_counts": {}} + + # Media. A bot that sets its own avatar asks for the upload limits first + # and refuses to proceed without them, then uploads and expects an MXC + # URI back. + if path.endswith("/media/config") or path.endswith("/media/v3/config"): + return {"m.upload.size": 10485760} + + if path.endswith("/upload"): + return {"content_uri": f"mxc://{SERVER_NAME}/molecule-stub-media"} + + # Sync filters are uploaded before the first sync and referenced by id. + if path.endswith("/filter"): + return {"filter_id": "molecule-stub-filter"} + + if path.endswith("/joined_rooms"): + return {"joined_rooms": JOINED_ROOMS} + + if path.endswith("/whoami"): + return {"user_id": USER_ID, "device_id": "STUBDEVICE"} + + if path.endswith("/versions"): + return { + "versions": ["v1.1", "v1.2", "v1.3", "v1.4", "v1.5", "v1.6"], + "unstable_features": {}, + } + + if path.endswith("/capabilities"): + return {"capabilities": {}} + + # Where bots authenticating with a username and password log in, rather than as an + # appservice with a token. Matched loosely on purpose, because clients differ on the + # API version prefix, and a login falling through to the catch-all `{}` below looks + # to the client like bad credentials. + if path.endswith("/login"): + return { + "user_id": USER_ID, + "access_token": "stub_access_token", + "device_id": "STUBDEVICE", + "home_server": SERVER_NAME, + } + + if path.endswith("/createRoom"): + return {"room_id": f"!stub-room:{SERVER_NAME}"} + + join_match = re.search(r"/join/([^/]+)$", path) + if join_match: + return {"room_id": unquote(join_match.group(1))} + + if re.search(r"/rooms/[^/]+/join$", path) or path.endswith("/join"): + return {"room_id": f"!stub-room:{SERVER_NAME}"} + + if "/send/" in path or "/state/" in path: + return {"event_id": f"$stub-event:{SERVER_NAME}"} + + if path.endswith("/register"): + return { + "user_id": USER_ID, + "access_token": "stub_access_token", + "device_id": "STUBDEVICE", + "home_server": SERVER_NAME, + } + + if path.endswith("/profile") or "/profile/" in path: + return {"displayname": "stub"} + + if path.startswith("/_matrix/key/"): + return {"server_name": SERVER_NAME, "verify_keys": {}, "old_verify_keys": {}} + + if path.startswith("/.well-known/matrix/client"): + return {"m.homeserver": {"base_url": f"http://{SERVER_NAME}:{PORT}"}} + + if path.startswith("/.well-known/matrix/server"): + return {"m.server": f"{SERVER_NAME}:{PORT}"} + + if path.endswith("/health") or path.endswith("/_matrix/federation/v1/version"): + return {"server": {"name": "molecule-stub", "version": "0"}} + + # Anything unrecognised: an empty object, so a component probing an endpoint + # not listed here still gets past it. + return {} + + def do_GET(self): + path = urlparse(self.path).path + + if ROOM_STATE: + if re.search(r"/rooms/[^/]+/state$", path): + self._send(ROOM_STATE) + return + + if "/account_data/" in path or re.search( + r"/rooms/[^/]+/state/[^/]+(?:/[^/]+)?$", path + ): + self._send( + { + "errcode": "M_NOT_FOUND", + "error": "Molecule stub state not found", + }, + status=404, + ) + return + + self._send(self._route()) + + def do_POST(self): + length = int(self.headers.get("Content-Length") or 0) + if length: + self.rfile.read(length) + self._send(self._route()) + + def do_PUT(self): + self.do_POST() + + def do_DELETE(self): + self._send({}) + + def log_message(self, fmt, *args): + # Quiet by default. STUB_VERBOSE=1 when a scenario will not start and you need + # to see what the component is actually asking for. + if os.environ.get("STUB_VERBOSE"): + sys.stderr.write("stub: " + (fmt % args) + "\n") + + +if __name__ == "__main__": + ThreadingHTTPServer(("0.0.0.0", PORT), Handler).serve_forever() diff --git a/molecule-shared/homeserver-stub.py.license b/molecule-shared/homeserver-stub.py.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/molecule-shared/homeserver-stub.py.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/molecule-shared/playbook-context.yml b/molecule-shared/playbook-context.yml new file mode 100644 index 000000000..9de5262e9 --- /dev/null +++ b/molecule-shared/playbook-context.yml @@ -0,0 +1,83 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# The variables a role reads from its surroundings rather than from its own defaults. +# In a real run `matrix-base` and `group_vars/matrix_servers` provide them. +# +# Include from a scenario's prepare.yml, converge.yml and verify.yml: +# +# vars_files: +# - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" +# +# Gotcha: `vars_files` outranks inventory `group_vars`, so a scenario cannot override these there. +# +# Keep this to variables that come from OUTSIDE the role under test. +# Anything the role defines itself belongs in the scenario. + +# --- Identity and paths (matrix-base) -------------------------------------- + +matrix_base_data_path: /matrix +matrix_domain: molecule.local + +matrix_user_name: matrix +matrix_group_name: matrix + +# Deliberately not 1000: the base images already have a user there, so a distinct id +# is what proves a role used the one it was given rather than coinciding with the image's own. +matrix_user_uid: 1234 +matrix_user_gid: 1234 + +# Empty in the playbook's own defaults too. Components that would invite an administrator +# into a room skip doing so when it is empty. +matrix_admin: '' + +# --- Host commands (matrix-base) ------------------------------------------- + +# Some roles shell out through this indirection instead of naming the binary directly +# (matrix-bridge-hookshot and matrix-bridge-appservice-irc both generate a key with it). +# They install it themselves by including matrix-base's `ensure_openssl_installed` tasks. +matrix_host_command_openssl: "/usr/bin/env openssl" + +# Used by homeserver systemd units for startup delays and post-start health checks. +matrix_host_command_sleep: "/usr/bin/env sleep" + +# --- Bridge-wide switches (matrix-base) ------------------------------------ + +# Every bridge role reads these, so they live here rather than in each bridge's scenario. +# The values match the playbook's own defaults. A scenario proving one of these reaches +# the rendered configuration should override it in its own group_vars. + +matrix_bridges_encryption_enabled: false +matrix_bridges_encryption_default: false +matrix_bridges_msc4190_enabled: false +matrix_bridges_self_sign_enabled: false +matrix_bridges_relay_enabled: false + +matrix_bridges_exposure_enabled: true +matrix_bridges_exposure_hostname: molecule.local +matrix_bridges_exposure_path_prefix: /bridges + +# --- Public hostnames (matrix-base) ---------------------------------------- + +# 18 of the roles here read one of these. Rendered against the scenario's matrix_domain +# rather than left as Jinja, so verify.yml can read them without the role's defaults in scope. + +matrix_server_fqn_matrix: matrix.molecule.local +matrix_server_fqn_matrix_federation: matrix.molecule.local +matrix_server_fqn_element: element.molecule.local +matrix_server_fqn_hydrogen: hydrogen.molecule.local +matrix_server_fqn_cinny: cinny.molecule.local +matrix_server_fqn_sable: sable.molecule.local +matrix_server_fqn_schildichat: schildichat.molecule.local +matrix_server_fqn_fluffychat: fluffychat.molecule.local +matrix_server_fqn_buscarron: buscarron.molecule.local +matrix_server_fqn_etherpad: etherpad.molecule.local +matrix_server_fqn_jitsi: jitsi.molecule.local +matrix_server_fqn_grafana: stats.molecule.local +matrix_server_fqn_sygnal: sygnal.molecule.local +matrix_server_fqn_mautrix_wsproxy: wsproxy.molecule.local +matrix_server_fqn_ntfy: ntfy.molecule.local +matrix_server_fqn_rageshake: rageshake.molecule.local +matrix_server_fqn_matrixto: mt.molecule.local diff --git a/molecule-shared/playbook-context.yml.license b/molecule-shared/playbook-context.yml.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/molecule-shared/playbook-context.yml.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/molecule-shared/requirements.txt b/molecule-shared/requirements.txt new file mode 100644 index 000000000..f84689c24 --- /dev/null +++ b/molecule-shared/requirements.txt @@ -0,0 +1,4 @@ +ansible==14.3.1 +molecule==26.8.0 +molecule-plugins==26.7.15 +docker==7.2.0 diff --git a/molecule-shared/requirements.txt.license b/molecule-shared/requirements.txt.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/molecule-shared/requirements.txt.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/molecule-shared/requirements.yml b/molecule-shared/requirements.yml new file mode 100644 index 000000000..4e721acca --- /dev/null +++ b/molecule-shared/requirements.yml @@ -0,0 +1,21 @@ +--- +# Shared by every role scenario, so the pins cannot drift apart across roles. +roles: + - name: ansible-role-docker + src: https://github.com/geerlingguy/ansible-role-docker + scm: git + version: 8.0.0 + + - name: com.devture.ansible.role.playbook_help + src: https://github.com/devture/com.devture.ansible.role.playbook_help + scm: git + version: main + + - name: com.devture.ansible.role.systemd_docker_base + src: https://github.com/devture/com.devture.ansible.role.systemd_docker_base + scm: git + version: v1.5.0-0 + +collections: + - name: community.docker + version: 5.2.2 diff --git a/molecule-shared/requirements.yml.license b/molecule-shared/requirements.yml.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/molecule-shared/requirements.yml.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/molecule-shared/tasks/homeserver-stub.yml b/molecule-shared/tasks/homeserver-stub.yml new file mode 100644 index 000000000..03d4dc063 --- /dev/null +++ b/molecule-shared/tasks/homeserver-stub.yml @@ -0,0 +1,87 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Stands up a stand-in homeserver on a container network, for scenarios whose component +# contacts a homeserver while starting up. +# +# Include from a scenario's prepare.yml: +# +# - name: Ensure the homeserver stub is running +# ansible.builtin.include_tasks: +# file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" +# vars: +# molecule_shared_stub_network: "{{ _container_network }}" +# molecule_shared_stub_joined_rooms: ["!some-room:molecule.local"] +# +# The component should then be pointed at http://matrix.molecule.local:8008. +# +# See molecule-shared/homeserver-stub.py for what it answers and, more importantly, what it is not. + +- name: Ensure the homeserver stub script is present + ansible.builtin.copy: + src: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/homeserver-stub.py" + dest: /root/molecule-homeserver-stub.py + mode: "0755" + +- name: Ensure a previous homeserver stub is gone + ansible.builtin.command: + argv: + - docker + - rm + - --force + - "{{ molecule_shared_stub_name | default('matrix-homeserver-stub') }}" + register: molecule_shared_stub_removal + changed_when: molecule_shared_stub_removal.rc == 0 + failed_when: false + +# The alias is what the component resolves, so its configuration can name a hostname +# rather than a container name. +- name: Ensure the homeserver stub is running + ansible.builtin.command: + argv: + - docker + - run + - --detach + - --name={{ molecule_shared_stub_name | default('matrix-homeserver-stub') }} + - --network={{ molecule_shared_stub_network }} + - --network-alias={{ molecule_shared_stub_hostname | default('matrix.molecule.local') }} + - --env=STUB_SERVER_NAME={{ molecule_shared_stub_server_name | default('molecule.local') }} + - --env=STUB_JOINED_ROOMS={{ (molecule_shared_stub_joined_rooms | default([])) | join(',') }} + # Appservices call /whoami on startup and refuse to run if the id returned is not + # the bot user they were configured as, so a scenario bridging anything has to tell + # the stub who it should claim to be. + - --env=STUB_USER_ID={{ molecule_shared_stub_user_id | default('@stub:' + (molecule_shared_stub_server_name | default('molecule.local'))) }} + # Some components need to inspect an existing management room before they can start. + # This optional static fixture does not attempt to model subsequent state changes. + - --env=STUB_ROOM_STATE={{ (molecule_shared_stub_room_state | default([])) | to_json }} + # Set molecule_shared_stub_verbose to "1" to log every request the stub is asked for. + # How you find out why a component will not start, and for a component with no port of + # its own, the only place to observe it acting on what the role configured. + - --env=STUB_VERBOSE={{ molecule_shared_stub_verbose | default('') }} + - --volume=/root/molecule-homeserver-stub.py:/stub.py:ro + - "{{ molecule_shared_image_python }}" + - python3 + - /stub.py + register: molecule_shared_stub_start + changed_when: molecule_shared_stub_start.rc == 0 + +- name: Wait for the homeserver stub to answer + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ molecule_shared_stub_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --fail + - --max-time + - "5" + - "http://{{ molecule_shared_stub_hostname | default('matrix.molecule.local') }}:8008/_matrix/client/versions" + register: molecule_shared_stub_ready + changed_when: false + until: molecule_shared_stub_ready.rc == 0 + retries: 12 + delay: 5 diff --git a/molecule-shared/tasks/postgres.yml b/molecule-shared/tasks/postgres.yml new file mode 100644 index 000000000..96bef15a2 --- /dev/null +++ b/molecule-shared/tasks/postgres.yml @@ -0,0 +1,78 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Stands up Postgres on a container network, for scenarios whose role has a database. +# +# Include from a scenario's prepare.yml: +# +# - name: Ensure Postgres is running +# ansible.builtin.include_tasks: +# file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" +# vars: +# molecule_shared_postgres_network: "{{ _container_network }}" +# molecule_shared_postgres_database: matrix_ +# molecule_shared_postgres_username: matrix_ +# molecule_shared_postgres_password: +# +# The role should then be pointed at it with its own `_database_engine: postgres` and +# `_database_hostname: matrix-postgres-molecule` (or whatever hostname is passed here). +# +# This is what the playbook does in a real run: `group_vars/matrix_servers` selects postgres +# whenever postgres is enabled, which is the default. sqlite is the path almost nobody uses. + +- name: Ensure a previous Postgres is gone + ansible.builtin.command: + argv: + - docker + - rm + - --force + - "{{ molecule_shared_postgres_name | default('matrix-postgres-molecule') }}" + register: molecule_shared_postgres_removal + changed_when: molecule_shared_postgres_removal.rc == 0 + failed_when: false + +- name: Ensure Postgres is running + ansible.builtin.command: + argv: + - docker + - run + - --detach + - --name={{ molecule_shared_postgres_name | default('matrix-postgres-molecule') }} + - --network={{ molecule_shared_postgres_network }} + - --network-alias={{ molecule_shared_postgres_hostname | default('matrix-postgres-molecule') }} + - --env=POSTGRES_DB={{ molecule_shared_postgres_database }} + - --env=POSTGRES_USER={{ molecule_shared_postgres_username }} + - --env=POSTGRES_PASSWORD={{ molecule_shared_postgres_password }} + # PGDATA is set explicitly, and to /data rather than anywhere under + # /var/lib/postgresql, for the same reasons the postgres role does it: v18 changed the + # default to a versioned subdirectory, and /var/lib/postgresql is a VOLUME in the image, + # so nothing can be mounted beneath it. Setting it explicitly also means a future image + # changing its own default cannot move the data out from under this. + # + # A tmpfs, because the database is thrown away with the container and not writing it to + # the overlay filesystem is faster. + - --env=PGDATA=/data + - --tmpfs=/data + - "{{ molecule_shared_image_postgres }}" + register: molecule_shared_postgres_start + changed_when: molecule_shared_postgres_start.rc == 0 + +# `pg_isready` needs the username: it defaults to the OS user of whoever runs it, which inside +# this container is `postgres` and may not be the role the scenario created. +- name: Wait for Postgres to accept connections + ansible.builtin.command: + argv: + - docker + - exec + - "{{ molecule_shared_postgres_name | default('matrix-postgres-molecule') }}" + - pg_isready + - --username={{ molecule_shared_postgres_username }} + - --dbname={{ molecule_shared_postgres_database }} + - --quiet + register: molecule_shared_postgres_ready + changed_when: false + until: molecule_shared_postgres_ready.rc == 0 + retries: 30 + delay: 2 diff --git a/molecule-shared/vars.yml b/molecule-shared/vars.yml new file mode 100644 index 000000000..269edcb47 --- /dev/null +++ b/molecule-shared/vars.yml @@ -0,0 +1,22 @@ +--- +# Helper container images the scenarios use for probing. Here rather than inline in each +# verify.yml, so there is one pin per image instead of one per role, and so Renovate can see +# them. See the customManager in .github/renovate.json. + +# Used to reach a role's container over its own container network, because the role publishes +# no host port - exactly as in a real deployment. Publishing one for the test would collide +# between scenarios running in parallel. +# renovate: datasource=docker depName=docker.io/curlimages/curl +molecule_shared_image_curl: "docker.io/curlimages/curl:8.22.0" + +# Used for small stub services (a fake homeserver, and so on). +# renovate: datasource=docker depName=docker.io/library/python +molecule_shared_image_python: "docker.io/library/python:3.14-alpine" + +# Postgres for scenarios whose role has a database. Pinned at the major the postgres role +# deploys to new installations, and left to Renovate from there: when a new major lands, +# the PR bumping this pin runs every scenario against it, which is the earliest warning we +# get that a component does not cope. Users who upgrade Postgres promptly are on that major +# well before the postgres role makes it the default for new installations. +# renovate: datasource=docker depName=docker.io/library/postgres +molecule_shared_image_postgres: "docker.io/library/postgres:18.6-alpine" diff --git a/molecule-shared/vars.yml.license b/molecule-shared/vars.yml.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/molecule-shared/vars.yml.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/requirements.yml b/requirements.yml index 5ea598704..5876b2a4a 100644 --- a/requirements.yml +++ b/requirements.yml @@ -1,23 +1,23 @@ --- - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-aux.git - version: v1.0.0-6 + version: v2.0.0-0 name: auxiliary - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-backup_borg.git - version: v1.4.3-2.1.3-2 + version: v1.4.5-2.1.7-2 name: backup_borg - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-cinny.git - version: v4.11.1-1 + version: v4.12.6-2 name: cinny - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-container-socket-proxy.git - version: v0.4.2-4 + version: v0.5.0-0 name: container_socket_proxy - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-coturn.git - version: v4.9.0-1 + version: v4.9.0-3 name: coturn activation_prefix: coturn_ - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-ddclient.git - version: v4.0.0-2 + version: v4.0.0-5 name: ddclient activation_prefix: ddclient_ - src: git+https://github.com/geerlingguy/ansible-role-docker @@ -27,28 +27,28 @@ version: 542a2d68db4e9a8e9bb4b508052760b900c7dce6 name: docker_sdk_for_python - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-etherpad.git - version: v2.6.1-3 + version: v3.3.3-2 name: etherpad - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-exim-relay.git - version: v4.99.1-r0-2-0 + version: v4.99.1-r0-2-3 name: exim_relay - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-grafana.git - version: v11.6.5-9 + version: v13.0.2-2 name: grafana - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-hydrogen.git - version: v0.5.1-2 + version: v0.5.1-7 name: hydrogen - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-jitsi.git - version: v10741-2 + version: v11146-2-1 name: jitsi - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-livekit-server.git - version: v1.9.12-1 + version: v1.13.6-0 name: livekit_server - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-ntfy.git - version: v2.20.1-0 + version: v2.28.0-0 name: ntfy - src: git+https://github.com/devture/com.devture.ansible.role.playbook_help.git - version: ea8c5cc750c4e23d004c9a836dfd9eda82d45ff4 + version: 717de2c7fb03f8124abc2beeb34980305f723f33 name: playbook_help - src: git+https://github.com/devture/com.devture.ansible.role.playbook_runtime_messages.git version: 9b4b088c62b528b73a9a7c93d3109b091dd42ec6 @@ -57,41 +57,41 @@ version: dd6e15246b7a9a2d921e0b3f9cd8a4a917a1bb2f name: playbook_state_preserver - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-postgres.git - version: v18.3-4 + version: v18.6-1 name: postgres - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-postgres-backup.git - version: v18-2 + version: v18-4 name: postgres_backup - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-prometheus.git - version: v3.10.0-1 + version: v3.14.0-0 name: prometheus - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-nginxlog-exporter.git - version: v1.10.0-2 + version: v1.11.0-0 name: prometheus_nginxlog_exporter - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-node-exporter.git - version: v1.10.2-0 + version: v1.12.1-1 name: prometheus_node_exporter - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-prometheus-postgres-exporter.git - version: v0.19.1-3 + version: v0.20.1-1 name: prometheus_postgres_exporter - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-sable.git - version: v1.6.0-3 + version: v1.21.0-2 name: sable - src: git+https://github.com/devture/com.devture.ansible.role.systemd_docker_base.git version: v1.5.0-0 name: systemd_docker_base - src: git+https://github.com/devture/com.devture.ansible.role.systemd_service_manager.git - version: v3.2.0-0 + version: v3.2.1-0 name: systemd_service_manager - src: git+https://github.com/devture/com.devture.ansible.role.timesync.git version: v1.1.0-1 name: timesync - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-traefik.git - version: v3.6.12-0 + version: v3.7.12-0 name: traefik - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-traefik-certs-dumper.git - version: v2.10.0-5 + version: v2.11.4-1 name: traefik_certs_dumper - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-valkey.git - version: v9.0.3-3 + version: v9.1.2-0 name: valkey diff --git a/roles/custom/matrix-alertmanager-receiver/defaults/main.yml b/roles/custom/matrix-alertmanager-receiver/defaults/main.yml index 5471e368c..b4beaa076 100644 --- a/roles/custom/matrix-alertmanager-receiver/defaults/main.yml +++ b/roles/custom/matrix-alertmanager-receiver/defaults/main.yml @@ -11,7 +11,7 @@ matrix_alertmanager_receiver_enabled: true # renovate: datasource=docker depName=docker.io/metio/matrix-alertmanager-receiver -matrix_alertmanager_receiver_version: 2026.3.25 +matrix_alertmanager_receiver_version: 2026.8.26 matrix_alertmanager_receiver_scheme: https @@ -32,7 +32,6 @@ matrix_alertmanager_receiver_container_src_path: "{{ matrix_alertmanager_receive matrix_alertmanager_receiver_container_image: "{{ matrix_alertmanager_receiver_container_image_registry_prefix }}metio/matrix-alertmanager-receiver:{{ matrix_alertmanager_receiver_container_image_tag }}" matrix_alertmanager_receiver_container_image_tag: "{{ matrix_alertmanager_receiver_version }}" -matrix_alertmanager_receiver_container_image_force_pull: "{{ matrix_alertmanager_receiver_container_image.endswith(':main') }}" matrix_alertmanager_receiver_container_image_registry_prefix: "{{ matrix_alertmanager_receiver_container_image_registry_prefix_upstream }}" matrix_alertmanager_receiver_container_image_registry_prefix_upstream: "{{ matrix_alertmanager_receiver_container_image_registry_prefix_upstream_default }}" matrix_alertmanager_receiver_container_image_registry_prefix_upstream_default: "docker.io/" diff --git a/roles/custom/matrix-alertmanager-receiver/molecule/default/converge.yml b/roles/custom/matrix-alertmanager-receiver/molecule/default/converge.yml new file mode 100644 index 000000000..0a68b9c97 --- /dev/null +++ b/roles/custom/matrix-alertmanager-receiver/molecule/default/converge.yml @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# The devture base roles carry the variables this role reads, the same way they do when +# the playbook runs. `matrix-base` is deliberately NOT included: it does far more than this +# role needs, and the two variables it would supply are set directly in molecule.yml. +- name: Include roles for matrix-alertmanager-receiver Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-alertmanager-receiver Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +# The role installs the unit but does not start it; in the playbook that is +# `systemd_service_manager`'s job. +- name: Ensure matrix-alertmanager-receiver is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure matrix-alertmanager-receiver systemd service is started + ansible.builtin.systemd_service: + name: matrix-alertmanager-receiver.service + state: started diff --git a/roles/custom/matrix-alertmanager-receiver/molecule/default/molecule.yml b/roles/custom/matrix-alertmanager-receiver/molecule/default/molecule.yml new file mode 100644 index 000000000..27a17a5b4 --- /dev/null +++ b/roles/custom/matrix-alertmanager-receiver/molecule/default/molecule.yml @@ -0,0 +1,74 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-alertmanager-receiver-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_alertmanager_receiver_hostname: alertmanager-receiver.molecule.local + matrix_alertmanager_receiver_path_prefix: / + matrix_alertmanager_receiver_container_network: matrix-alertmanager-receiver-molecule + + # verify.yml runs as its own play, where the role's defaults are out of scope, + # so the paths it reads are pinned here to match what the role derives. + matrix_alertmanager_receiver_base_path: /matrix/alertmanager-receiver + matrix_alertmanager_receiver_config_path: /matrix/alertmanager-receiver/config + + # Traefik is not deployed here, so the labels the role would render for it are + # switched off and their absence is asserted instead. + matrix_alertmanager_receiver_container_labels_traefik_enabled: false + + # Different from the role's own defaults, so verify.yml can tell what the role + # rendered apart from what the application would have done on its own. + matrix_alertmanager_receiver_config_http_port: 12399 + matrix_alertmanager_receiver_config_http_metrics_enabled: true + matrix_alertmanager_receiver_config_http_metrics_path: /molecule-metrics + matrix_alertmanager_receiver_config_http_alerts_path_prefix: /molecule-alerts + + # The homeserver IS reached at startup: the service fetches its joined rooms and + # exits 1 if that fails, so prepare.yml stands up a stub for it. + matrix_alertmanager_receiver_config_matrix_homeserver_url: http://matrix.molecule.local:8008 + matrix_alertmanager_receiver_config_matrix_user_id: "@alertmanager:molecule.local" + matrix_alertmanager_receiver_config_matrix_access_token: molecule_access_token_4f2a91 + matrix_alertmanager_receiver_config_matrix_room_mapping: + molecule-room: "!molecule-room-id:molecule.local" + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-alertmanager-receiver/molecule/default/prepare.yml b/roles/custom/matrix-alertmanager-receiver/molecule/default/prepare.yml new file mode 100644 index 000000000..d3f8a9992 --- /dev/null +++ b/roles/custom/matrix-alertmanager-receiver/molecule/default/prepare.yml @@ -0,0 +1,80 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-alertmanager-receiver Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks set owner/group by name, which Ansible resolves through the + # passwd database, so they have to exist first. `matrix-base` creates them for real. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_alertmanager_receiver_container_network }}" + register: matrix_alertmanager_receiver_molecule_network + changed_when: matrix_alertmanager_receiver_molecule_network.rc == 0 + failed_when: + - matrix_alertmanager_receiver_molecule_network.rc != 0 + - "'already exists' not in matrix_alertmanager_receiver_molecule_network.stderr" + + # The service fetches /_matrix/client/v3/joined_rooms to resolve its room mapping and + # exits 1 if that fails, so a homeserver has to exist for it to come up at all. + # The shared stub is enough. See molecule-shared/homeserver-stub.py. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_alertmanager_receiver_container_network }}" + molecule_shared_stub_joined_rooms: "{{ matrix_alertmanager_receiver_config_matrix_room_mapping.values() | list }}" diff --git a/roles/custom/matrix-alertmanager-receiver/molecule/default/requirements.yml b/roles/custom/matrix-alertmanager-receiver/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-alertmanager-receiver/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-alertmanager-receiver/molecule/default/verify.yml b/roles/custom/matrix-alertmanager-receiver/molecule/default/verify.yml new file mode 100644 index 000000000..0fcc6718f --- /dev/null +++ b/roles/custom/matrix-alertmanager-receiver/molecule/default/verify.yml @@ -0,0 +1,173 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Verify matrix-alertmanager-receiver + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + + tasks: + # Read from the role's own defaults rather than pinned in molecule.yml, so the version + # assertion compares the running image against what defaults/main.yml ships. + # Pinning it here would make that assertion compare the scenario with itself. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_alertmanager_receiver_role_defaults + + - name: Wait for the matrix-alertmanager-receiver service to become active + ansible.builtin.systemd_service: + name: matrix-alertmanager-receiver.service + register: matrix_alertmanager_receiver_service + until: matrix_alertmanager_receiver_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # `Restart=always` means a crash-looping container still reports `active`, so the restart + # counter is checked too. Asserted `is defined` because `| int` turns a missing property + # into 0 and would pass vacuously. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - matrix_alertmanager_receiver_service.status.ActiveState == 'active' + - matrix_alertmanager_receiver_service.status.NRestarts is defined + - matrix_alertmanager_receiver_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-alertmanager-receiver.service is + {{ matrix_alertmanager_receiver_service.status.ActiveState | default('unknown') }} + after {{ matrix_alertmanager_receiver_service.status.NRestarts | default('?') }} + automatic restart(s) + success_msg: "matrix-alertmanager-receiver.service is active and has not restarted" + + # Probed from inside the container network rather than the host, because the role + # publishes no host port - exactly as in a real deployment, where Traefik reaches it + # over the network. + - name: Wait for matrix-alertmanager-receiver to answer on the port the role configured + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_alertmanager_receiver_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - "http://matrix-alertmanager-receiver:{{ matrix_alertmanager_receiver_config_http_port }}{{ matrix_alertmanager_receiver_config_http_metrics_path }}" + register: matrix_alertmanager_receiver_metrics + changed_when: false + until: "'HTTP_STATUS=200' in matrix_alertmanager_receiver_metrics.stdout" + retries: 24 + delay: 5 + failed_when: false + + # Port and metrics path are both non-default here, so a 200 is only reachable if what + # the role rendered is what the process is running on. + - name: Assert the configured port and metrics path reached the process + ansible.builtin.assert: + that: + - "'HTTP_STATUS=200' in matrix_alertmanager_receiver_metrics.stdout" + fail_msg: >- + matrix-alertmanager-receiver did not serve metrics on port + {{ matrix_alertmanager_receiver_config_http_port }} at + {{ matrix_alertmanager_receiver_config_http_metrics_path }} + ({{ matrix_alertmanager_receiver_metrics.stdout | default('no output') }}) + success_msg: >- + matrix-alertmanager-receiver serves metrics on the configured port and path + + - name: Assert the metrics endpoint is really Prometheus metrics + ansible.builtin.assert: + that: + - "'# HELP' in matrix_alertmanager_receiver_metrics.stdout" + fail_msg: >- + The metrics endpoint answered, but did not return Prometheus metrics + success_msg: "The metrics endpoint returns Prometheus metrics" + + # Negative control for the assertion above: the role's own default metrics path must NOT + # answer, or a 200 on the configured path would prove nothing. + - name: Ask for the role's default metrics path, which this scenario moved away from + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_alertmanager_receiver_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - "http://matrix-alertmanager-receiver:{{ matrix_alertmanager_receiver_config_http_port }}/metrics" + register: matrix_alertmanager_receiver_default_path + changed_when: false + failed_when: false + + - name: Assert the default metrics path does not answer + ansible.builtin.assert: + that: + - "'HTTP_STATUS=200' not in matrix_alertmanager_receiver_default_path.stdout" + fail_msg: >- + /metrics answered as well, so serving on + {{ matrix_alertmanager_receiver_config_http_metrics_path }} does not + prove the role's configuration reached the process + ({{ matrix_alertmanager_receiver_default_path.stdout | default('no output') }}) + success_msg: "Only the configured metrics path answers" + + - name: Read the configuration file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_alertmanager_receiver_config_path }}/config.yml" + register: matrix_alertmanager_receiver_config_file + + - name: Assert the rendered configuration carries this scenario's values + ansible.builtin.assert: + that: + - matrix_alertmanager_receiver_config_matrix_user_id in matrix_alertmanager_receiver_config_rendered + - matrix_alertmanager_receiver_config_matrix_access_token in matrix_alertmanager_receiver_config_rendered + - "'molecule-room' in matrix_alertmanager_receiver_config_rendered" + fail_msg: "The rendered configuration does not carry the scenario's Matrix settings" + success_msg: "The rendered configuration carries the scenario's Matrix settings" + vars: + matrix_alertmanager_receiver_config_rendered: "{{ matrix_alertmanager_receiver_config_file.content | b64decode }}" + + - name: Assert the running container is the image the role pins + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-alertmanager-receiver + - --format + - "{{ '{{' }} .Config.Image {{ '}}' }}" + register: matrix_alertmanager_receiver_image + changed_when: false + + - name: Assert the image carries the version defaults/main.yml pins + ansible.builtin.assert: + that: + - matrix_alertmanager_receiver_role_defaults.matrix_alertmanager_receiver_version in matrix_alertmanager_receiver_image.stdout + fail_msg: >- + The running container is {{ matrix_alertmanager_receiver_image.stdout }}, + which does not carry the pinned version {{ matrix_alertmanager_receiver_role_defaults.matrix_alertmanager_receiver_version }} + success_msg: "The running container is the version defaults/main.yml pins" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_alertmanager_receiver_base_path }}/labels" + register: matrix_alertmanager_receiver_labels + + - name: Assert no Traefik labels are emitted while Traefik support is disabled + ansible.builtin.assert: + that: + - "'traefik.' not in (matrix_alertmanager_receiver_labels.content | b64decode)" + fail_msg: >- + Traefik labels were emitted even though + matrix_alertmanager_receiver_container_labels_traefik_enabled is false + success_msg: "No Traefik labels are emitted while Traefik support is disabled" diff --git a/roles/custom/matrix-alertmanager-receiver/tasks/install.yml b/roles/custom/matrix-alertmanager-receiver/tasks/install.yml index d322c244c..ff707c8dc 100644 --- a/roles/custom/matrix-alertmanager-receiver/tasks/install.yml +++ b/roles/custom/matrix-alertmanager-receiver/tasks/install.yml @@ -42,11 +42,9 @@ register: matrix_alertmanager_receiver_support_files_result - name: Ensure matrix-alertmanager-receiver container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_alertmanager_receiver_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_alertmanager_receiver_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_alertmanager_receiver_container_image_force_pull }}" + pull: always when: "not matrix_alertmanager_receiver_container_image_self_build | bool" register: matrix_alertmanager_receiver_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -55,6 +53,15 @@ - when: matrix_alertmanager_receiver_container_image_self_build | bool block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure matrix-alertmanager-receiver repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_alertmanager_receiver_container_src_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure matrix-alertmanager-receiver repository is present on self-build ansible.builtin.git: repo: "{{ matrix_alertmanager_receiver_container_image_self_build_repo }}" @@ -75,6 +82,7 @@ changed_when: true - name: Ensure matrix-alertmanager-receiver container network is created + when: matrix_alertmanager_receiver_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_alertmanager_receiver_container_network }}" diff --git a/roles/custom/matrix-alertmanager-receiver/tasks/validate_config.yml b/roles/custom/matrix-alertmanager-receiver/tasks/validate_config.yml index 55b79d2a0..9ea446103 100644 --- a/roles/custom/matrix-alertmanager-receiver/tasks/validate_config.yml +++ b/roles/custom/matrix-alertmanager-receiver/tasks/validate_config.yml @@ -24,6 +24,7 @@ when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - {'old': 'matrix_alertmanager_receiver_container_image_name_prefix', 'new': 'matrix_alertmanager_receiver_container_image_registry_prefix'} + - {'old': 'matrix_alertmanager_receiver_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - {'old': 'matrix_alertmanager_receiver_config_templating_computed_values', 'new': ' +# SPDX-FileCopyrightText: 2024 - 2026 Catalan Lover # SPDX-FileCopyrightText: 2024 Slavi Pantaleev # SPDX-FileCopyrightText: 2024 Suguru Hirahara # @@ -26,17 +26,25 @@ when: "item.when | bool" - name: Ensure Draupnir Docker image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_appservice_draupnir_for_all_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_appservice_draupnir_for_all_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_appservice_draupnir_for_all_container_image_force_pull }}" + pull: always when: "not matrix_appservice_draupnir_for_all_container_image_self_build | bool" register: matrix_appservice_draupnir_for_all_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_appservice_draupnir_for_all_container_image_pull_result is not failed +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Draupnir repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_appservice_draupnir_for_all_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_appservice_draupnir_for_all_container_image_self_build | bool" + - name: Ensure Draupnir repository is present on self-build ansible.builtin.git: repo: "{{ matrix_appservice_draupnir_for_all_container_image_self_build_repo }}" @@ -49,15 +57,18 @@ when: "matrix_appservice_draupnir_for_all_container_image_self_build | bool" - name: Ensure Draupnir Docker image is built - community.docker.docker_image: + # Using docker_image_build with BuildKit for modern, efficient builds. + # Rebuild when the git checkout advanced to a new commit; otherwise keep the build idempotent. + # Technically the idempotency of rebuilds is more that if a build has already been executed for that name:tag + # then we won't rebuild while in idempotent mode even if git moved. That's what the force rebuild logic is for. + community.docker.docker_image_build: name: "{{ matrix_appservice_draupnir_for_all_container_image }}" - source: build - force_source: "{{ matrix_appservice_draupnir_for_all_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_appservice_draupnir_for_all_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_appservice_draupnir_for_all_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_appservice_draupnir_for_all_git_pull_results.changed | bool else 'never' }}" when: "matrix_appservice_draupnir_for_all_container_image_self_build | bool" + register: matrix_appservice_draupnir_for_all_container_image_build_result - name: Ensure matrix-appservice-draupnir-for-all appservice config installed ansible.builtin.copy: @@ -87,6 +98,7 @@ register: matrix_appservice_draupnir_for_all_registration_config_result - name: Ensure matrix-appservice-draupnir-for-all container network is created + when: matrix_appservice_draupnir_for_all_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_appservice_draupnir_for_all_container_network }}" @@ -100,6 +112,16 @@ mode: '0644' register: matrix_appservice_draupnir_for_all_systemd_service_result +# matrix-appservice-draupnir-for-all and matrix-bot-draupnir share the +# same upstream container image. When both are enabled and force-pull is +# on, the second role to run sees the image as already up-to-date (the +# first role just pulled it), so its pull_result.changed is false and +# conditional restart would skip it. To avoid that, we also treat +# force-pull itself as a restart trigger for this role. The downside is +# that both Draupnir services restart on every run when force-pull is +# enabled (e.g. with rolling tags like `latest` or `main`), even when the +# upstream image has not moved. That is wasteful but acceptable. +# See: https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/5186 - name: Determine whether Draupnir for All needs a restart ansible.builtin.set_fact: matrix_appservice_draupnir_for_all_restart_necessary: >- @@ -110,6 +132,8 @@ or matrix_appservice_draupnir_for_all_registration_config_result.changed | default(false) or matrix_appservice_draupnir_for_all_systemd_service_result.changed | default(false) or matrix_appservice_draupnir_for_all_container_image_pull_result.changed | default(false) + or matrix_appservice_draupnir_for_all_container_image_build_result.changed | default(false) + or matrix_appservice_draupnir_for_all_force_restart | bool }} - name: Ensure matrix-appservice-draupnir-for-all.service restarted, if necessary diff --git a/roles/custom/matrix-appservice-draupnir-for-all/tasks/setup_uninstall.yml b/roles/custom/matrix-appservice-draupnir-for-all/tasks/setup_uninstall.yml index 4ad172539..d52643232 100644 --- a/roles/custom/matrix-appservice-draupnir-for-all/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-appservice-draupnir-for-all/tasks/setup_uninstall.yml @@ -26,5 +26,5 @@ - name: Ensure matrix-appservice-draupnir-for-all paths don't exist ansible.builtin.file: - path: "{{ matrix_bot_draupnir_base_path }}" + path: "{{ matrix_appservice_draupnir_for_all_base_path }}" state: absent diff --git a/roles/custom/matrix-appservice-draupnir-for-all/tasks/validate_config.yml b/roles/custom/matrix-appservice-draupnir-for-all/tasks/validate_config.yml index 5b41a4a75..6383b6487 100644 --- a/roles/custom/matrix-appservice-draupnir-for-all/tasks/validate_config.yml +++ b/roles/custom/matrix-appservice-draupnir-for-all/tasks/validate_config.yml @@ -1,5 +1,5 @@ # SPDX-FileCopyrightText: 2024 MDAD project contributors -# SPDX-FileCopyrightText: 2024 Catalan Lover +# SPDX-FileCopyrightText: 2024 - 2026 Catalan Lover # SPDX-FileCopyrightText: 2024 Slavi Pantaleev # SPDX-FileCopyrightText: 2025 Suguru Hirahara # @@ -23,11 +23,21 @@ - {'old': 'matrix_appservice_draupnir_for_all_docker_image_registry_prefix_upstream', 'new': 'matrix_appservice_draupnir_for_all_container_image_registry_prefix_upstream'} - {'old': 'matrix_appservice_draupnir_for_all_docker_image_registry_prefix_upstream_default', 'new': 'matrix_appservice_draupnir_for_all_container_image_registry_prefix_upstream_default'} - {'old': 'matrix_appservice_draupnir_for_all_docker_src_files_path', 'new': 'matrix_appservice_draupnir_for_all_container_src_files_path'} + - {'old': 'matrix_appservice_draupnir_for_all_container_image_force_pull', 'new': ' (No longer needed due to new docker module doing this natively only if needed.)'} -- name: Fail if required matrix-bot-draupnir variables are undefined +- name: Fail if required matrix-appservice-draupnir-for-all variables are undefined ansible.builtin.fail: - msg: "The `{{ item }}` variable must be defined and have a non-null value." + msg: "The `{{ item.name }}` variable must be defined and have a non-null value." with_items: - - "matrix_appservice_draupnir_for_all_config_adminRoom" - - "matrix_bot_draupnir_container_network" - when: "lookup('vars', item, default='') == '' or lookup('vars', item, default='') is none" + - {'name': 'matrix_appservice_draupnir_for_all_config_adminRoom', when: "{{ not matrix_appservice_draupnir_for_all_zero_touch_deploy }}"} + - {'name': 'matrix_appservice_draupnir_for_all_config_initialManager', when: "{{ matrix_appservice_draupnir_for_all_zero_touch_deploy }}"} + - {'name': 'matrix_appservice_draupnir_for_all_container_network', when: true} + when: "item.when | bool and (lookup('vars', item.name, default='') == '' or lookup('vars', item.name, default='') is none)" + +- name: Fail if inappropriate variables are defined + ansible.builtin.fail: + msg: "The `{{ item.name }}` variable must be undefined or have a null value." + with_items: + - {'name': 'matrix_appservice_draupnir_for_all_config_adminRoom', when: "{{ matrix_appservice_draupnir_for_all_zero_touch_deploy }}"} + - {'name': 'matrix_appservice_draupnir_for_all_config_initialManager', when: "{{ not matrix_appservice_draupnir_for_all_zero_touch_deploy }}"} + when: "item.when | bool and not (lookup('vars', item.name, default='') == '' or lookup('vars', item.name, default='') is none)" diff --git a/roles/custom/matrix-appservice-draupnir-for-all/templates/production-appservice.yaml.j2 b/roles/custom/matrix-appservice-draupnir-for-all/templates/production-appservice.yaml.j2 index ea168dac9..38bce59b9 100644 --- a/roles/custom/matrix-appservice-draupnir-for-all/templates/production-appservice.yaml.j2 +++ b/roles/custom/matrix-appservice-draupnir-for-all/templates/production-appservice.yaml.j2 @@ -1,6 +1,6 @@ {# SPDX-FileCopyrightText: 2024 MDAD project contributors -SPDX-FileCopyrightText: 2024 - 2025 Catalan Lover +SPDX-FileCopyrightText: 2024 - 2026 Catalan Lover SPDX-FileCopyrightText: 2024 Suguru Hirahara SPDX-License-Identifier: AGPL-3.0-or-later @@ -17,9 +17,16 @@ db: engine: "postgres" connectionString: "{{ matrix_appservice_draupnir_for_all_database_connection_string }}" +{% if not matrix_appservice_draupnir_for_all_zero_touch_deploy %} # A room you have created that scopes who can access the appservice. # See docs/access_control.md adminRoom: {{ matrix_appservice_draupnir_for_all_config_adminRoom | to_json }} +{% endif %} + +{% if matrix_appservice_draupnir_for_all_zero_touch_deploy %} +# The initial manager to invite if the admin room has to be created. +initialManager: {{ matrix_appservice_draupnir_for_all_config_initialManager | to_json }} +{% endif %} # This is a web api that the widget connects to in order to interact with the appservice. webAPI: @@ -28,5 +35,14 @@ webAPI: # The directory the bot should store various bits of information in dataPath: "/data" +# Maximum number of bots each user can provision. +# Defaults to 1 when omitted. +maxDraupnirsPerUser: 1 + +# Allow users to self-provision by inviting the appservice bot. +# When false, provisioning must be done through admin commands. +# Defaults to false when omitted. +allowSelfServiceProvisioning: false + roomStateBackingStore: enabled: {{ matrix_appservice_draupnir_for_all_config_roomStateBackingStore_enabled | to_json }} diff --git a/roles/custom/matrix-appservice-draupnir-for-all/templates/production-bots.yaml.j2 b/roles/custom/matrix-appservice-draupnir-for-all/templates/production-bots.yaml.j2 index 63eb20b22..1f78c7746 100644 --- a/roles/custom/matrix-appservice-draupnir-for-all/templates/production-bots.yaml.j2 +++ b/roles/custom/matrix-appservice-draupnir-for-all/templates/production-bots.yaml.j2 @@ -1,6 +1,6 @@ {# SPDX-FileCopyrightText: 2024 MDAD project contributors -SPDX-FileCopyrightText: 2024 - 2025 Catalan Lover +SPDX-FileCopyrightText: 2024 - 2026 Catalan Lover SPDX-License-Identifier: AGPL-3.0-or-later #} @@ -61,6 +61,14 @@ commands: # will address only my_moderator_bot. allowNoPrefix: false + # Controls which symbol will prefix a secondary prefix that is described in additionalPrefixes. + # For example the `!` in `!draupnir`. + # If you wish the bot to use "slash commands" with the "/" character instead of the exclamation mark "!" change the value to `"/"` and the bot will start responding to slash commands. + + symbolPrefixes: + - "!" + + # Any additional bot prefixes that Draupnir will listen to. i.e. adding `mod` will allow `!mod help`. additionalPrefixes: - "draupnir-bot" diff --git a/roles/custom/matrix-appservice-draupnir-for-all/templates/systemd/matrix-appservice-draupnir-for-all.service.j2 b/roles/custom/matrix-appservice-draupnir-for-all/templates/systemd/matrix-appservice-draupnir-for-all.service.j2 index 43ae9e610..8dc631ad8 100644 --- a/roles/custom/matrix-appservice-draupnir-for-all/templates/systemd/matrix-appservice-draupnir-for-all.service.j2 +++ b/roles/custom/matrix-appservice-draupnir-for-all/templates/systemd/matrix-appservice-draupnir-for-all.service.j2 @@ -32,9 +32,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {{ matrix_appservice_draupnir_for_all_container_image }} \ appservice -c /data/config/production-appservice.yaml -f /data/config/draupnir-for-all-registration.yaml -p {{ matrix_appservice_draupnir_for_all_appservice_port }} --draupnir-config /data/config/production-bots.yaml +{% if matrix_appservice_draupnir_for_all_container_network != 'host' %} {% for network in matrix_appservice_draupnir_for_all_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-appservice-draupnir-for-all {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-appservice-draupnir-for-all diff --git a/roles/custom/matrix-authentication-service/defaults/main.yml b/roles/custom/matrix-authentication-service/defaults/main.yml index 98bc96ce0..dd7f2dab7 100644 --- a/roles/custom/matrix-authentication-service/defaults/main.yml +++ b/roles/custom/matrix-authentication-service/defaults/main.yml @@ -22,12 +22,11 @@ matrix_authentication_service_container_repo_version: "{{ 'main' if matrix_authe matrix_authentication_service_container_src_files_path: "{{ matrix_base_data_path }}/matrix-authentication-service/container-src" # renovate: datasource=docker depName=ghcr.io/element-hq/matrix-authentication-service -matrix_authentication_service_version: 1.14.0 +matrix_authentication_service_version: 1.24.0 matrix_authentication_service_container_image_registry_prefix: "{{ 'localhost/' if matrix_authentication_service_container_image_self_build else matrix_authentication_service_container_image_registry_prefix_upstream }}" matrix_authentication_service_container_image_registry_prefix_upstream: "{{ matrix_authentication_service_container_image_registry_prefix_upstream_default }}" matrix_authentication_service_container_image_registry_prefix_upstream_default: "ghcr.io/" matrix_authentication_service_container_image: "{{ matrix_authentication_service_container_image_registry_prefix }}element-hq/matrix-authentication-service:{{ matrix_authentication_service_version }}" -matrix_authentication_service_container_image_force_pull: "{{ matrix_authentication_service_container_image.endswith(':latest') }}" matrix_authentication_service_base_path: "{{ matrix_base_data_path }}/matrix-authentication-service" matrix_authentication_service_bin_path: "{{ matrix_authentication_service_base_path }}/bin" @@ -261,6 +260,33 @@ matrix_authentication_service_config_account_registration_token_required: false ######################################################################################## +######################################################################################## +# # +# Captcha configuration # +# # +######################################################################################## + +# Controls the `captcha.service` configuration setting. +# +# Which service to use for CAPTCHA protection of certain operations (like self-service password registration). +# Valid values: recaptcha_v2, cloudflare_turnstile, hcaptcha +# When defined, `matrix_authentication_service_config_captcha_site_key` and `matrix_authentication_service_config_captcha_secret_key` must be defined as well. +# Leave empty to disable CAPTCHA protection. +matrix_authentication_service_config_captcha_service: "" + +# Controls the `captcha.site_key` configuration setting. +matrix_authentication_service_config_captcha_site_key: "" + +# Controls the `captcha.secret_key` configuration setting. +matrix_authentication_service_config_captcha_secret_key: "" + +######################################################################################## +# # +# /Captcha configuration # +# # +######################################################################################## + + ######################################################################################## # # # Database configuration # diff --git a/roles/custom/matrix-authentication-service/molecule/default/converge.yml b/roles/custom/matrix-authentication-service/molecule/default/converge.yml new file mode 100644 index 000000000..cf84a9012 --- /dev/null +++ b/roles/custom/matrix-authentication-service/molecule/default/converge.yml @@ -0,0 +1,49 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for Matrix Authentication Service Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include base roles for Matrix Authentication Service Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + loop_control: + loop_var: role_name + + # The role's main task file also carries separately invoked CLI actions. Include the + # validation and installation selected by the normal setup tags, without invoking them. + - name: Include Matrix Authentication Service setup task files + ansible.builtin.include_role: + name: "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + public: true + tasks_from: "{{ role_task_file }}" + loop: + - validate_config.yml + - install.yml + loop_control: + loop_var: role_task_file + +# Component roles install their unit; the complete playbook's service manager starts it. +- name: Ensure Matrix Authentication Service is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure Matrix Authentication Service systemd service is started + ansible.builtin.systemd_service: + name: matrix-authentication-service.service + state: started diff --git a/roles/custom/matrix-authentication-service/molecule/default/molecule.yml b/roles/custom/matrix-authentication-service/molecule/default/molecule.yml new file mode 100644 index 000000000..a6533b502 --- /dev/null +++ b/roles/custom/matrix-authentication-service/molecule/default/molecule.yml @@ -0,0 +1,100 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-authentication-service-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_authentication_service_hostname: mas.molecule.local + matrix_authentication_service_path_prefix: /molecule-auth + matrix_authentication_service_container_network: matrix-authentication-service-molecule + + # verify.yml is a separate play where role defaults are out of scope. These are + # pinned to the paths the role derives from matrix_base_data_path. + matrix_authentication_service_base_path: /matrix/matrix-authentication-service + matrix_authentication_service_config_path: /matrix/matrix-authentication-service/config + matrix_authentication_service_data_path: /matrix/matrix-authentication-service/data + matrix_authentication_service_data_keys_path: /matrix/matrix-authentication-service/data/keys + + # Real Postgres, with a database and role which differ from the component defaults. + # A migrated schema therefore proves hostname resolution and authentication too. + matrix_authentication_service_config_database_host: matrix-postgres-molecule + matrix_authentication_service_config_database_port: 5432 + matrix_authentication_service_config_database_username: molecule_mas_user + matrix_authentication_service_config_database_password: molecule_pg_password_97af31 + matrix_authentication_service_config_database_database: molecule_mas_database + matrix_authentication_service_config_database_max_connections: 7 + matrix_authentication_service_config_database_min_connections: 2 + matrix_authentication_service_config_database_connect_timeout: 17 + + matrix_authentication_service_config_secrets_encryption: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef + matrix_authentication_service_config_matrix_homeserver: molecule.local + matrix_authentication_service_config_matrix_secret: molecule_homeserver_secret_d3a58f + matrix_authentication_service_config_matrix_endpoint: http://matrix.molecule.local:8008 + + # Values unlike both the role and MAS defaults, so parsed configuration assertions + # can tell whether this scenario reached the rendered file. + matrix_authentication_service_config_http_trusted_proxies: + - 198.51.100.0/24 + - 2001:db8:1234::/48 + matrix_authentication_service_config_email_from_name: Molecule MAS + matrix_authentication_service_config_email_from_address: auth@molecule.local + matrix_authentication_service_config_account_displayname_change_allowed: false + matrix_authentication_service_config_account_password_registration_enabled: true + matrix_authentication_service_config_account_password_registration_email_required: false + matrix_authentication_service_config_account_password_recovery_enabled: true + matrix_authentication_service_config_account_login_with_email_allowed: true + matrix_authentication_service_config_passwords_minimum_complexity: 2 + + # Traefik itself is intentionally absent. The rendered label file and Docker's live + # labels prove the role composed the non-default routing contract correctly. + matrix_authentication_service_container_labels_traefik_entrypoints: web + matrix_authentication_service_container_labels_traefik_tls_certResolver: molecule-resolver + matrix_authentication_service_container_labels_public_main_priority: 742 + matrix_authentication_service_container_labels_public_compatibility_layer_enabled: true + matrix_authentication_service_container_labels_public_compatibility_layer_hostname: matrix.molecule.local + matrix_authentication_service_container_labels_public_compatibility_layer_priority: 743 + matrix_authentication_service_container_labels_traefik_additional_response_headers_custom: + X-Molecule-MAS: covered + matrix_authentication_service_container_labels_additional_labels: | + molecule.mas.coverage=enabled + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-authentication-service/molecule/default/prepare.yml b/roles/custom/matrix-authentication-service/molecule/default/prepare.yml new file mode 100644 index 000000000..0fb3a33e2 --- /dev/null +++ b/roles/custom/matrix-authentication-service/molecule/default/prepare.yml @@ -0,0 +1,86 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare Matrix Authentication Service Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the private container network exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_authentication_service_container_network }}" + register: matrix_authentication_service_molecule_network + changed_when: matrix_authentication_service_molecule_network.rc == 0 + failed_when: + - matrix_authentication_service_molecule_network.rc != 0 + - "'already exists' not in matrix_authentication_service_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_authentication_service_container_network }}" + molecule_shared_postgres_database: "{{ matrix_authentication_service_config_database_database }}" + molecule_shared_postgres_username: "{{ matrix_authentication_service_config_database_username }}" + molecule_shared_postgres_password: "{{ matrix_authentication_service_config_database_password }}" + + # MAS does not need a successful homeserver request to expose discovery, but providing + # its configured endpoint makes the scenario independent of future startup checks. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_authentication_service_container_network }}" + molecule_shared_stub_server_name: molecule.local diff --git a/roles/custom/matrix-authentication-service/molecule/default/requirements.yml b/roles/custom/matrix-authentication-service/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-authentication-service/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-authentication-service/molecule/default/verify.yml b/roles/custom/matrix-authentication-service/molecule/default/verify.yml new file mode 100644 index 000000000..cdc81313d --- /dev/null +++ b/roles/custom/matrix-authentication-service/molecule/default/verify.yml @@ -0,0 +1,538 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# MAS exits on a bad startup configuration rather than retrying in-process. The restart +# counter guards that failure mode; live health, OIDC, JWKS, and schema checks carry the +# stronger proof that the stable process is actually using what this role rendered. +- name: Verify Matrix Authentication Service + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + vars: + matrix_authentication_service_config: >- + {{ matrix_authentication_service_config_file.content | b64decode | from_yaml }} + matrix_authentication_service_web_listener: >- + {{ matrix_authentication_service_config.http.listeners + | selectattr('name', 'equalto', 'web') | first | default({}) }} + matrix_authentication_service_internal_listener: >- + {{ matrix_authentication_service_config.http.listeners + | selectattr('name', 'equalto', 'internal') | first | default({}) }} + matrix_authentication_service_discovery_body: >- + {{ matrix_authentication_service_discovery_http.stdout_lines[:-1] | join('\n') }} + matrix_authentication_service_discovery: >- + {{ matrix_authentication_service_discovery_body | from_json }} + matrix_authentication_service_jwks_body: >- + {{ matrix_authentication_service_jwks_http.stdout_lines[:-1] | join('\n') }} + matrix_authentication_service_jwks: >- + {{ matrix_authentication_service_jwks_body | from_json }} + matrix_authentication_service_jwks_kids: >- + {{ matrix_authentication_service_jwks['keys'] | map(attribute='kid') | list }} + matrix_authentication_service_labels_lines: >- + {{ (matrix_authentication_service_labels_file.content | b64decode).splitlines() }} + matrix_authentication_service_runtime: >- + {{ (matrix_authentication_service_container_inspect.stdout | from_json) | first }} + matrix_authentication_service_config_mounts: >- + {{ matrix_authentication_service_runtime.Mounts + | selectattr('Destination', 'equalto', '/config.yaml') | list }} + matrix_authentication_service_keys_mounts: >- + {{ matrix_authentication_service_runtime.Mounts + | selectattr('Destination', 'equalto', '/keys') | list }} + + tasks: + # Read the pin from the role itself so Renovate changes what this assertion expects. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_authentication_service_role_defaults + + - name: Wait for the Matrix Authentication Service unit to become active + ansible.builtin.systemd_service: + name: matrix-authentication-service.service + register: matrix_authentication_service_service + until: matrix_authentication_service_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + - name: Assert the Matrix Authentication Service process is stable + ansible.builtin.assert: + that: + - matrix_authentication_service_service.status.ActiveState == 'active' + - matrix_authentication_service_service.status.NRestarts is defined + - matrix_authentication_service_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-authentication-service.service is + {{ matrix_authentication_service_service.status.ActiveState | default('unknown') }} + after {{ matrix_authentication_service_service.status.NRestarts | default('?') }} restart(s) + success_msg: "Matrix Authentication Service is active and has not restarted" + + # The internal listener binds loopback inside the MAS container. Sharing its network + # namespace is the only way to probe it without changing the deployment contract. + - name: Request the prefixed internal health endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network=container:matrix-authentication-service + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://[::1]:8081/molecule-auth/health + register: matrix_authentication_service_health_http + changed_when: false + until: "'HTTP_STATUS=200' in matrix_authentication_service_health_http.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the internal listener reports healthy + ansible.builtin.assert: + that: + - matrix_authentication_service_health_http.rc == 0 + - matrix_authentication_service_health_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_authentication_service_health_http.stdout_lines[0] == 'ok' + fail_msg: >- + MAS did not report healthy on its prefixed, loopback-only internal listener + ({{ matrix_authentication_service_health_http.stdout | default('no output') }}) + success_msg: "MAS reports healthy on the prefixed internal listener" + + - name: Request the unprefixed internal health path + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network=container:matrix-authentication-service + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://[::1]:8081/health + register: matrix_authentication_service_unprefixed_health_http + changed_when: false + failed_when: false + + - name: Assert the internal health resource exists only below the configured prefix + ansible.builtin.assert: + that: + - matrix_authentication_service_unprefixed_health_http.rc == 0 + - matrix_authentication_service_unprefixed_health_http.stdout == 'HTTP_STATUS=404' + fail_msg: "The unprefixed health path answered, so the configured prefix is not proven" + success_msg: "The internal listener rejects the unprefixed health path" + + # Probed through the private network because the role deliberately publishes no host port. + - name: Request the prefixed OpenID Provider discovery document + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_authentication_service_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-authentication-service:8080/molecule-auth/.well-known/openid-configuration + register: matrix_authentication_service_discovery_http + changed_when: false + until: "'HTTP_STATUS=200' in matrix_authentication_service_discovery_http.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert MAS serves a real OpenID Provider discovery document + ansible.builtin.assert: + that: + - matrix_authentication_service_discovery_http.rc == 0 + - matrix_authentication_service_discovery_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_authentication_service_discovery is mapping + - matrix_authentication_service_discovery.issuer == 'https://mas.molecule.local/molecule-auth/' + - matrix_authentication_service_discovery.authorization_endpoint == 'https://mas.molecule.local/molecule-auth/authorize' + - matrix_authentication_service_discovery.token_endpoint == 'https://mas.molecule.local/molecule-auth/oauth2/token' + - matrix_authentication_service_discovery.jwks_uri == 'https://mas.molecule.local/molecule-auth/oauth2/keys.json' + - matrix_authentication_service_discovery.userinfo_endpoint == 'https://mas.molecule.local/molecule-auth/oauth2/userinfo' + - "'openid' in matrix_authentication_service_discovery.scopes_supported" + - "'authorization_code' in matrix_authentication_service_discovery.grant_types_supported" + - "'S256' in matrix_authentication_service_discovery.code_challenge_methods_supported" + fail_msg: >- + MAS did not return the configured, prefixed OIDC discovery contract + ({{ matrix_authentication_service_discovery_http.stdout | default('no output') }}) + success_msg: "MAS advertises its configured prefixed OpenID Provider contract" + + - name: Request the unprefixed discovery path + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_authentication_service_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-authentication-service:8080/.well-known/openid-configuration + register: matrix_authentication_service_unprefixed_discovery_http + changed_when: false + failed_when: false + + - name: Assert discovery exists only below the configured prefix + ansible.builtin.assert: + that: + - matrix_authentication_service_unprefixed_discovery_http.rc == 0 + - matrix_authentication_service_unprefixed_discovery_http.stdout == 'HTTP_STATUS=404' + fail_msg: "The unprefixed discovery path answered, so the configured prefix is not proven" + success_msg: "The public listener rejects the unprefixed discovery path" + + - name: Request the JWKS advertised by discovery + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_authentication_service_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-authentication-service:8080/molecule-auth/oauth2/keys.json + register: matrix_authentication_service_jwks_http + changed_when: false + failed_when: false + + - name: Assert JWKS exposes all role-managed signing keys + ansible.builtin.assert: + that: + - matrix_authentication_service_jwks_http.rc == 0 + - matrix_authentication_service_jwks_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_authentication_service_jwks is mapping + - matrix_authentication_service_jwks['keys'] is sequence + - matrix_authentication_service_jwks['keys'] | length == 4 + - "'default-rsa' in matrix_authentication_service_jwks_kids" + - "'default-ecdsa-p256' in matrix_authentication_service_jwks_kids" + - "'default-ecdsa-p384' in matrix_authentication_service_jwks_kids" + - "'default-ecdsa-k256' in matrix_authentication_service_jwks_kids" + - (matrix_authentication_service_jwks['keys'] | selectattr('kid', 'equalto', 'default-rsa') | first).kty == 'RSA' + - (matrix_authentication_service_jwks['keys'] | selectattr('kid', 'equalto', 'default-rsa') | first).n | length > 100 + - (matrix_authentication_service_jwks['keys'] | selectattr('kid', 'equalto', 'default-ecdsa-p256') | first).crv == 'P-256' + - (matrix_authentication_service_jwks['keys'] | selectattr('kid', 'equalto', 'default-ecdsa-p384') | first).crv == 'P-384' + - (matrix_authentication_service_jwks['keys'] | selectattr('kid', 'equalto', 'default-ecdsa-k256') | first).crv == 'secp256k1' + fail_msg: "MAS did not derive the expected public JWKS from all four managed keys" + success_msg: "MAS exposes all four role-managed signing keys in its public JWKS" + + - name: Read the rendered MAS configuration + ansible.builtin.slurp: + src: "{{ matrix_authentication_service_config_path }}/config.yaml" + register: matrix_authentication_service_config_file + + - name: Read the rendered MAS configuration identity + ansible.builtin.stat: + path: "{{ matrix_authentication_service_config_path }}/config.yaml" + register: matrix_authentication_service_config_stat + + - name: Assert the parsed listener and public URL configuration + ansible.builtin.assert: + that: + - matrix_authentication_service_config.http.listeners | length == 2 + - matrix_authentication_service_web_listener.resources | map(attribute='name') | list == ['discovery', 'human', 'oauth', 'compat', 'graphql', 'assets'] + - "matrix_authentication_service_web_listener.binds == [{'address': '[::]:8080'}]" + - matrix_authentication_service_web_listener.prefix == '/molecule-auth' + - not matrix_authentication_service_web_listener.proxy_protocol + - "matrix_authentication_service_internal_listener.resources == [{'name': 'health'}]" + - "matrix_authentication_service_internal_listener.binds == [{'host': 'localhost', 'port': 8081}]" + - matrix_authentication_service_internal_listener.prefix == '/molecule-auth' + - matrix_authentication_service_config.http.public_base == 'https://mas.molecule.local/molecule-auth/' + - matrix_authentication_service_config.http.issuer == 'https://mas.molecule.local/molecule-auth/' + - matrix_authentication_service_config.http.trusted_proxies == ['198.51.100.0/24', '2001:db8:1234::/48'] + fail_msg: "The parsed MAS listener or public URL configuration is incorrect" + success_msg: "The parsed MAS configuration carries the non-default listener contract" + + - name: Assert the parsed Postgres pool configuration + ansible.builtin.assert: + that: + - matrix_authentication_service_config.database.host == matrix_authentication_service_config_database_host + - matrix_authentication_service_config.database.port == matrix_authentication_service_config_database_port + - matrix_authentication_service_config.database.username == matrix_authentication_service_config_database_username + - matrix_authentication_service_config.database.password == matrix_authentication_service_config_database_password + - matrix_authentication_service_config.database.database == matrix_authentication_service_config_database_database + - matrix_authentication_service_config.database.ssl_mode == 'disable' + - matrix_authentication_service_config.database.max_connections == 7 + - matrix_authentication_service_config.database.min_connections == 2 + - matrix_authentication_service_config.database.connect_timeout == 17 + fail_msg: "The parsed MAS configuration does not point at scenario Postgres" + success_msg: "The parsed MAS configuration points at scenario Postgres" + no_log: true + + - name: Assert the parsed Matrix and cryptographic configuration + ansible.builtin.assert: + that: + - matrix_authentication_service_config.matrix.homeserver == 'molecule.local' + - matrix_authentication_service_config.matrix.endpoint == 'http://matrix.molecule.local:8008' + - matrix_authentication_service_config.matrix.secret == matrix_authentication_service_config_matrix_secret + - matrix_authentication_service_config.secrets.encryption == matrix_authentication_service_config_secrets_encryption + - matrix_authentication_service_config.secrets['keys'] | map(attribute='kid') | list == ['default-rsa', 'default-ecdsa-p256', 'default-ecdsa-p384', 'default-ecdsa-k256'] + - matrix_authentication_service_config.secrets['keys'] | map(attribute='key_file') | list == ['/keys/rsa-2048.priv.pem', '/keys/ecdsa-p256.priv.pem', '/keys/ecdsa-p384.priv.pem', '/keys/ecdsa-k256.priv.pem'] + fail_msg: "The parsed MAS Matrix or signing-key configuration is incorrect" + success_msg: "The parsed MAS configuration carries its Matrix secrets and managed keys" + no_log: true + + - name: Assert the parsed non-default account behavior + ansible.builtin.assert: + that: + - not matrix_authentication_service_config.account.displayname_change_allowed + - matrix_authentication_service_config.account.password_registration_enabled + - not matrix_authentication_service_config.account.password_registration_email_required + - matrix_authentication_service_config.account.password_recovery_enabled + - matrix_authentication_service_config.account.login_with_email_allowed + - matrix_authentication_service_config.passwords.minimum_complexity == 2 + - matrix_authentication_service_config.email.from == '"Molecule MAS" ' + - matrix_authentication_service_config.email.transport == 'blackhole' + - matrix_authentication_service_config.clients == [] + - "'upstream_oauth2' not in matrix_authentication_service_config" + - "'captcha' not in matrix_authentication_service_config" + fail_msg: "The parsed MAS configuration does not carry the scenario account behavior" + success_msg: "The parsed MAS configuration carries the non-default account behavior" + + - name: Assert the rendered configuration file identity + ansible.builtin.assert: + that: + - matrix_authentication_service_config_stat.stat.uid | int == matrix_user_uid | int + - matrix_authentication_service_config_stat.stat.gid | int == matrix_user_gid | int + - matrix_authentication_service_config_stat.stat.mode == '0644' + fail_msg: "config.yaml has the wrong ownership or mode" + success_msg: "config.yaml has the playbook identity and expected mode" + + - name: Read the managed signing-key identities + ansible.builtin.stat: + path: "{{ matrix_authentication_service_data_keys_path }}/{{ key_file }}" + loop: + - rsa-2048.priv.pem + - ecdsa-p256.priv.pem + - ecdsa-p384.priv.pem + - ecdsa-k256.priv.pem + loop_control: + loop_var: key_file + register: matrix_authentication_service_key_stats + + - name: Assert every managed signing key is non-empty and private + ansible.builtin.assert: + that: + - key_stat.stat.exists + - key_stat.stat.isreg + - key_stat.stat.size | int > 200 + - key_stat.stat.uid | int == matrix_user_uid | int + - key_stat.stat.gid | int == matrix_user_gid | int + - key_stat.stat.mode == '0600' + fail_msg: "A managed MAS signing key is missing, empty, exposed, or misowned" + success_msg: "The managed MAS signing key is present and private" + loop: "{{ matrix_authentication_service_key_stats.results }}" + loop_control: + loop_var: key_stat + label: "{{ key_stat.key_file }}" + + - name: Validate every managed signing key with OpenSSL + ansible.builtin.command: + argv: + - openssl + - pkey + - -in + - "{{ matrix_authentication_service_data_keys_path }}/{{ key_file }}" + - -check + - -noout + loop: + - rsa-2048.priv.pem + - ecdsa-p256.priv.pem + - ecdsa-p384.priv.pem + - ecdsa-k256.priv.pem + loop_control: + loop_var: key_file + register: matrix_authentication_service_key_validation + changed_when: false + + - name: Assert OpenSSL accepts every managed signing key + ansible.builtin.assert: + that: + - key_validation.rc == 0 + fail_msg: "OpenSSL rejected a role-managed MAS signing key" + success_msg: "OpenSSL accepts the role-managed MAS signing key" + loop: "{{ matrix_authentication_service_key_validation.results }}" + loop_control: + loop_var: key_validation + label: "{{ key_validation.key_file }}" + + # These tables can only exist after MAS has reached the named host, authenticated as + # the non-default role, selected the non-default database, and run genuine migrations. + - name: List the tables MAS created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_authentication_service_config_database_username }} + - --dbname={{ matrix_authentication_service_config_database_database }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: matrix_authentication_service_tables + changed_when: false + + - name: Count successful MAS migrations in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_authentication_service_config_database_username }} + - --dbname={{ matrix_authentication_service_config_database_database }} + - --tuples-only + - --no-align + - --command=SELECT count(*) FROM _sqlx_migrations WHERE success + register: matrix_authentication_service_migrations + changed_when: false + + - name: Assert MAS genuinely migrated the configured Postgres database + ansible.builtin.assert: + that: + - matrix_authentication_service_tables.rc == 0 + - "'_sqlx_migrations' in matrix_authentication_service_table_names" + - "'users' in matrix_authentication_service_table_names" + - "'user_sessions' in matrix_authentication_service_table_names" + - "'oauth2_clients' in matrix_authentication_service_table_names" + - "'oauth2_access_tokens' in matrix_authentication_service_table_names" + - "'upstream_oauth_providers' in matrix_authentication_service_table_names" + - matrix_authentication_service_table_names | length > 30 + - matrix_authentication_service_migrations.rc == 0 + - matrix_authentication_service_migrations.stdout | trim | int > 100 + fail_msg: >- + MAS did not genuinely migrate {{ matrix_authentication_service_config_database_database }} + ({{ matrix_authentication_service_table_names | length }} tables, + {{ matrix_authentication_service_migrations.stdout | trim | default('?') }} migrations) + success_msg: "MAS genuinely migrated the configured Postgres database" + vars: + matrix_authentication_service_table_names: >- + {{ matrix_authentication_service_tables.stdout_lines | select | list }} + + - name: Read the Traefik labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_authentication_service_config_path }}/labels" + register: matrix_authentication_service_labels_file + + - name: Assert the rendered labels carry the non-default public routing contract + ansible.builtin.assert: + that: + - "'traefik.enable=true' in matrix_authentication_service_labels_lines" + - "'traefik.docker.network=matrix-authentication-service-molecule' in matrix_authentication_service_labels_lines" + - "'traefik.http.services.matrix-authentication-service.loadbalancer.server.port=8080' in matrix_authentication_service_labels_lines" + - "'traefik.http.routers.matrix-authentication-service.rule=Host(`mas.molecule.local`) && PathPrefix(`/molecule-auth`)' in matrix_authentication_service_labels_lines" + - "'traefik.http.routers.matrix-authentication-service.priority=742' in matrix_authentication_service_labels_lines" + - "'traefik.http.middlewares.matrix-authentication-service-slashless-redirect.redirectregex.regex=(/molecule-auth)$' in matrix_authentication_service_labels_lines" + - "'traefik.http.middlewares.matrix-authentication-service-add-headers.headers.customresponseheaders.X-Molecule-MAS=covered' in matrix_authentication_service_labels_lines" + - "'traefik.http.routers.matrix-authentication-service.middlewares=matrix-authentication-service-slashless-redirect,matrix-authentication-service-add-headers' in matrix_authentication_service_labels_lines" + - "'traefik.http.routers.matrix-authentication-service.entrypoints=web' in matrix_authentication_service_labels_lines" + - "'traefik.http.routers.matrix-authentication-service.tls=false' in matrix_authentication_service_labels_lines" + - "'molecule.mas.coverage=enabled' in matrix_authentication_service_labels_lines" + fail_msg: "The rendered labels do not carry the configured public MAS route" + success_msg: "The rendered labels carry the configured public MAS route" + + - name: Assert the rendered labels carry the compatibility-layer route + ansible.builtin.assert: + that: + - "'traefik.http.middlewares.matrix-authentication-service-add-prefix.addprefix.prefix=/molecule-auth' in matrix_authentication_service_labels_lines" + - "'traefik.http.routers._internalmatrix-authentication-service-public-compatibility-layer.rule=Host(`matrix.molecule.local`) && PathRegexp(`^/_matrix/client/(?P([^/]+))/(?P(login|logout|refresh))`)' in matrix_authentication_service_labels_lines" + - "'traefik.http.routers._internalmatrix-authentication-service-public-compatibility-layer.priority=743' in matrix_authentication_service_labels_lines" + - "'traefik.http.routers._internalmatrix-authentication-service-public-compatibility-layer.middlewares=matrix-authentication-service-add-prefix' in matrix_authentication_service_labels_lines" + - "'traefik.http.routers._internalmatrix-authentication-service-public-compatibility-layer.entrypoints=web' in matrix_authentication_service_labels_lines" + - "'traefik.http.routers._internalmatrix-authentication-service-public-compatibility-layer.tls=false' in matrix_authentication_service_labels_lines" + fail_msg: "The rendered labels do not carry the configured compatibility route" + success_msg: "The rendered labels carry the configured compatibility-layer route" + + - name: Inspect the running MAS container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-authentication-service + register: matrix_authentication_service_container_inspect + changed_when: false + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - matrix_authentication_service_runtime.Config.Image == 'ghcr.io/element-hq/matrix-authentication-service:' + matrix_authentication_service_role_defaults.matrix_authentication_service_version + fail_msg: "The running MAS container does not use the exact role-pinned image" + success_msg: "The running MAS container uses the exact role-pinned image" + + - name: Assert the running container uses the playbook identity + ansible.builtin.assert: + that: + - matrix_authentication_service_runtime.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + fail_msg: "The running MAS container does not use the playbook UID and GID" + success_msg: "The running MAS container uses the playbook UID and GID" + + - name: Assert the running container security isolation + ansible.builtin.assert: + that: + - matrix_authentication_service_runtime.HostConfig.ReadonlyRootfs is sameas true + - matrix_authentication_service_runtime.HostConfig.CapDrop == ['ALL'] + - not matrix_authentication_service_runtime.HostConfig.Privileged + fail_msg: "The running MAS container lacks read-only, capability-dropped isolation" + success_msg: "The running MAS container has read-only, capability-dropped isolation" + + - name: Assert the running container mounts only configuration and keys read-only + ansible.builtin.assert: + that: + - matrix_authentication_service_runtime.Mounts | length == 2 + - matrix_authentication_service_config_mounts | length == 1 + - matrix_authentication_service_config_mounts[0].RW is sameas false + - matrix_authentication_service_keys_mounts | length == 1 + - matrix_authentication_service_keys_mounts[0].RW is sameas false + fail_msg: "The running MAS container's config or key mount contract is incorrect" + success_msg: "The running MAS container mounts only configuration and keys read-only" + + - name: Assert the running container has only its dedicated network + ansible.builtin.assert: + that: + - matrix_authentication_service_runtime.NetworkSettings.Networks is mapping + - matrix_authentication_service_runtime.NetworkSettings.Networks | length == 1 + - matrix_authentication_service_container_network in matrix_authentication_service_runtime.NetworkSettings.Networks + fail_msg: "The running MAS container has unexpected network attachments" + success_msg: "The running MAS container has only its dedicated network" + + - name: Assert the running container publishes no host ports + ansible.builtin.assert: + that: + - matrix_authentication_service_runtime.HostConfig.PortBindings | default({}, true) | length == 0 + - matrix_authentication_service_runtime.NetworkSettings.Ports | default({}, true) | length == 0 + - not matrix_authentication_service_runtime.HostConfig.PublishAllPorts + fail_msg: "The running MAS container unexpectedly publishes a host port" + success_msg: "The running MAS container publishes no host ports" + + - name: Assert Docker accepted the role's exact routing labels + ansible.builtin.assert: + that: + - matrix_authentication_service_runtime.Config.Labels is mapping + - matrix_authentication_service_runtime.Config.Labels['molecule.mas.coverage'] == 'enabled' + - matrix_authentication_service_runtime.Config.Labels['traefik.docker.network'] == 'matrix-authentication-service-molecule' + - matrix_authentication_service_runtime.Config.Labels['traefik.http.services.matrix-authentication-service.loadbalancer.server.port'] == '8080' + - matrix_authentication_service_runtime.Config.Labels['traefik.http.routers.matrix-authentication-service.rule'] == 'Host(`mas.molecule.local`) && PathPrefix(`/molecule-auth`)' + - matrix_authentication_service_runtime.Config.Labels['traefik.http.routers.matrix-authentication-service.priority'] == '742' + - matrix_authentication_service_runtime.Config.Labels['traefik.http.routers._internalmatrix-authentication-service-public-compatibility-layer.priority'] == '743' + - matrix_authentication_service_runtime.Config.Labels['traefik.http.middlewares.matrix-authentication-service-add-headers.headers.customresponseheaders.X-Molecule-MAS'] == 'covered' + fail_msg: "Docker did not attach the exact labels rendered by the role" + success_msg: "Docker attached the exact routing labels rendered by the role" diff --git a/roles/custom/matrix-authentication-service/tasks/install.yml b/roles/custom/matrix-authentication-service/tasks/install.yml index a291b5039..d1927a45f 100644 --- a/roles/custom/matrix-authentication-service/tasks/install.yml +++ b/roles/custom/matrix-authentication-service/tasks/install.yml @@ -84,11 +84,9 @@ register: matrix_authentication_service_support_files_result - name: Ensure Matrix Authentication Service container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_authentication_service_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_authentication_service_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_authentication_service_container_image_force_pull }}" + pull: always when: "not matrix_authentication_service_container_image_self_build | bool" register: matrix_authentication_service_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -97,6 +95,15 @@ - when: "matrix_authentication_service_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure Matrix Authentication Service repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_authentication_service_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure Matrix Authentication Service repository is present on self-build ansible.builtin.git: repo: "{{ matrix_authentication_service_container_repo }}" @@ -116,6 +123,7 @@ changed_when: true - name: Ensure Matrix Authentication Service container network is created + when: matrix_authentication_service_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_authentication_service_container_network }}" diff --git a/roles/custom/matrix-authentication-service/tasks/mas_cli_syn2mas.yml b/roles/custom/matrix-authentication-service/tasks/mas_cli_syn2mas.yml index 676db8e65..a15435a64 100644 --- a/roles/custom/matrix-authentication-service/tasks/mas_cli_syn2mas.yml +++ b/roles/custom/matrix-authentication-service/tasks/mas_cli_syn2mas.yml @@ -110,11 +110,17 @@ ansible.builtin.debug: var: matrix_authentication_service_mas_cli_syn2mas_command_result -- name: Ensure Synapse is started (if it previously was) +- name: Inject syn2mas post-migration note when: "not matrix_authentication_service_syn2mas_migrate_dry_run and matrix_authentication_service_mas_cli_syn2mas_command_result.changed" - ansible.builtin.service: - name: matrix-synapse - state: started + ansible.builtin.set_fact: + devture_playbook_runtime_messages_list: | + {{ + devture_playbook_runtime_messages_list | default([]) + + + [ + "Synapse was intentionally not restarted after `syn2mas`. Continue with the next steps in the Matrix Authentication Service migration guide before re-running the installation." + ] + }} - name: Ensure Matrix Authentication Service is started (if it previously was) when: "not matrix_authentication_service_syn2mas_migrate_dry_run and matrix_authentication_service_mas_ensure_stopped_result.changed" diff --git a/roles/custom/matrix-authentication-service/tasks/validate_config.yml b/roles/custom/matrix-authentication-service/tasks/validate_config.yml index 1dd005047..becbbbf48 100644 --- a/roles/custom/matrix-authentication-service/tasks/validate_config.yml +++ b/roles/custom/matrix-authentication-service/tasks/validate_config.yml @@ -25,6 +25,8 @@ - {'name': 'matrix_authentication_service_container_labels_public_compatibility_layer_hostname', when: "{{ matrix_authentication_service_container_labels_public_compatibility_layer_enabled }}"} - {'name': 'matrix_authentication_service_container_labels_internal_compatibility_layer_entrypoints', when: "{{ matrix_authentication_service_container_labels_internal_compatibility_layer_enabled }}"} - {'name': 'matrix_authentication_service_config_email_hostname', when: "{{ matrix_authentication_service_config_email_transport == 'smtp' }}"} + - {'name': 'matrix_authentication_service_config_captcha_site_key', when: "{{ matrix_authentication_service_config_captcha_service != '' }}"} + - {'name': 'matrix_authentication_service_config_captcha_secret_key', when: "{{ matrix_authentication_service_config_captcha_service != '' }}"} - name: Fail if matrix_authentication_service_config_secrets_encryption is not 64 characters long ansible.builtin.fail: @@ -36,6 +38,11 @@ msg: "matrix_authentication_service_config_email_transport must be one of: blackhole, smtp, or aws_ses" when: "matrix_authentication_service_config_email_transport not in ['blackhole', 'smtp', 'aws_ses']" +- name: Fail if matrix_authentication_service_config_captcha_service is invalid + ansible.builtin.fail: + msg: "matrix_authentication_service_config_captcha_service must be one of: recaptcha_v2, cloudflare_turnstile, or hcaptcha (or empty, to disable CAPTCHA protection)" + when: "matrix_authentication_service_config_captcha_service not in ['', 'recaptcha_v2', 'cloudflare_turnstile', 'hcaptcha']" + - name: (Deprecation) Catch and report renamed matrix-authentication-service settings ansible.builtin.fail: msg: >- @@ -53,3 +60,4 @@ - {'old': 'matrix_authentication_service_syn2mas_container_image_self_build', 'new': ''} - {'old': 'matrix_authentication_service_syn2mas_process_extra_arguments', 'new': 'matrix_authentication_service_syn2mas_command_extra_options or matrix_authentication_service_syn2mas_subcommand_extra_options'} - {'old': 'matrix_authentication_service_syn2mas_dry_run', 'new': 'matrix_authentication_service_syn2mas_migrate_dry_run'} + - {'old': 'matrix_authentication_service_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-authentication-service/templates/config.yaml.j2 b/roles/custom/matrix-authentication-service/templates/config.yaml.j2 index 0060584be..efaacc826 100644 --- a/roles/custom/matrix-authentication-service/templates/config.yaml.j2 +++ b/roles/custom/matrix-authentication-service/templates/config.yaml.j2 @@ -72,6 +72,13 @@ account: login_with_email_allowed: {{ matrix_authentication_service_config_account_login_with_email_allowed | to_json }} registration_token_required: {{ matrix_authentication_service_config_account_registration_token_required | to_json }} +{% if matrix_authentication_service_config_captcha_service %} +captcha: + service: {{ matrix_authentication_service_config_captcha_service | to_json }} + site_key: {{ matrix_authentication_service_config_captcha_site_key | to_json }} + secret_key: {{ matrix_authentication_service_config_captcha_secret_key | to_json }} +{% endif %} + clients: {{ matrix_authentication_service_config_clients | to_json }} {% if matrix_authentication_service_config_upstream_oauth2_providers | length > 0 %} diff --git a/roles/custom/matrix-authentication-service/templates/systemd/matrix-authentication-service.service.j2 b/roles/custom/matrix-authentication-service/templates/systemd/matrix-authentication-service.service.j2 index b91535e4b..ceb353f22 100644 --- a/roles/custom/matrix-authentication-service/templates/systemd/matrix-authentication-service.service.j2 +++ b/roles/custom/matrix-authentication-service/templates/systemd/matrix-authentication-service.service.j2 @@ -36,9 +36,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_authentication_service_container_image }} +{% if matrix_authentication_service_container_network != 'host' %} {% for network in matrix_authentication_service_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-authentication-service {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-authentication-service diff --git a/roles/custom/matrix-base/defaults/main.yml b/roles/custom/matrix-base/defaults/main.yml index 2cd854111..d7195f066 100644 --- a/roles/custom/matrix-base/defaults/main.yml +++ b/roles/custom/matrix-base/defaults/main.yml @@ -54,6 +54,15 @@ matrix_bridges_msc4190_enabled: "{{ matrix_authentication_service_enabled and ma # Global var for enabling bridge self-signing ( On supported bridges) matrix_bridges_self_sign_enabled: "{{ matrix_bridges_msc4190_enabled }}" +# Global vars for exposing bridges' HTTP API publicly on the Matrix domain. +# This is used by tools like mautrix-manager (https://github.com/mautrix/manager) to drive bridge login. +# Each supported bridge's HTTP endpoint is exposed under `/` (e.g. `/bridges/gmessages`). +# Requests are authenticated by the bridge itself (e.g. per-user Matrix access token for the provisioning API, +# or the homeserver token for the appservice endpoints), not by us. +matrix_bridges_exposure_enabled: true +matrix_bridges_exposure_hostname: "{{ matrix_server_fqn_matrix }}" +matrix_bridges_exposure_path_prefix: /bridges + # Global var to enable/disable relay mode across all bridges with relay mode support matrix_bridges_relay_enabled: false @@ -84,7 +93,7 @@ matrix_monitoring_container_network: matrix-monitoring matrix_homeserver_enabled: true # This will contain the homeserver implementation that is in use. -# Valid values: synapse, dendrite, conduit, continuwuity +# Valid values: synapse, dendrite, conduit, continuwuity, tuwunel # # By default, we use Synapse, because it's the only full-featured Matrix server at the moment. # @@ -131,9 +140,6 @@ matrix_server_fqn_buscarron: "buscarron.{{ matrix_domain }}" # This is where you access the Etherpad (if enabled via etherpad_enabled; disabled by default). matrix_server_fqn_etherpad: "etherpad.{{ matrix_domain }}" -# For use with Go-NEB! (github callback url for example) -matrix_server_fqn_bot_go_neb: "goneb.{{ matrix_domain }}" - # This is where you access Jitsi. matrix_server_fqn_jitsi: "jitsi.{{ matrix_domain }}" @@ -198,6 +204,26 @@ matrix_group_system: true matrix_user_uid: ~ matrix_user_gid: ~ +# Controls Synology DSM-specific handling. `null` means autodetect (via /etc/synoinfo.conf). +# Set to `true`/`false` to force. +matrix_base_host_is_synology: ~ + +# Password for the Matrix service account on Synology DSM. +# Must be set to a non-empty value in your vars.yml when running on Synology. +# The account is created as expired so the password cannot be used to log in. +matrix_synology_user_password: "" + +# Version constraint for the requests Python package installed on Synology hosts. +# requests >= 2.32 dropped the http+docker URL scheme used by the Docker SDK, +# causing "Not supported URL scheme http+docker" errors. Installed into the +# system Python interpreter (ansible_python_interpreter) on the remote host. +matrix_base_synology_requests_version_constraint: "requests<2.32" + +# Synology volume that needs shared mount propagation so that Docker +# bind-propagation=slave mounts (used by matrix-synapse for its media store) +# work correctly. Defaults to /volume1 (DSM's default Docker storage volume). +matrix_base_synology_volume_path: "/volume1" + matrix_base_data_path: "/matrix" matrix_base_data_path_mode: "750" diff --git a/roles/custom/matrix-base/tasks/detect_platform.yml b/roles/custom/matrix-base/tasks/detect_platform.yml new file mode 100644 index 000000000..5d36f3d89 --- /dev/null +++ b/roles/custom/matrix-base/tasks/detect_platform.yml @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: 2026 Chiu Ki Sit +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Detect Synology DSM + ansible.builtin.stat: + path: /etc/synoinfo.conf + register: matrix_base_synoinfo_conf_stat + when: matrix_base_host_is_synology is none + +- name: Set matrix_base_host_is_synology from detection + ansible.builtin.set_fact: + matrix_base_host_is_synology: "{{ matrix_base_synoinfo_conf_stat.stat.exists }}" + when: matrix_base_host_is_synology is none diff --git a/roles/custom/matrix-base/tasks/main.yml b/roles/custom/matrix-base/tasks/main.yml index d6d4d8f26..14c1340ab 100644 --- a/roles/custom/matrix-base/tasks/main.yml +++ b/roles/custom/matrix-base/tasks/main.yml @@ -4,6 +4,7 @@ # SPDX-FileCopyrightText: 2020 Marcel Partap # SPDX-FileCopyrightText: 2022 Marko Weltzer # SPDX-FileCopyrightText: 2022 Warren Bailey +# SPDX-FileCopyrightText: 2026 Chiu Ki Sit # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -15,6 +16,11 @@ block: - ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" +- tags: + - always + block: + - ansible.builtin.include_tasks: "{{ role_path }}/tasks/detect_platform.yml" + # This needs to always run, because it populates `matrix_user_uid` and `matrix_user_gid`, # which are required by many other roles. - tags: @@ -24,6 +30,13 @@ block: - ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_matrix_user.yml" +- tags: + - setup-all + - install-all + block: + - ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_synology_prerequisites.yml" + when: matrix_base_host_is_synology + - tags: - setup-all - install-all diff --git a/roles/custom/matrix-base/tasks/setup_matrix_base.yml b/roles/custom/matrix-base/tasks/setup_matrix_base.yml index 94750383a..7fc7148e7 100644 --- a/roles/custom/matrix-base/tasks/setup_matrix_base.yml +++ b/roles/custom/matrix-base/tasks/setup_matrix_base.yml @@ -7,11 +7,20 @@ # SPDX-FileCopyrightText: 2022 Sebastian Gumprich # SPDX-FileCopyrightText: 2024 - 2025 Suguru Hirahara # SPDX-FileCopyrightText: 2024 László Várady +# SPDX-FileCopyrightText: 2026 Chiu Ki Sit # # SPDX-License-Identifier: AGPL-3.0-or-later --- +# Snapshot ownership before any changes so we can decide whether a recursive +# chown is needed (only when uid/gid actually differs from expected). +- name: Check current ownership of Matrix base path (Synology) + ansible.builtin.stat: + path: "{{ matrix_base_data_path }}" + register: matrix_base_data_path_stat + when: matrix_base_host_is_synology + - name: Ensure Matrix base paths exists ansible.builtin.file: path: "{{ item }}" @@ -28,3 +37,18 @@ src: "{{ role_path }}/templates/bin/remove-all.j2" dest: "{{ matrix_bin_path }}/remove-all" mode: '0750' + +# On Synology, name-based chown works for directly-touched paths but leaves +# existing sub-paths with stale numeric ownership when uid/gid changes between +# runs. We recurse only when the pre-task uid/gid didn't match, so normal runs +# skip the expensive tree walk entirely. chown -R is used instead of the file +# module's recurse option to avoid Ansible iterating every entry in Python. +- name: Ensure Matrix base path ownership is correct using numeric UID/GID (Synology) + ansible.builtin.command: chown -R {{ matrix_user_uid }}:{{ matrix_user_gid }} {{ matrix_base_data_path }} + changed_when: true + when: >- + matrix_base_host_is_synology and ( + not matrix_base_data_path_stat.stat.exists or + matrix_base_data_path_stat.stat.uid | int != matrix_user_uid | int or + matrix_base_data_path_stat.stat.gid | int != matrix_user_gid | int + ) diff --git a/roles/custom/matrix-base/tasks/setup_matrix_user.yml b/roles/custom/matrix-base/tasks/setup_matrix_user.yml index b2512a437..2ab8a496c 100644 --- a/roles/custom/matrix-base/tasks/setup_matrix_user.yml +++ b/roles/custom/matrix-base/tasks/setup_matrix_user.yml @@ -1,31 +1,13 @@ # SPDX-FileCopyrightText: 2020 - 2022 Slavi Pantaleev # SPDX-FileCopyrightText: 2022 Marko Weltzer +# SPDX-FileCopyrightText: 2026 Chiu Ki Sit # # SPDX-License-Identifier: AGPL-3.0-or-later --- -- name: Ensure Matrix group is created - ansible.builtin.group: - name: "{{ matrix_group_name }}" - gid: "{{ omit if matrix_user_gid is none else matrix_user_gid }}" - state: present - system: "{{ matrix_group_system }}" - register: matrix_group +- ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_matrix_user_synology.yml" + when: matrix_base_host_is_synology -- name: Ensure Matrix user is created - ansible.builtin.user: - name: "{{ matrix_user_name }}" - uid: "{{ omit if matrix_user_uid is none else matrix_user_uid }}" - state: present - group: "{{ matrix_group_name }}" - home: "{{ matrix_base_data_path }}" - create_home: false - system: "{{ matrix_user_system }}" - shell: "{{ matrix_user_shell }}" - register: matrix_user - -- name: Initialize matrix_user_uid and matrix_user_gid - ansible.builtin.set_fact: - matrix_user_uid: "{{ matrix_user.uid }}" - matrix_user_gid: "{{ matrix_group.gid }}" +- ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_matrix_user_linux.yml" + when: not matrix_base_host_is_synology diff --git a/roles/custom/matrix-base/tasks/setup_matrix_user_linux.yml b/roles/custom/matrix-base/tasks/setup_matrix_user_linux.yml new file mode 100644 index 000000000..b2512a437 --- /dev/null +++ b/roles/custom/matrix-base/tasks/setup_matrix_user_linux.yml @@ -0,0 +1,31 @@ +# SPDX-FileCopyrightText: 2020 - 2022 Slavi Pantaleev +# SPDX-FileCopyrightText: 2022 Marko Weltzer +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Ensure Matrix group is created + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ omit if matrix_user_gid is none else matrix_user_gid }}" + state: present + system: "{{ matrix_group_system }}" + register: matrix_group + +- name: Ensure Matrix user is created + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ omit if matrix_user_uid is none else matrix_user_uid }}" + state: present + group: "{{ matrix_group_name }}" + home: "{{ matrix_base_data_path }}" + create_home: false + system: "{{ matrix_user_system }}" + shell: "{{ matrix_user_shell }}" + register: matrix_user + +- name: Initialize matrix_user_uid and matrix_user_gid + ansible.builtin.set_fact: + matrix_user_uid: "{{ matrix_user.uid }}" + matrix_user_gid: "{{ matrix_group.gid }}" diff --git a/roles/custom/matrix-base/tasks/setup_matrix_user_synology.yml b/roles/custom/matrix-base/tasks/setup_matrix_user_synology.yml new file mode 100644 index 000000000..6d49c9d7f --- /dev/null +++ b/roles/custom/matrix-base/tasks/setup_matrix_user_synology.yml @@ -0,0 +1,69 @@ +# SPDX-FileCopyrightText: 2026 Chiu Ki Sit +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Fail if matrix_synology_user_password is not set + ansible.builtin.fail: + msg: >- + You must set `matrix_synology_user_password` to a non-empty value in your vars.yml. + This password secures the Matrix service account on Synology DSM. + The account is created as expired so the password cannot be used to log in. + when: matrix_synology_user_password == '' or matrix_synology_user_password is none + +- name: Check if Matrix user exists (Synology) + ansible.builtin.command: id {{ matrix_user_name }} + register: matrix_user_check + changed_when: false + failed_when: false + +# Created with expired=1 (cannot log in) +# as this is a service account. If you pre-create the user, you are responsible +# for securing it; the playbook will not modify an existing account's settings. +- name: Ensure Matrix user is created (Synology) + ansible.builtin.command: > + /usr/syno/sbin/synouser --add {{ matrix_user_name }} + "{{ matrix_synology_user_password }}" "{{ matrix_user_name }}" 1 "" 0 + when: matrix_user_check.rc != 0 + changed_when: true + no_log: true + +- name: Ensure Matrix user password is up to date (Synology) + ansible.builtin.command: /usr/syno/sbin/synouser --setpw {{ matrix_user_name }} "{{ matrix_synology_user_password }}" + when: matrix_user_check.rc == 0 + changed_when: false + no_log: true + +- name: Check if Matrix group exists (Synology) + ansible.builtin.command: /usr/syno/sbin/synogroup --get {{ matrix_group_name }} + register: matrix_group_check + changed_when: false + failed_when: false + +- name: Ensure Matrix group is created (Synology) + ansible.builtin.command: /usr/syno/sbin/synogroup --add {{ matrix_group_name }} {{ matrix_user_name }} + when: matrix_group_check.rc != 0 + changed_when: true + +- name: Get Matrix user UID (Synology) + ansible.builtin.command: id -u {{ matrix_user_name }} + register: matrix_user_uid_result + changed_when: false + +- name: Get Matrix group info (Synology) + ansible.builtin.command: /usr/syno/sbin/synogroup --get {{ matrix_group_name }} + register: matrix_synogroup_result + changed_when: false + +- name: Initialize matrix_user_uid and matrix_user_gid + ansible.builtin.set_fact: + matrix_user_uid: "{{ matrix_user_uid_result.stdout }}" + matrix_user_gid: >- + {{ + matrix_synogroup_result.stdout_lines + | select('match', '^Group ID:') + | first + | regex_search('\[(\d+)\]', '\1') + | first + }} diff --git a/roles/custom/matrix-base/tasks/setup_synology_boot_fix.yml b/roles/custom/matrix-base/tasks/setup_synology_boot_fix.yml new file mode 100644 index 000000000..66498c677 --- /dev/null +++ b/roles/custom/matrix-base/tasks/setup_synology_boot_fix.yml @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: 2026 Chiu Ki Sit +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Deploy Matrix boot recovery script (Synology) + ansible.builtin.template: + src: "{{ role_path }}/templates/bin/matrix-synology-boot-fix.j2" + dest: "{{ matrix_bin_path }}/matrix-synology-boot-fix" + mode: "0750" + owner: root + group: root + +- name: Deploy Matrix boot recovery service (Synology) + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-synology-boot-fix.service.j2" + dest: /etc/systemd/system/matrix-synology-boot-fix.service + mode: "0644" + register: matrix_synology_boot_fix_service + +- name: Reload systemd and enable Matrix boot recovery service (Synology) + ansible.builtin.systemd: + name: matrix-synology-boot-fix.service + daemon_reload: true + enabled: true + when: matrix_synology_boot_fix_service.changed diff --git a/roles/custom/matrix-base/tasks/setup_synology_prerequisites.yml b/roles/custom/matrix-base/tasks/setup_synology_prerequisites.yml new file mode 100644 index 000000000..5985e8dd4 --- /dev/null +++ b/roles/custom/matrix-base/tasks/setup_synology_prerequisites.yml @@ -0,0 +1,34 @@ +# SPDX-FileCopyrightText: 2026 Chiu Ki Sit +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Ensure requests Python package is constrained for Docker SDK compatibility (Synology) + ansible.builtin.pip: + name: "{{ matrix_base_synology_requests_version_constraint }}" + state: present + +# Determine whether the volume is already a shared mount, so that the +# make-shared command below only runs (and only reports `changed`) when it +# actually needs to. We read /proc/self/mountinfo (always present on Linux) +# and look for the ` shared:` optional tag on the volume's mount point line. +# grep exits non-zero on no-match or any error, so the make-shared command is +# skipped only when shared propagation is positively confirmed; every other +# case falls through to running it (which is idempotent). +- name: Determine current mount propagation of the Synology volume + ansible.builtin.command: grep -E ' {{ matrix_base_synology_volume_path }} .* shared:' /proc/self/mountinfo + register: matrix_base_synology_volume_propagation + changed_when: false + failed_when: false + +# Run immediately during setup so matrix services can start without a manual +# step. The boot-fix service handles this on every subsequent reboot. +# noqa command-instead-of-module: ansible.builtin.mount does not support +# changing mount propagation (--make-shared); command is the only option here. +- name: Ensure the Synology volume has shared mount propagation + ansible.builtin.command: mount --make-shared {{ matrix_base_synology_volume_path }} # noqa command-instead-of-module + when: matrix_base_synology_volume_propagation.rc != 0 + changed_when: true + +- ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_synology_boot_fix.yml" diff --git a/roles/custom/matrix-base/tasks/validate_config.yml b/roles/custom/matrix-base/tasks/validate_config.yml index 237bcec00..45df63ddc 100644 --- a/roles/custom/matrix-base/tasks/validate_config.yml +++ b/roles/custom/matrix-base/tasks/validate_config.yml @@ -13,7 +13,7 @@ - name: Fail if invalid homeserver implementation ansible.builtin.fail: msg: "You need to set a valid homeserver implementation in `matrix_homeserver_implementation`" - when: "matrix_homeserver_implementation not in ['synapse', 'dendrite', 'conduit', 'continuwuity']" + when: "matrix_homeserver_implementation not in ['synapse', 'dendrite', 'conduit', 'continuwuity', 'tuwunel']" - name: (Deprecation) Catch and report renamed settings ansible.builtin.fail: diff --git a/roles/custom/matrix-base/templates/bin/matrix-synology-boot-fix.j2 b/roles/custom/matrix-base/templates/bin/matrix-synology-boot-fix.j2 new file mode 100755 index 000000000..9970c17a2 --- /dev/null +++ b/roles/custom/matrix-base/templates/bin/matrix-synology-boot-fix.j2 @@ -0,0 +1,54 @@ +#!/bin/sh +# SPDX-FileCopyrightText: 2026 Chiu Ki Sit +# +# SPDX-License-Identifier: AGPL-3.0-or-later +# +# Boot recovery for Matrix services on Synology DSM. +# +# This script runs after multi-user.target (outside Container Manager's dependency +# chain) and does two things: +# +# 1. Makes {{ matrix_base_synology_volume_path }} mount-shared so Docker bind-propagation=slave mounts work. +# Inserting this into the systemd chain Before=pkg-ContainerManager-dockerd.service +# causes Container Manager to detect a broken dependency and prompt for repair, +# so it must run here instead, after Docker is already up. +# +# 2. Starts any enabled matrix-*.service that systemd skipped at boot. +# Synology's systemd drops services with multi-level dependency chains +# (e.g. traefik -> socket-proxy -> docker) from the boot activation queue. +# Services that need bind-propagation=slave (e.g. matrix-synapse) are +# created after step 1, so the propagation is already in effect. + +# Wait up to 120s for Docker to be ready +i=0 +while [ "$i" -lt 60 ]; do + {{ devture_systemd_docker_base_host_command_docker }} info >/dev/null 2>&1 && break + i=$((i + 1)) + sleep 2 +done + +if ! {{ devture_systemd_docker_base_host_command_docker }} info >/dev/null 2>&1; then + echo "matrix-synology-boot-fix: Docker not ready after 120s, aborting" >&2 + exit 1 +fi + +# Make {{ matrix_base_synology_volume_path }} shared so Docker bind-propagation=slave mounts work correctly. +# Must run after Docker is up to avoid interfering with Container Manager's +# integrity checks, but before matrix-synapse (and any other service using +# bind-propagation=slave) creates its containers. +/bin/mount --make-shared {{ matrix_base_synology_volume_path }} +echo "matrix-synology-boot-fix: {{ matrix_base_synology_volume_path }} set to shared mount propagation" + +# Start any enabled matrix-*.service that is inactive or failed. +# Both states indicate the service did not come up at boot — either skipped by +# Synology's boot ordering or failed due to Docker/mount-propagation not being +# ready yet (the conditions above now satisfy those prerequisites). +{{ devture_systemd_docker_base_host_command_systemctl }} list-unit-files 'matrix-*.service' --state=enabled --no-legend 2>/dev/null | \ + while read -r unit _state; do + [ "$unit" = "matrix-synology-boot-fix.service" ] && continue + status="$({{ devture_systemd_docker_base_host_command_systemctl }} is-active "$unit" 2>/dev/null)" + if [ "$status" = "inactive" ] || [ "$status" = "failed" ]; then + echo "matrix-synology-boot-fix: starting $unit (was $status)" + {{ devture_systemd_docker_base_host_command_systemctl }} start "$unit" + fi + done diff --git a/roles/custom/matrix-base/templates/systemd/matrix-synology-boot-fix.service.j2 b/roles/custom/matrix-base/templates/systemd/matrix-synology-boot-fix.service.j2 new file mode 100644 index 000000000..f6db14fcd --- /dev/null +++ b/roles/custom/matrix-base/templates/systemd/matrix-synology-boot-fix.service.j2 @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: 2026 Chiu Ki Sit +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +[Unit] +Description=Matrix Services Boot Recovery (Synology) +# Run after multi-user.target so all matrix services have been attempted first. +After=multi-user.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart={{ matrix_bin_path }}/matrix-synology-boot-fix + +[Install] +WantedBy=multi-user.target diff --git a/roles/custom/matrix-bot-baibot/defaults/main.yml b/roles/custom/matrix-bot-baibot/defaults/main.yml index afb31621f..b6f1e9231 100644 --- a/roles/custom/matrix-bot-baibot/defaults/main.yml +++ b/roles/custom/matrix-bot-baibot/defaults/main.yml @@ -17,12 +17,11 @@ matrix_bot_baibot_container_repo_version: "{{ 'main' if matrix_bot_baibot_versio matrix_bot_baibot_container_src_files_path: "{{ matrix_base_data_path }}/baibot/container-src" # renovate: datasource=docker depName=ghcr.io/etkecc/baibot -matrix_bot_baibot_version: v1.17.0 +matrix_bot_baibot_version: v1.26.0 matrix_bot_baibot_container_image: "{{ matrix_bot_baibot_container_image_registry_prefix }}etkecc/baibot:{{ matrix_bot_baibot_version }}" matrix_bot_baibot_container_image_registry_prefix: "{{ 'localhost/' if matrix_bot_baibot_container_image_self_build else matrix_bot_baibot_container_image_registry_prefix_upstream }}" matrix_bot_baibot_container_image_registry_prefix_upstream: "{{ matrix_bot_baibot_container_image_registry_prefix_upstream_default }}" matrix_bot_baibot_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_bot_baibot_container_image_force_pull: "{{ matrix_bot_baibot_container_image.endswith(':latest') }}" matrix_bot_baibot_base_path: "{{ matrix_base_data_path }}/baibot" matrix_bot_baibot_config_path: "{{ matrix_bot_baibot_base_path }}/config" @@ -201,6 +200,12 @@ matrix_bot_baibot_config_agents_static_definitions_auto: |- 'provider': matrix_bot_baibot_config_agents_static_definitions_openai_provider, 'config': matrix_bot_baibot_config_agents_static_definitions_openai_config, }] if matrix_bot_baibot_config_agents_static_definitions_openai_enabled else []) + + + ([{ + 'id': matrix_bot_baibot_config_agents_static_definitions_venice_id, + 'provider': matrix_bot_baibot_config_agents_static_definitions_venice_provider, + 'config': matrix_bot_baibot_config_agents_static_definitions_venice_config, + }] if matrix_bot_baibot_config_agents_static_definitions_venice_enabled else []) }} matrix_bot_baibot_config_agents_static_definitions_custom: [] @@ -400,7 +405,9 @@ matrix_bot_baibot_config_agents_static_definitions_openai_config_extension_yaml: matrix_bot_baibot_config_agents_static_definitions_openai_config_base_url: https://api.openai.com/v1 -# The API key is intentionally not required. Some OpenAI-compatible APIs do not require a key. +# Required when this provider is enabled. +# For OpenAI-compatible APIs that need no key, baibot has a separate `openai_compat` provider, +# which this role does not expose. matrix_bot_baibot_config_agents_static_definitions_openai_config_api_key: "" matrix_bot_baibot_config_agents_static_definitions_openai_config_text_generation_enabled: true @@ -431,7 +438,7 @@ matrix_bot_baibot_config_agents_static_definitions_openai_config_text_to_speech_ matrix_bot_baibot_config_agents_static_definitions_openai_config_text_to_speech_response_format: opus matrix_bot_baibot_config_agents_static_definitions_openai_config_image_generation_enabled: true -matrix_bot_baibot_config_agents_static_definitions_openai_config_image_generation_model_id: gpt-image-1.5 +matrix_bot_baibot_config_agents_static_definitions_openai_config_image_generation_model_id: gpt-image-2.5-sunburst matrix_bot_baibot_config_agents_static_definitions_openai_config_image_generation_style: null matrix_bot_baibot_config_agents_static_definitions_openai_config_image_generation_size: null matrix_bot_baibot_config_agents_static_definitions_openai_config_image_generation_quality: null @@ -443,6 +450,175 @@ matrix_bot_baibot_config_agents_static_definitions_openai_config_image_generatio ######################################################################################## +######################################################################################## +# # +# Venice agent configuration # +# # +######################################################################################## + +matrix_bot_baibot_config_agents_static_definitions_venice_enabled: false +matrix_bot_baibot_config_agents_static_definitions_venice_id: venice +matrix_bot_baibot_config_agents_static_definitions_venice_provider: venice + +matrix_bot_baibot_config_agents_static_definitions_venice_config: "{{ matrix_bot_baibot_config_agents_static_definitions_venice_config_yaml | from_yaml | combine(matrix_bot_baibot_config_agents_static_definitions_venice_config_extension, recursive=True) }}" + +matrix_bot_baibot_config_agents_static_definitions_venice_config_yaml: "{{ lookup('template', 'templates/provider/venice-config.yml.j2') }}" + +matrix_bot_baibot_config_agents_static_definitions_venice_config_extension: "{{ matrix_bot_baibot_config_agents_static_definitions_venice_config_extension_yaml | from_yaml if matrix_bot_baibot_config_agents_static_definitions_venice_config_extension_yaml | from_yaml is mapping else {} }}" + +matrix_bot_baibot_config_agents_static_definitions_venice_config_extension_yaml: | + # Your custom YAML configuration for this provider's configuration goes here. + # This configuration extends the default starting configuration (`matrix_bot_baibot_config_agents_static_definitions_venice_config`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by + # completely redefining `matrix_bot_baibot_config_agents_static_definitions_venice_config_yaml`. + # + # The fully-commented sample config (every Venice knob, with explanations) lives at: + # https://github.com/etkecc/baibot/blob/main/docs/sample-provider-configs/venice.yml + # + # Example configuration extension follows: + # + # text_generation: + # venice_parameters: + # enable_web_search: "off" + +matrix_bot_baibot_config_agents_static_definitions_venice_config_base_url: https://api.venice.ai/api/v1 + +matrix_bot_baibot_config_agents_static_definitions_venice_config_api_key: "" + +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_enabled: true +# For valid model choices, see: https://docs.venice.ai/models/overview +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_model_id: kimi-k2-5 +# The prompt text to use (can be null or empty to not use a prompt). +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_prompt: "{{ matrix_bot_baibot_config_agents_static_definitions_prompt }}" +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_temperature: 1.0 +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_max_response_tokens: 4096 +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_max_context_tokens: 128000 +# How long Venice keeps the prompt prefix cached: "default", "extended", or "24h". +# "24h" makes a long, stable system prompt cheap across a day of conversations. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_prompt_cache_retention: 24h +# The optional top-level sampling and reasoning knobs below default to null, meaning the knob is +# omitted from the request and Venice applies its own server-side default. Set a value to override. +# Nucleus sampling, 0.0-1.0 (an alternative to temperature). +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_top_p: ~ +# Penalize tokens by how often they have already appeared, -2.0-2.0. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_frequency_penalty: ~ +# Penalize tokens that have appeared at all, -2.0-2.0. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_presence_penalty: ~ +# Penalize repetition; values above 1.0 discourage repeats. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_repetition_penalty: ~ +# Reasoning budget for models that support it: "low", "medium", or "high". +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_reasoning_effort: ~ +# Append the model's reasoning below the answer as a collapsible "Reasoning" block (folded by default). +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_show_reasoning: ~ + +# Venice-specific request parameters (the `venice_parameters` bag). Each non-null knob below is sent; +# a null knob is omitted, so Venice applies its own default. Omitting a knob is NOT the same as +# setting it to `false` (which actively sends `false`). +# Web search: "auto" (model decides), "on" (always), or "off". +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_web_search: auto +# Strip blocks from reasoning models so the user sees only the answer. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_strip_thinking_response: true +# Run in TEE-only mode (works across all models) instead of end-to-end-encrypted inference (only +# some models support it). TEE is still zero-retention private; this default keeps every model usable. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_e2ee: false +# Render web-search sources as readable citations in the reply. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_web_citations: ~ +# Let web search read full page content, not just snippets. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_web_scraping: ~ +# Prepend Venice's own system prompt alongside yours. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_include_venice_system_prompt: ~ +# Include search results inline in the streamed response. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_include_search_results_in_stream: ~ +# Return search results as documents rather than inline text. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_return_search_results_as_documents: ~ +# Allow web search to query X (Twitter). +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_x_search: ~ +# Disable the model's thinking phase entirely. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_disable_thinking: ~ +# Response verbosity for models that support it: "low", "medium", or "high". +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_verbosity: ~ +# Use a public Venice character by its slug. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_character_slug: ~ + +matrix_bot_baibot_config_agents_static_definitions_venice_config_speech_to_text_enabled: true +matrix_bot_baibot_config_agents_static_definitions_venice_config_speech_to_text_model_id: nvidia/parakeet-tdt-0.6b-v3 + +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_enabled: true +# Other models include tts-qwen3-1-7b, tts-xai-v1, tts-elevenlabs-turbo-v2-5, tts-minimax-speech-02-hd. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_model_id: tts-kokoro +# Voices are model-specific. Kokoro uses af_*/am_*/bf_*/bm_* (e.g. af_sky, am_adam). You can also pass +# a cloned-voice handle (vv_). An incompatible voice returns an error. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_voice: af_sky +# Output audio format: mp3, opus, aac, flac, wav, or pcm. mp3 is the broadest Matrix-client fit. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_response_format: mp3 +# The optional knobs below default to null (omitted). Set a value to override Venice's default. +# Playback speed, 0.25-4.0 (1.0 is normal). +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_speed: ~ +# A style prompt steering emotion/delivery (e.g. "Excited and energetic."). Only Qwen 3 TTS uses it. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_prompt: ~ +# Sampling temperature, 0.0-2.0. Only Qwen 3 / Orpheus / Chatterbox HD use it. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_temperature: ~ +# Nucleus sampling, 0.0-1.0. Only Qwen 3 TTS uses it. +matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_top_p: ~ + +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_enabled: true +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_model_id: chroma +# The optional generation knobs below default to null (omitted). Set a value to override Venice's +# default. Omitting a knob is NOT the same as setting it: an omitted knob lets Venice apply its own +# default, a set value is sent verbatim. +# A description of what should NOT appear in the image. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_negative_prompt: ~ +# CFG scale, 0-20. Higher values make the image adhere more closely to the prompt. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_cfg_scale: ~ +# Number of inference steps. Model-specific; some models ignore it. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_steps: ~ +# A named style to apply (e.g. "3D Model"). See Venice's image-styles reference. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_style_preset: ~ +# Random seed, -999999999-999999999. Fix it for reproducible results; omit for a random seed. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_seed: ~ +# Blur images classified as adult content. Defaults to true. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_safe_mode: ~ +# Hide the Venice watermark. Venice may ignore this for certain generated content. Defaults to false. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_hide_watermark: ~ +# Output format: jpeg, png, or webp. webp is smallest; png is highest-quality. Defaults to webp. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_format: ~ +# Image dimensions in pixels, each 1-1280. Default 1024x1024. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_width: ~ +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_height: ~ +# Aspect ratio (used by certain models, e.g. Nano Banana): "1:1", "16:9". An alternative to width/height. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_aspect_ratio: ~ +# Resolution tier (used by certain models): "1K", "2K", "4K". +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_resolution: ~ +# Output quality for supported models (e.g. GPT Image 2): low, medium, high. Higher can cost more. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_quality: ~ +# Lora strength, 0-100. Only applies if the model uses additional Loras. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_lora_strength: ~ +# Embed the generation prompt into the image's EXIF metadata. Defaults to false. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_embed_exif_metadata: ~ +# Let the model pull the latest info from the web for the image. Model-specific; costs extra credits. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_enable_web_search: ~ +# Image editing shares this image_generation config block; only the model differs. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_model_id: firered-image-edit +# The optional edit knobs below default to null (omitted). Set a value to override Venice's default. +# Output format: jpeg, png, or webp. When omitted, Venice infers it (PNG at 1K, JPEG at 2K/4K). +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_output_format: ~ +# Aspect ratio of the result: auto, 1:1, 3:2, 16:9, 21:9, 9:16, 2:3, 3:4, 4:5 (model-specific). +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_aspect_ratio: ~ +# Resolution tier: 1K, 2K, 4K (model-specific). Defaults to 1K. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_resolution: ~ +# Blur images classified as adult content. Defaults to true. +matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_safe_mode: ~ + +######################################################################################## +# # +# /Venice agent configuration # +# # +######################################################################################## + + # Controls the `initial_global_config.handler.catch_all` configuration setting. # # This is an initial global configuration setting. diff --git a/roles/custom/matrix-bot-baibot/molecule/default/converge.yml b/roles/custom/matrix-bot-baibot/molecule/default/converge.yml new file mode 100644 index 000000000..fe6a6e238 --- /dev/null +++ b/roles/custom/matrix-bot-baibot/molecule/default/converge.yml @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# The devture base roles carry the variables this role reads, the same way they do when +# the playbook runs. `matrix-base` is deliberately NOT included: it does far more than this +# role needs, and what it would supply comes from molecule-shared/playbook-context.yml. +- name: Include roles for matrix-bot-baibot Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-bot-baibot Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +# The role installs the unit but does not start it; in the playbook that is +# `systemd_service_manager`'s job. +- name: Ensure matrix-bot-baibot is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure matrix-bot-baibot systemd service is started + ansible.builtin.systemd_service: + name: matrix-bot-baibot.service + state: started diff --git a/roles/custom/matrix-bot-baibot/molecule/default/molecule.yml b/roles/custom/matrix-bot-baibot/molecule/default/molecule.yml new file mode 100644 index 000000000..5425ab70d --- /dev/null +++ b/roles/custom/matrix-bot-baibot/molecule/default/molecule.yml @@ -0,0 +1,86 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-bot-baibot-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bot_baibot_container_network: matrix-bot-baibot-molecule + + # verify.yml runs as its own play, where the role's defaults are out of scope, + # so the paths it reads are pinned here to match what the role derives. + matrix_bot_baibot_base_path: /matrix/baibot + matrix_bot_baibot_config_path: /matrix/baibot/config + matrix_bot_baibot_data_path: /matrix/baibot/data + + # baibot is a plain Matrix client, not an appservice: it logs in with a password + # and then syncs, so a homeserver has to answer for it to get anywhere. + matrix_bot_baibot_config_homeserver_url: http://matrix.molecule.local:8008 + + # Deliberately different from the role's defaults AND from baibot's own, so a passing + # assertion cannot be explained by "it would have happened anyway". + matrix_bot_baibot_config_user_mxid_localpart: molecule-baibot + matrix_bot_baibot_config_user_name: Molecule baibot + matrix_bot_baibot_config_user_password: molecule_baibot_password_5b7c14 + matrix_bot_baibot_config_command_prefix: "!molecule-bai" + matrix_bot_baibot_config_room_post_join_self_introduction_enabled: false + matrix_bot_baibot_config_access_admin_patterns: + - "@molecule-admin:molecule.local" + + # `debug` rather than the role's `info`, so the journal carries what the bot loaded. + matrix_bot_baibot_config_logging_level_baibot: debug + + # A scenario must not need an AI provider account, and does not have to: providers are + # contacted only when a message asks an agent to do something, never at startup. + # So the agent below carries a placeholder key and a base URL that resolves nowhere. + # Nothing is ever called, yet the definition still has to survive baibot's startup + # parsing - which is what proves the role's provider templating produced something + # the bot accepts. + matrix_bot_baibot_config_agents_static_definitions_anthropic_enabled: true + matrix_bot_baibot_config_agents_static_definitions_anthropic_id: molecule-anthropic + matrix_bot_baibot_config_agents_static_definitions_anthropic_config_base_url: http://molecule-no-such-provider.invalid/v1 + matrix_bot_baibot_config_agents_static_definitions_anthropic_config_api_key: molecule-placeholder-not-a-real-key + matrix_bot_baibot_config_agents_static_definitions_anthropic_config_text_generation_model_id: molecule-model-4-2 + matrix_bot_baibot_config_agents_static_definitions_anthropic_config_text_generation_temperature: 0.25 + matrix_bot_baibot_config_agents_static_definitions_anthropic_config_text_generation_max_response_tokens: 1234 + matrix_bot_baibot_config_agents_static_definitions_anthropic_config_text_generation_max_context_tokens: 56789 + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bot-baibot/molecule/default/prepare.yml b/roles/custom/matrix-bot-baibot/molecule/default/prepare.yml new file mode 100644 index 000000000..949a0e7d7 --- /dev/null +++ b/roles/custom/matrix-bot-baibot/molecule/default/prepare.yml @@ -0,0 +1,82 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-bot-baibot Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks set owner/group by name, which Ansible resolves through the + # passwd database, so they have to exist first. `matrix-base` creates them for real. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bot_baibot_container_network }}" + register: matrix_bot_baibot_molecule_network + changed_when: matrix_bot_baibot_molecule_network.rc == 0 + failed_when: + - matrix_bot_baibot_molecule_network.rc != 0 + - "'already exists' not in matrix_bot_baibot_molecule_network.stderr" + + # baibot logs in and then syncs forever; with no homeserver answering it never gets past + # login. The shared stub is enough - see molecule-shared/homeserver-stub.py for what it is not. + # + # Told to claim the bot's own MXID, because the bot resolves who it is from what the + # homeserver hands back at login, and its profile and own-message filtering hang off that. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bot_baibot_container_network }}" + molecule_shared_stub_user_id: "@{{ matrix_bot_baibot_config_user_mxid_localpart }}:{{ matrix_domain }}" diff --git a/roles/custom/matrix-bot-baibot/molecule/default/requirements.yml b/roles/custom/matrix-bot-baibot/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bot-baibot/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bot-baibot/molecule/default/verify.yml b/roles/custom/matrix-bot-baibot/molecule/default/verify.yml new file mode 100644 index 000000000..00a68a6af --- /dev/null +++ b/roles/custom/matrix-bot-baibot/molecule/default/verify.yml @@ -0,0 +1,231 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Verify matrix-bot-baibot + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + + tasks: + # Read from the role's own defaults rather than pinned in molecule.yml, so the version + # assertion compares the running image against what defaults/main.yml ships. + # Pinning it here would make that assertion compare the scenario with itself. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_bot_baibot_role_defaults + + - name: Wait for the matrix-bot-baibot service to become active + ansible.builtin.systemd_service: + name: matrix-bot-baibot.service + register: matrix_bot_baibot_service + until: matrix_bot_baibot_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # `Restart=always` means a crash-looping container still reports `active`, so the restart + # counter is checked too. Asserted `is defined` because `| int` turns a missing property + # into 0 and would pass vacuously. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - matrix_bot_baibot_service.status.ActiveState == 'active' + - matrix_bot_baibot_service.status.NRestarts is defined + - matrix_bot_baibot_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-bot-baibot.service is + {{ matrix_bot_baibot_service.status.ActiveState | default('unknown') }} + after {{ matrix_bot_baibot_service.status.NRestarts | default('?') }} + automatic restart(s) + success_msg: "matrix-bot-baibot.service is active and has not restarted" + + # baibot is a Matrix client, not a server, so what it says about itself has to come from + # its output. The unit runs `docker start --attach`, so `--log-driver=none` does not stop + # the journal from carrying it. + # + # `Syncing..` is what carries this scenario, not the unit check above. baibot does not exit + # when startup goes wrong: a profile step it cannot complete is retried forever with a + # growing delay, so the unit stays `active` with `NRestarts` at 0 while the bot never + # reaches its message loop. Point the avatar at a missing file and the assertion above + # still passes; this one does not. + - name: Wait for baibot to reach its sync loop + ansible.builtin.shell: + cmd: >- + set -o pipefail && journalctl -u matrix-bot-baibot.service --no-pager -o cat + | sed -e 's/\x1b\[[0-9;]*m//g' + executable: /bin/bash + register: matrix_bot_baibot_journal + changed_when: false + until: "'Syncing..' in matrix_bot_baibot_journal.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert baibot got past startup and into its sync loop + ansible.builtin.assert: + that: + - "'Syncing..' in matrix_bot_baibot_journal.stdout" + - "'Failed to prepare profile' not in matrix_bot_baibot_journal.stdout" + fail_msg: >- + baibot never reached its sync loop; it is still in startup or stuck + retrying profile setup + success_msg: "baibot got past startup and is syncing" + + # The scenario's display name is neither the role's default nor what the stub reports the + # account already has, so the bot wanting it can only have come from what the role rendered. + - name: Assert the display name the role configured reached the process + ansible.builtin.assert: + that: + - >- + 'desired_display_name="' ~ matrix_bot_baibot_config_user_name ~ '"' + in matrix_bot_baibot_journal.stdout + fail_msg: >- + baibot did not report {{ matrix_bot_baibot_config_user_name }} as the + display name it wants, so `user.name` did not reach the process + success_msg: "baibot acts on the display name the role configured" + + # `logging` is one string carrying per-target levels, so proving it arrived means proving + # different targets ended up at different levels. A single global level satisfies neither half. + # + # First clause: baibot's own records appear at DEBUG, which the role's default of `info` + # would not produce. + # + # Second clause is the control, and it is not vacuous. At DEBUG the crates underneath are + # extremely talkative, so raising the catch-all turns these two records into roughly a + # hundred. Their silence is the `warn` catch-all being enforced. + # + # The trap here: a control on mxlink was tried first, and mxlink emits no DEBUG records at + # all on a first run - so asserting their absence passed just as happily with mxlink set + # to `debug`. + - name: Assert the per-target logging levels reached the process + ansible.builtin.assert: + that: + - matrix_bot_baibot_debug_lines | select('search', 'baibot::') | list | length > 0 + - matrix_bot_baibot_debug_lines | reject('search', 'baibot::') | list | length == 0 + fail_msg: >- + The rendered `logging` string did not take effect: + {{ matrix_bot_baibot_debug_lines | length }} DEBUG record(s), of which + {{ matrix_bot_baibot_debug_lines | select('search', 'baibot::') | list | length }} + from baibot itself + success_msg: >- + baibot logs at DEBUG while everything under it stays at the catch-all + level, as the rendered `logging` string asks + vars: + matrix_bot_baibot_debug_lines: >- + {{ matrix_bot_baibot_journal.stdout_lines | select('search', ' DEBUG ') | list }} + + - name: Read the configuration file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_baibot_config_path }}/config.yml" + register: matrix_bot_baibot_config_file + + - name: Assert the rendered configuration carries this scenario's Matrix settings + ansible.builtin.assert: + that: + - matrix_bot_baibot_config.homeserver.server_name == matrix_domain + - matrix_bot_baibot_config.homeserver.url == matrix_bot_baibot_config_homeserver_url + - matrix_bot_baibot_config.user.mxid_localpart == matrix_bot_baibot_config_user_mxid_localpart + - matrix_bot_baibot_config.user.name == matrix_bot_baibot_config_user_name + - matrix_bot_baibot_config.command_prefix == matrix_bot_baibot_config_command_prefix + - matrix_bot_baibot_config.room.post_join_self_introduction_enabled is false + - matrix_bot_baibot_config.access.admin_patterns == matrix_bot_baibot_config_access_admin_patterns + - matrix_bot_baibot_config.initial_global_config.user_patterns == ['@*:' ~ matrix_domain] + fail_msg: "The rendered configuration does not carry the scenario's Matrix settings" + success_msg: "The rendered configuration carries the scenario's Matrix settings" + vars: + matrix_bot_baibot_config: "{{ matrix_bot_baibot_config_file.content | b64decode | from_yaml }}" + + # The role refuses a configuration that sets both authentication modes. This scenario uses + # password mode, so the access-token keys must render as nulls, not be omitted or set. + - name: Assert only the password authentication mode is rendered + ansible.builtin.assert: + that: + - matrix_bot_baibot_config.user.password == matrix_bot_baibot_config_user_password + - matrix_bot_baibot_config.user.access_token is none + - matrix_bot_baibot_config.user.device_id is none + fail_msg: "The rendered configuration does not use password authentication exclusively" + success_msg: "The rendered configuration uses password authentication exclusively" + vars: + matrix_bot_baibot_config: "{{ matrix_bot_baibot_config_file.content | b64decode | from_yaml }}" + + # The agent presets are the most involved templating in this role: a per-provider template + # rendered to YAML, parsed, merged with an extension, nested into the list. Asserted as a + # whole round trip, key by key. + # + # No provider is ever contacted. baibot calls one only when a message asks an agent to do + # something, and the base URL here resolves nowhere on purpose. + - name: Assert the statically-defined agent survived the provider templating + ansible.builtin.assert: + that: + - matrix_bot_baibot_agents | length == 1 + - matrix_bot_baibot_agent.id == matrix_bot_baibot_config_agents_static_definitions_anthropic_id + - matrix_bot_baibot_agent.provider == 'anthropic' + - matrix_bot_baibot_agent.config.base_url == matrix_bot_baibot_config_agents_static_definitions_anthropic_config_base_url + - matrix_bot_baibot_agent.config.api_key == matrix_bot_baibot_config_agents_static_definitions_anthropic_config_api_key + - matrix_bot_baibot_agent.config.text_generation.model_id == matrix_bot_baibot_config_agents_static_definitions_anthropic_config_text_generation_model_id + - matrix_bot_baibot_agent.config.text_generation.temperature == matrix_bot_baibot_config_agents_static_definitions_anthropic_config_text_generation_temperature + - matrix_bot_baibot_agent.config.text_generation.max_response_tokens == matrix_bot_baibot_config_agents_static_definitions_anthropic_config_text_generation_max_response_tokens + - matrix_bot_baibot_agent.config.text_generation.max_context_tokens == matrix_bot_baibot_config_agents_static_definitions_anthropic_config_text_generation_max_context_tokens + fail_msg: >- + The statically-defined agent is not what the role's preset variables ask + for: {{ matrix_bot_baibot_agents }} + success_msg: "The statically-defined agent carries the scenario's provider settings" + vars: + matrix_bot_baibot_agents: "{{ (matrix_bot_baibot_config_file.content | b64decode | from_yaml).agents.static_definitions }}" + matrix_bot_baibot_agent: "{{ matrix_bot_baibot_agents | first }}" + + - name: Read the container's runtime configuration + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-bot-baibot + - --format + - "{{ '{{' }} .Config.Image {{ '}}' }} {{ '{{' }} .Config.User {{ '}}' }}" + register: matrix_bot_baibot_container + changed_when: false + + - name: Assert the image carries the version defaults/main.yml pins + ansible.builtin.assert: + that: + - matrix_bot_baibot_role_defaults.matrix_bot_baibot_version in matrix_bot_baibot_container.stdout + fail_msg: >- + The running container is {{ matrix_bot_baibot_container.stdout }}, + which does not carry the pinned version + {{ matrix_bot_baibot_role_defaults.matrix_bot_baibot_version }} + success_msg: "The running container is the version defaults/main.yml pins" + + # The uid/gid come from outside the role and are deliberately not 1000, which the base + # image already uses, so this cannot pass by coinciding with the image's own user. + - name: Assert the container runs as the identity the playbook supplies + ansible.builtin.assert: + that: + - "matrix_user_uid ~ ':' ~ matrix_user_gid in matrix_bot_baibot_container.stdout" + fail_msg: >- + The container does not run as {{ matrix_user_uid }}:{{ matrix_user_gid }} + ({{ matrix_bot_baibot_container.stdout }}) + success_msg: "The container runs as the uid/gid the playbook supplies" + + # baibot keeps its session and crypto store here. The file existing proves the bind mount + # is writable by the user the container runs as. + - name: Stat the session file baibot persists + ansible.builtin.stat: + path: "{{ matrix_bot_baibot_data_path }}/session.json" + register: matrix_bot_baibot_session_file + + - name: Assert baibot persisted its session as the matrix user + ansible.builtin.assert: + that: + - matrix_bot_baibot_session_file.stat.exists + - matrix_bot_baibot_session_file.stat.uid | int == matrix_user_uid | int + fail_msg: >- + {{ matrix_bot_baibot_data_path }}/session.json is missing or not owned + by uid {{ matrix_user_uid }} + success_msg: "baibot persisted its session into the data path as the matrix user" diff --git a/roles/custom/matrix-bot-baibot/tasks/install.yml b/roles/custom/matrix-bot-baibot/tasks/install.yml index 7ae2c25b0..db77eac90 100644 --- a/roles/custom/matrix-bot-baibot/tasks/install.yml +++ b/roles/custom/matrix-bot-baibot/tasks/install.yml @@ -38,11 +38,9 @@ register: matrix_bot_baibot_env_result - name: Ensure baibot container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_bot_baibot_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_bot_baibot_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_baibot_container_image_force_pull }}" + pull: always when: "not matrix_bot_baibot_container_image_self_build | bool" register: matrix_bot_baibot_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -51,6 +49,15 @@ - when: "matrix_bot_baibot_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure baibot repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bot_baibot_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure baibot repository is present on self-build ansible.builtin.git: repo: "{{ matrix_bot_baibot_container_repo }}" @@ -62,17 +69,16 @@ register: matrix_bot_baibot_git_pull_results - name: Ensure baibot container image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_bot_baibot_container_image }}" - source: build - force_source: "{{ matrix_bot_baibot_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_baibot_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_bot_baibot_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_bot_baibot_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bot_baibot_git_pull_results.changed | bool else 'never' }}" + register: matrix_bot_baibot_container_image_build_result - name: Ensure baibot container network is created + when: matrix_bot_baibot_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_bot_baibot_container_network }}" @@ -94,4 +100,5 @@ or matrix_bot_baibot_env_result.changed | default(false) or matrix_bot_baibot_systemd_service_result.changed | default(false) or matrix_bot_baibot_container_image_pull_result.changed | default(false) + or matrix_bot_baibot_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-bot-baibot/tasks/validate_config.yml b/roles/custom/matrix-bot-baibot/tasks/validate_config.yml index c6eca9657..cf6636403 100644 --- a/roles/custom/matrix-bot-baibot/tasks/validate_config.yml +++ b/roles/custom/matrix-bot-baibot/tasks/validate_config.yml @@ -25,6 +25,8 @@ - {'name': 'matrix_bot_baibot_config_agents_static_definitions_openai_config_api_key', when: "{{ matrix_bot_baibot_config_agents_static_definitions_openai_enabled }}"} + - {'name': 'matrix_bot_baibot_config_agents_static_definitions_venice_config_api_key', when: "{{ matrix_bot_baibot_config_agents_static_definitions_venice_enabled }}"} + - name: Fail if baibot authentication mode is not configured ansible.builtin.fail: msg: >- @@ -91,3 +93,4 @@ when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - {'old': 'matrix_bot_baibot_container_image_name_prefix', 'new': 'matrix_bot_baibot_container_image_registry_prefix'} + - {'old': 'matrix_bot_baibot_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-bot-baibot/templates/provider/venice-config.yml.j2 b/roles/custom/matrix-bot-baibot/templates/provider/venice-config.yml.j2 new file mode 100644 index 000000000..5cfd8352f --- /dev/null +++ b/roles/custom/matrix-bot-baibot/templates/provider/venice-config.yml.j2 @@ -0,0 +1,154 @@ +#jinja2: lstrip_blocks: True +base_url: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_base_url | to_json }} + +api_key: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_api_key | to_json }} + +{% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_enabled %} +text_generation: + model_id: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_model_id | to_json }} + prompt: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_prompt | to_json }} + temperature: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_temperature | to_json }} + max_response_tokens: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_max_response_tokens | int | to_json }} + max_context_tokens: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_max_context_tokens | int | to_json }} + prompt_cache_retention: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_prompt_cache_retention | to_json }} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_top_p is not none %} + top_p: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_top_p | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_frequency_penalty is not none %} + frequency_penalty: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_frequency_penalty | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_presence_penalty is not none %} + presence_penalty: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_presence_penalty | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_repetition_penalty is not none %} + repetition_penalty: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_repetition_penalty | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_reasoning_effort is not none %} + reasoning_effort: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_reasoning_effort | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_show_reasoning is not none %} + show_reasoning: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_show_reasoning | to_json }} + {% endif %} + venice_parameters: + enable_web_search: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_web_search | to_json }} + strip_thinking_response: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_strip_thinking_response | to_json }} + enable_e2ee: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_e2ee | to_json }} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_web_citations is not none %} + enable_web_citations: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_web_citations | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_web_scraping is not none %} + enable_web_scraping: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_web_scraping | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_include_venice_system_prompt is not none %} + include_venice_system_prompt: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_include_venice_system_prompt | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_include_search_results_in_stream is not none %} + include_search_results_in_stream: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_include_search_results_in_stream | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_return_search_results_as_documents is not none %} + return_search_results_as_documents: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_return_search_results_as_documents | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_x_search is not none %} + enable_x_search: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_enable_x_search | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_disable_thinking is not none %} + disable_thinking: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_disable_thinking | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_verbosity is not none %} + verbosity: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_verbosity | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_character_slug is not none %} + character_slug: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_generation_venice_parameters_character_slug | to_json }} + {% endif %} +{% endif %} + +{% if matrix_bot_baibot_config_agents_static_definitions_venice_config_speech_to_text_enabled %} +speech_to_text: + model_id: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_speech_to_text_model_id | to_json }} +{% endif %} + +{% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_enabled %} +text_to_speech: + model_id: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_model_id | to_json }} + voice: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_voice | to_json }} + response_format: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_response_format | to_json }} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_speed is not none %} + speed: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_speed | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_prompt is not none %} + prompt: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_prompt | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_temperature is not none %} + temperature: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_temperature | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_top_p is not none %} + top_p: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_text_to_speech_top_p | to_json }} + {% endif %} +{% endif %} + +{% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_enabled %} +image_generation: + model_id: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_model_id | to_json }} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_negative_prompt is not none %} + negative_prompt: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_negative_prompt | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_cfg_scale is not none %} + cfg_scale: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_cfg_scale | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_steps is not none %} + steps: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_steps | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_style_preset is not none %} + style_preset: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_style_preset | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_seed is not none %} + seed: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_seed | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_safe_mode is not none %} + safe_mode: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_safe_mode | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_hide_watermark is not none %} + hide_watermark: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_hide_watermark | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_format is not none %} + format: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_format | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_width is not none %} + width: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_width | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_height is not none %} + height: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_height | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_aspect_ratio is not none %} + aspect_ratio: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_aspect_ratio | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_resolution is not none %} + resolution: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_resolution | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_quality is not none %} + quality: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_quality | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_lora_strength is not none %} + lora_strength: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_lora_strength | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_embed_exif_metadata is not none %} + embed_exif_metadata: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_embed_exif_metadata | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_enable_web_search is not none %} + enable_web_search: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_enable_web_search | to_json }} + {% endif %} + edit: + model_id: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_model_id | to_json }} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_output_format is not none %} + output_format: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_output_format | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_aspect_ratio is not none %} + aspect_ratio: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_aspect_ratio | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_resolution is not none %} + resolution: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_resolution | to_json }} + {% endif %} + {% if matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_safe_mode is not none %} + safe_mode: {{ matrix_bot_baibot_config_agents_static_definitions_venice_config_image_generation_edit_safe_mode | to_json }} + {% endif %} +{% endif %} diff --git a/roles/custom/matrix-bot-baibot/templates/provider/venice-config.yml.j2.license b/roles/custom/matrix-bot-baibot/templates/provider/venice-config.yml.j2.license new file mode 100644 index 000000000..ed4a74493 --- /dev/null +++ b/roles/custom/matrix-bot-baibot/templates/provider/venice-config.yml.j2.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bot-baibot/templates/systemd/matrix-bot-baibot.service.j2 b/roles/custom/matrix-bot-baibot/templates/systemd/matrix-bot-baibot.service.j2 index e9b01fb0a..3483b086b 100644 --- a/roles/custom/matrix-bot-baibot/templates/systemd/matrix-bot-baibot.service.j2 +++ b/roles/custom/matrix-bot-baibot/templates/systemd/matrix-bot-baibot.service.j2 @@ -37,9 +37,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_bot_baibot_container_image }} +{% if matrix_bot_baibot_container_network != 'host' %} {% for network in matrix_bot_baibot_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-baibot {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-baibot diff --git a/roles/custom/matrix-bot-buscarron/defaults/main.yml b/roles/custom/matrix-bot-buscarron/defaults/main.yml index 3da905392..987fc7063 100644 --- a/roles/custom/matrix-bot-buscarron/defaults/main.yml +++ b/roles/custom/matrix-bot-buscarron/defaults/main.yml @@ -13,7 +13,7 @@ matrix_bot_buscarron_enabled: true # renovate: datasource=docker depName=ghcr.io/etkecc/buscarron -matrix_bot_buscarron_version: v1.4.3 +matrix_bot_buscarron_version: v1.5.0 # The hostname at which Buscarron is served. matrix_bot_buscarron_hostname: '' @@ -40,7 +40,6 @@ matrix_bot_buscarron_container_image: "{{ matrix_bot_buscarron_container_image_r matrix_bot_buscarron_container_image_registry_prefix: "{{ 'localhost/' if matrix_bot_buscarron_container_image_self_build else matrix_bot_buscarron_container_image_registry_prefix_upstream }}" matrix_bot_buscarron_container_image_registry_prefix_upstream: "{{ matrix_bot_buscarron_container_image_registry_prefix_upstream_default }}" matrix_bot_buscarron_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_bot_buscarron_container_image_force_pull: "{{ matrix_bot_buscarron_container_image.endswith(':latest') }}" # The base container network. It will be auto-created by this role if it doesn't exist already. matrix_bot_buscarron_container_network: matrix-bot-buscarron @@ -137,19 +136,15 @@ matrix_bot_buscarron_database_sslmode: disable matrix_bot_buscarron_database_connection_string: 'postgres://{{ matrix_bot_buscarron_database_username }}:{{ matrix_bot_buscarron_database_password }}@{{ matrix_bot_buscarron_database_hostname }}:{{ matrix_bot_buscarron_database_port }}/{{ matrix_bot_buscarron_database_name }}?sslmode={{ matrix_bot_buscarron_database_sslmode }}' -matrix_bot_buscarron_storage_database: "{{ - { - 'sqlite': matrix_bot_buscarron_sqlite_database_path_in_container, - 'postgres': matrix_bot_buscarron_database_connection_string, - }[matrix_bot_buscarron_database_engine] -}}" +matrix_bot_buscarron_storage_database: "{{ { + 'sqlite': matrix_bot_buscarron_sqlite_database_path_in_container, + 'postgres': matrix_bot_buscarron_database_connection_string, +}[matrix_bot_buscarron_database_engine] }}" -matrix_bot_buscarron_database_dialect: "{{ - { +matrix_bot_buscarron_database_dialect: "{{ { 'sqlite': 'sqlite3', 'postgres': 'postgres', - }[matrix_bot_buscarron_database_engine] -}}" +}[matrix_bot_buscarron_database_engine] }}" # The bot's username. This user needs to be created manually beforehand. diff --git a/roles/custom/matrix-bot-buscarron/tasks/setup_install.yml b/roles/custom/matrix-bot-buscarron/tasks/setup_install.yml index ea786046b..d37f77823 100644 --- a/roles/custom/matrix-bot-buscarron/tasks/setup_install.yml +++ b/roles/custom/matrix-bot-buscarron/tasks/setup_install.yml @@ -61,17 +61,25 @@ register: matrix_bot_buscarron_support_files_result - name: Ensure Buscarron image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_bot_buscarron_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_bot_buscarron_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_buscarron_container_image_force_pull }}" + pull: always when: "not matrix_bot_buscarron_container_image_self_build | bool" register: matrix_bot_buscarron_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_bot_buscarron_container_image_pull_result is not failed +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Buscarron repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bot_buscarron_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bot_buscarron_container_image_self_build | bool" + - name: Ensure Buscarron repository is present on self-build ansible.builtin.git: repo: "{{ matrix_bot_buscarron_container_repo }}" @@ -84,16 +92,14 @@ when: "matrix_bot_buscarron_container_image_self_build | bool" - name: Ensure Buscarron image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_bot_buscarron_container_image }}" - source: build - force_source: "{{ matrix_bot_buscarron_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_buscarron_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_bot_buscarron_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_bot_buscarron_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bot_buscarron_git_pull_results.changed | bool else 'never' }}" when: "matrix_bot_buscarron_container_image_self_build | bool" + register: matrix_bot_buscarron_container_image_build_result - name: Ensure matrix-bot-buscarron.service installed ansible.builtin.template: @@ -110,9 +116,11 @@ or matrix_bot_buscarron_support_files_result.changed | default(false) or matrix_bot_buscarron_systemd_service_result.changed | default(false) or matrix_bot_buscarron_container_image_pull_result.changed | default(false) + or matrix_bot_buscarron_container_image_build_result.changed | default(false) }} - name: Ensure Buscarron container network is created + when: matrix_bot_buscarron_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_bot_buscarron_container_network }}" diff --git a/roles/custom/matrix-bot-buscarron/tasks/validate_config.yml b/roles/custom/matrix-bot-buscarron/tasks/validate_config.yml index e0a52542c..23de5936f 100644 --- a/roles/custom/matrix-bot-buscarron/tasks/validate_config.yml +++ b/roles/custom/matrix-bot-buscarron/tasks/validate_config.yml @@ -19,6 +19,7 @@ - {'old': 'matrix_bot_buscarron_container_image_name_prefix', 'new': 'matrix_bot_buscarron_container_image_registry_prefix'} - {'old': 'matrix_bot_buscarron_docker_image', 'new': 'matrix_bot_buscarron_container_image'} - {'old': 'matrix_bot_buscarron_docker_image_force_pull', 'new': 'matrix_bot_buscarron_container_image_force_pull'} + - {'old': 'matrix_bot_buscarron_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - {'old': 'matrix_bot_buscarron_docker_image_registry_prefix', 'new': 'matrix_bot_buscarron_container_image_registry_prefix'} - {'old': 'matrix_bot_buscarron_docker_image_registry_prefix_upstream', 'new': 'matrix_bot_buscarron_container_image_registry_prefix_upstream'} - {'old': 'matrix_bot_buscarron_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bot_buscarron_container_image_registry_prefix_upstream_default'} diff --git a/roles/custom/matrix-bot-buscarron/templates/systemd/matrix-bot-buscarron.service.j2 b/roles/custom/matrix-bot-buscarron/templates/systemd/matrix-bot-buscarron.service.j2 index e108741d8..69c22f4c4 100644 --- a/roles/custom/matrix-bot-buscarron/templates/systemd/matrix-bot-buscarron.service.j2 +++ b/roles/custom/matrix-bot-buscarron/templates/systemd/matrix-bot-buscarron.service.j2 @@ -32,9 +32,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_bot_buscarron_container_image }} +{% if matrix_bot_buscarron_container_network != 'host' %} {% for network in matrix_bot_buscarron_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-buscarron {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-buscarron diff --git a/roles/custom/matrix-bot-draupnir/defaults/main.yml b/roles/custom/matrix-bot-draupnir/defaults/main.yml index c10024987..c586fe2be 100644 --- a/roles/custom/matrix-bot-draupnir/defaults/main.yml +++ b/roles/custom/matrix-bot-draupnir/defaults/main.yml @@ -11,24 +11,35 @@ matrix_bot_draupnir_enabled: true -# renovate: datasource=docker depName=gnuxie/draupnir -matrix_bot_draupnir_version: "v2.9.0" +# renovate: datasource=docker depName=ghcr.io/the-draupnir-project/draupnir +matrix_bot_draupnir_version: "v3.1.0" matrix_bot_draupnir_container_image_self_build: false matrix_bot_draupnir_container_image_self_build_repo: "https://github.com/the-draupnir-project/Draupnir.git" matrix_bot_draupnir_container_image: "{{ matrix_bot_draupnir_container_image_registry_prefix }}{{ matrix_bot_draupnir_container_image_registry_namespace_identifier }}:{{ matrix_bot_draupnir_version }}" -matrix_bot_draupnir_container_image_registry_namespace_identifier: "gnuxie/draupnir" +matrix_bot_draupnir_container_image_registry_namespace_identifier: "the-draupnir-project/draupnir" matrix_bot_draupnir_container_image_registry_prefix: "{{ 'localhost/' if matrix_bot_draupnir_container_image_self_build else matrix_bot_draupnir_container_image_registry_prefix_upstream }}" matrix_bot_draupnir_container_image_registry_prefix_upstream: "{{ matrix_bot_draupnir_container_image_registry_prefix_upstream_default }}" -matrix_bot_draupnir_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_bot_draupnir_container_image_force_pull: "{{ matrix_bot_draupnir_container_image.endswith(':latest') }}" +matrix_bot_draupnir_container_image_registry_prefix_upstream_default: "ghcr.io/" matrix_bot_draupnir_base_path: "{{ matrix_base_data_path }}/draupnir" matrix_bot_draupnir_config_path: "{{ matrix_bot_draupnir_base_path }}/config" matrix_bot_draupnir_data_path: "{{ matrix_bot_draupnir_base_path }}/data" matrix_bot_draupnir_container_src_files_path: "{{ matrix_bot_draupnir_base_path }}/docker-src" +# Rolling tag: true if version doesn't match semver shape (vX.Y.Z with optional prerelease/build), false otherwise. +matrix_bot_draupnir_rolling_tag: "{{ not (matrix_bot_draupnir_version is match('^v[0-9]+\\.[0-9]+\\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$')) }}" + +# Force restart the service on all runs only when both roles are enabled, both roles +# are using the same version string, and that version is a classified as a moving tag. +matrix_bot_draupnir_force_restart: "{{ + matrix_bot_draupnir_enabled | bool and + matrix_appservice_draupnir_for_all_enabled | bool and + matrix_bot_draupnir_version == matrix_appservice_draupnir_for_all_version and + matrix_bot_draupnir_rolling_tag | bool +}}" + matrix_bot_draupnir_config_web_enabled: "{{ matrix_bot_draupnir_config_web_abuseReporting or matrix_bot_draupnir_config_web_synapseHTTPAntispam_enabled }}" # noqa var-naming matrix_bot_draupnir_config_web_abuseReporting: false # noqa var-naming @@ -104,12 +115,36 @@ matrix_bot_draupnir_password: "{{ matrix_bot_draupnir_pantalaimon_password }}" # This configuration option does not follow the common naming schema as its not controlling a config key directly. matrix_bot_draupnir_login_native: false -# The room ID where people can use the bot. The bot has no access controls, so -# anyone in this room can use the bot - secure your room! +# This controls whether Zero Touch Deployment is enabled. +# When enabled, the playbook validates the settings and only +# renders the configuration values Draupnir expects. +# This prevents invalid manual combinations from being passed through, since +# Draupnir requires `matrix_bot_draupnir_config_managementRoom` to be unset and +# `matrix_bot_draupnir_config_initialManager` to be a valid MXID. +# Zero Touch Deployment is recommended for all new deployments. +# Deployments that are exempt from this recommendation are assumed to be +# advanced setups with specific needs for non-zero-touch mode. +# Note that enabling this on an existing deployment will cause the bot to +# recreate the management room. +# Recreating the management room will cause all protections to reset their settings to defaults +# and cause the recreation of secondary rooms like notification rooms. All bot memory will also be wiped. +matrix_bot_draupnir_zero_touch_deploy: false + +# The management room used for administration when Zero Touch +# Deployment is disabled. +# The bot has no access controls, so anyone in this room can use it - secure +# your room! # This should be a room alias or room ID - not a matrix.to URL. # Note: Draupnir is fairly verbose - expect a lot of messages from it. matrix_bot_draupnir_config_managementRoom: "" # noqa var-naming +# The MXID invited as the initial manager when Zero Touch Deployment creates the +# management room. +# This value is mutually exclusive with +# `matrix_bot_draupnir_config_managementRoom`, and the bot will crash if you +# attempt to set both at the same time. +matrix_bot_draupnir_config_initialManager: "" # noqa var-naming + # Endpoint URL that Draupnir uses to interact with the Matrix homeserver (client-server API). # Set this to the Pantalaimon URL if you're using that. matrix_bot_draupnir_config_homeserverUrl: "" # noqa var-naming @@ -185,7 +220,7 @@ matrix_bot_draupnir_configuration: "{{ matrix_bot_draupnir_configuration_yaml | # Regardless of whether this is enabled, it may or may not take effect due to the value of other variables. # See `matrix_synapse_container_labels_traefik_enabled` or `matrix_synapse_container_labels_matrix_related_labels_enabled` matrix_bot_draupnir_container_labels_traefik_enabled: false -matrix_bot_draupnir_container_labels_traefik_docker_network: "{{ matrix_draupnir_bot_container_network }}" +matrix_bot_draupnir_container_labels_traefik_docker_network: "{{ matrix_bot_draupnir_container_network }}" matrix_bot_draupnir_container_labels_web_abuseReporting_traefik_hostname: "{{ matrix_synapse_container_labels_traefik_hostname }}" # noqa var-naming matrix_bot_draupnir_container_labels_web_abuseReporting_traefik_path_regexp: "^/_matrix/client/(r0|v3)/rooms/([^/]*)/report/(.*)$" # noqa var-naming matrix_bot_draupnir_container_labels_web_abuseReporting_traefik_rule: "Host(`{{ matrix_bot_draupnir_container_labels_web_abuseReporting_traefik_hostname }}`) && PathRegexp(`{{ matrix_bot_draupnir_container_labels_web_abuseReporting_traefik_path_regexp }}`)" # noqa var-naming diff --git a/roles/custom/matrix-bot-draupnir/molecule/default/converge.yml b/roles/custom/matrix-bot-draupnir/molecule/default/converge.yml new file mode 100644 index 000000000..2654c9e8c --- /dev/null +++ b/roles/custom/matrix-bot-draupnir/molecule/default/converge.yml @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-bot-draupnir Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-bot-draupnir Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +# Component roles install their unit; the complete playbook's service manager starts it. +- name: Ensure matrix-bot-draupnir is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure matrix-bot-draupnir systemd service is started + ansible.builtin.systemd_service: + name: matrix-bot-draupnir.service + state: started diff --git a/roles/custom/matrix-bot-draupnir/molecule/default/molecule.yml b/roles/custom/matrix-bot-draupnir/molecule/default/molecule.yml new file mode 100644 index 000000000..bb1e26ad9 --- /dev/null +++ b/roles/custom/matrix-bot-draupnir/molecule/default/molecule.yml @@ -0,0 +1,110 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-bot-draupnir-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bot_draupnir_container_network: matrix-bot-draupnir-molecule + + # verify.yml is a separate play where the role's defaults are out of scope. Pin + # only paths it reads; the component version is loaded from defaults/main.yml. + matrix_bot_draupnir_base_path: /matrix/draupnir + matrix_bot_draupnir_config_path: /matrix/draupnir/config + matrix_bot_draupnir_data_path: /matrix/draupnir/data + + # Full-playbook context supplies the companion role's switch. It is deliberately + # absent here: this scenario tests the standalone bot, not the appservice variant. + matrix_appservice_draupnir_for_all_enabled: false + + # A local homeserver stub accepts this fake token. No real Matrix or third-party + # account is involved. The pre-existing room avoids zero-touch room creation. + matrix_bot_draupnir_config_accessToken: molecule_draupnir_access_token_48c1e7 + matrix_bot_draupnir_config_homeserverUrl: http://matrix.molecule.local:8008 + matrix_bot_draupnir_config_rawHomeserverUrl: http://matrix.molecule.local:8008 + matrix_bot_draupnir_config_managementRoom: "!draupnir-control:molecule.local" + matrix_bot_draupnir_zero_touch_deploy: false + matrix_bot_draupnir_pantalaimon_use: false + matrix_bot_draupnir_login_native: false + matrix_bot_draupnir_config_experimentalRustCrypto: false + + # Values differ from both role and upstream defaults. The extension also disables + # recovery safe mode: otherwise Draupnir can become healthy after a recoverable + # bootstrap failure without entering its normal moderation mode. + matrix_bot_draupnir_config_disableServerACL: true + matrix_bot_draupnir_config_roomStateBackingStore_enabled: false + matrix_bot_draupnir_config_web_abuseReporting: true + matrix_bot_draupnir_config_web_synapseHTTPAntispam_enabled: false + matrix_bot_draupnir_config_web_port: 18082 + matrix_bot_draupnir_config_displayReports: false + matrix_bot_draupnir_configuration_extension_yaml: | + logLevel: DEBUG + verifyPermissionsOnStartup: false + noop: true + backgroundDelayMS: 137 + commands: + allowNoPrefix: true + safeMode: + bootOption: Never + health: + healthz: + enabled: true + port: 18081 + address: 0.0.0.0 + endpoint: /molecule-ready + healthyStatus: 201 + unhealthyStatus: 503 + + # Traefik itself is not deployed. The role still renders these labels and Docker + # consumes them, proving the public-report routing contract and the derived network. + matrix_bot_draupnir_container_labels_traefik_enabled: true + matrix_bot_draupnir_container_labels_web_abuseReporting_traefik_hostname: draupnir-reports.molecule.local + matrix_bot_draupnir_container_labels_web_abuseReporting_traefik_path_regexp: ^/molecule-report/(v1)/rooms/([^/]*)/event/(.*)$$ + matrix_bot_draupnir_container_labels_web_abuseReporting_traefik_priority: 743 + matrix_bot_draupnir_container_labels_web_abuseReporting_traefik_entrypoints: web + matrix_bot_draupnir_container_labels_web_abuseReporting_traefik_tls: false + matrix_bot_draupnir_container_labels_traefik_labels_additional_labels: | + molecule.draupnir.coverage=enabled + + # Match the production-like no-host-port path; probes join the Docker network. + matrix_bot_draupnir_container_http_host_bind_port: '' + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bot-draupnir/molecule/default/prepare.yml b/roles/custom/matrix-bot-draupnir/molecule/default/prepare.yml new file mode 100644 index 000000000..771a8eeee --- /dev/null +++ b/roles/custom/matrix-bot-draupnir/molecule/default/prepare.yml @@ -0,0 +1,119 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-bot-draupnir Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # matrix-base creates this identity in the complete playbook. The component role's file + # tasks resolve owner/group by name, so the role-scoped scenario supplies that side effect. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # Draupnir and the stub need the network before the role's converge creates it. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bot_draupnir_container_network }}" + register: matrix_bot_draupnir_molecule_network + changed_when: matrix_bot_draupnir_molecule_network.rc == 0 + failed_when: + - matrix_bot_draupnir_molecule_network.rc != 0 + - "'already exists' not in matrix_bot_draupnir_molecule_network.stderr" + + # The bot must see itself joined to an existing management room. The create, member and + # power-level events are the minimum state Draupnir needs to validate that room and prove + # its own user can send state. No real homeserver or account is involved. + - name: Ensure the homeserver stub is running with Draupnir management-room state + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bot_draupnir_container_network }}" + molecule_shared_stub_user_id: "@draupnir:molecule.local" + molecule_shared_stub_joined_rooms: + - "{{ matrix_bot_draupnir_config_managementRoom }}" + molecule_shared_stub_verbose: "1" + molecule_shared_stub_room_state: + - type: m.room.create + state_key: '' + room_id: "{{ matrix_bot_draupnir_config_managementRoom }}" + sender: "@draupnir:molecule.local" + event_id: "$molecule-create" + origin_server_ts: 1 + content: + creator: "@draupnir:molecule.local" + room_version: "10" + - type: m.room.member + state_key: "@draupnir:molecule.local" + room_id: "{{ matrix_bot_draupnir_config_managementRoom }}" + sender: "@draupnir:molecule.local" + event_id: "$molecule-member" + origin_server_ts: 2 + content: + displayname: Molecule Draupnir + membership: join + - type: m.room.power_levels + state_key: '' + room_id: "{{ matrix_bot_draupnir_config_managementRoom }}" + sender: "@draupnir:molecule.local" + event_id: "$molecule-power" + origin_server_ts: 3 + content: + ban: 50 + events_default: 0 + invite: 50 + kick: 50 + redact: 50 + state_default: 50 + users: + "@draupnir:molecule.local": 100 + users_default: 0 diff --git a/roles/custom/matrix-bot-draupnir/molecule/default/requirements.yml b/roles/custom/matrix-bot-draupnir/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bot-draupnir/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bot-draupnir/molecule/default/verify.yml b/roles/custom/matrix-bot-draupnir/molecule/default/verify.yml new file mode 100644 index 000000000..258f429b7 --- /dev/null +++ b/roles/custom/matrix-bot-draupnir/molecule/default/verify.yml @@ -0,0 +1,298 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Health with safe mode disabled is the main readiness gate. Stub request evidence closes +# Draupnir's remaining blind spot: its health turns green after launching, but not awaiting, +# the SDK's first sync request. +- name: Verify matrix-bot-draupnir + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + matrix_bot_draupnir_rendered_config: "{{ matrix_bot_draupnir_config_file.content | b64decode | from_yaml }}" + matrix_bot_draupnir_labels_lines: "{{ (matrix_bot_draupnir_labels_file.content | b64decode).splitlines() }}" + matrix_bot_draupnir_runtime: "{{ (matrix_bot_draupnir_container_inspect.stdout | from_json) | first }}" + matrix_bot_draupnir_config_mounts: "{{ matrix_bot_draupnir_runtime.Mounts | selectattr('Destination', 'equalto', '/data/config') | list }}" + matrix_bot_draupnir_data_mounts: "{{ matrix_bot_draupnir_runtime.Mounts | selectattr('Destination', 'equalto', '/data') | list }}" + gather_facts: false + + tasks: + # Read the pin from the role rather than defining it in the scenario, so an image bump + # changes the expected value and exercises the newly shipped image. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_bot_draupnir_role_defaults + + - name: Wait for the matrix-bot-draupnir service to become active + ansible.builtin.systemd_service: + name: matrix-bot-draupnir.service + register: matrix_bot_draupnir_service + until: matrix_bot_draupnir_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes ActiveState alone insufficient for a crash-looping bot. + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_bot_draupnir_service.status.ActiveState == 'active' + - matrix_bot_draupnir_service.status.NRestarts is defined + - matrix_bot_draupnir_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-bot-draupnir.service is + {{ matrix_bot_draupnir_service.status.ActiveState | default('unknown') }} after + {{ matrix_bot_draupnir_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-bot-draupnir.service is active and has not restarted" + + # Probe over the role's own network. The non-default port and status are only reachable + # after normal-mode bootstrap because the scenario explicitly disables recovery safe mode. + - name: Wait for Draupnir to report healthy on the configured port + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_draupnir_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-bot-draupnir:18081/molecule-ready + register: matrix_bot_draupnir_health + changed_when: false + until: matrix_bot_draupnir_health.stdout == 'HTTP_STATUS=201' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert Draupnir reached its normal-mode health gate + ansible.builtin.assert: + that: + - matrix_bot_draupnir_health.rc == 0 + - matrix_bot_draupnir_health.stdout == 'HTTP_STATUS=201' + fail_msg: >- + Draupnir did not report the configured healthy status on port 18081 + (rc={{ matrix_bot_draupnir_health.rc }}, response={{ matrix_bot_draupnir_health.stdout | default('none') }}) + success_msg: "Draupnir reports healthy with the scenario's non-default status" + + - name: Wait for Draupnir to request an initial sync from the homeserver stub + ansible.builtin.command: + argv: + - docker + - logs + - matrix-homeserver-stub + register: matrix_bot_draupnir_stub_logs + changed_when: false + until: "'/sync?' in matrix_bot_draupnir_stub_logs.stderr or '/sync?' in matrix_bot_draupnir_stub_logs.stdout" + retries: 12 + delay: 5 + failed_when: false + + # These are observations of Draupnir's outbound bootstrap, not claims about the stub. + - name: Assert Draupnir completed its Matrix identity and management-room bootstrap + ansible.builtin.assert: + that: + - "'/account/whoami' in matrix_bot_draupnir_stub_request_log" + - "'/joined_rooms' in matrix_bot_draupnir_stub_request_log" + - "'/rooms/!draupnir-control%3Amolecule.local/state' in matrix_bot_draupnir_stub_request_log" + fail_msg: "Draupnir did not perform all expected Matrix bootstrap requests" + success_msg: "Draupnir performed its identity and management-room bootstrap" + vars: + matrix_bot_draupnir_stub_request_log: "{{ matrix_bot_draupnir_stub_logs.stdout + matrix_bot_draupnir_stub_logs.stderr }}" + + - name: Assert Draupnir entered the Matrix sync loop + ansible.builtin.assert: + that: + - "'/sync?' in matrix_bot_draupnir_stub_request_log" + fail_msg: "Draupnir became healthy without requesting an initial Matrix sync" + success_msg: "Draupnir requested its initial Matrix sync" + vars: + matrix_bot_draupnir_stub_request_log: "{{ matrix_bot_draupnir_stub_logs.stdout + matrix_bot_draupnir_stub_logs.stderr }}" + + - name: Read the configuration file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_draupnir_config_path }}/production.yaml" + register: matrix_bot_draupnir_config_file + + - name: Assert the rendered Matrix connection and management-room configuration + ansible.builtin.assert: + that: + - matrix_bot_draupnir_rendered_config.homeserverUrl == matrix_bot_draupnir_config_homeserverUrl + - matrix_bot_draupnir_rendered_config.rawHomeserverUrl == matrix_bot_draupnir_config_rawHomeserverUrl + - matrix_bot_draupnir_rendered_config.accessToken == matrix_bot_draupnir_config_accessToken + - matrix_bot_draupnir_rendered_config.managementRoom == matrix_bot_draupnir_config_managementRoom + - matrix_bot_draupnir_rendered_config.experimentalRustCrypto is sameas false + - matrix_bot_draupnir_rendered_config.pantalaimon is not defined + fail_msg: "The rendered configuration does not carry the scenario's Matrix connection" + success_msg: "The rendered configuration carries the scenario's Matrix connection" + + - name: Assert the rendered bootstrap and moderation behavior + ansible.builtin.assert: + that: + - matrix_bot_draupnir_rendered_config.logLevel == 'DEBUG' + - matrix_bot_draupnir_rendered_config.verifyPermissionsOnStartup is sameas false + - matrix_bot_draupnir_rendered_config.noop is sameas true + - matrix_bot_draupnir_rendered_config.disableServerACL is sameas true + - matrix_bot_draupnir_rendered_config.backgroundDelayMS == 137 + - matrix_bot_draupnir_rendered_config.commands.allowNoPrefix is sameas true + - matrix_bot_draupnir_rendered_config.roomStateBackingStore.enabled is sameas false + fail_msg: "The rendered configuration does not carry the non-default Draupnir behavior" + success_msg: "The rendered configuration carries the non-default Draupnir behavior" + + - name: Assert recovery safe mode is disabled in the rendered configuration + ansible.builtin.assert: + that: + - matrix_bot_draupnir_rendered_config.safeMode.bootOption == 'Never' + fail_msg: "Recovery safe mode could mask a failed normal Draupnir bootstrap" + success_msg: "Recovery safe mode cannot mask the scenario's readiness gate" + + - name: Assert the rendered health listener configuration + ansible.builtin.assert: + that: + - matrix_bot_draupnir_rendered_config.health.healthz.enabled is sameas true + - matrix_bot_draupnir_rendered_config.health.healthz.port == 18081 + - matrix_bot_draupnir_rendered_config.health.healthz.address == '0.0.0.0' + - matrix_bot_draupnir_rendered_config.health.healthz.endpoint == '/molecule-ready' + - matrix_bot_draupnir_rendered_config.health.healthz.healthyStatus == 201 + - matrix_bot_draupnir_rendered_config.health.healthz.unhealthyStatus == 503 + fail_msg: "The rendered health listener does not carry the scenario's settings" + success_msg: "The rendered health listener carries the scenario's settings" + + - name: Assert the rendered abuse-reporting web listener configuration + ansible.builtin.assert: + that: + - matrix_bot_draupnir_rendered_config.web.enabled is sameas true + - matrix_bot_draupnir_rendered_config.web.port == matrix_bot_draupnir_config_web_port + - matrix_bot_draupnir_rendered_config.web.address == '0.0.0.0' + - matrix_bot_draupnir_rendered_config.web.abuseReporting.enabled is sameas true + - matrix_bot_draupnir_rendered_config.web.synapseHTTPAntispam.enabled is sameas false + - matrix_bot_draupnir_rendered_config.displayReports is sameas false + fail_msg: "The rendered web configuration does not carry the abuse-reporting settings" + success_msg: "The rendered web listener carries the abuse-reporting settings" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_draupnir_base_path }}/labels" + register: matrix_bot_draupnir_labels_file + + - name: Assert the labels carry the configured public report routing + ansible.builtin.assert: + that: + - "'traefik.enable=true' in matrix_bot_draupnir_labels_lines" + - "'traefik.docker.network=' + matrix_bot_draupnir_container_network in matrix_bot_draupnir_labels_lines" + - "'traefik.http.services.matrix-bot-draupnir.loadbalancer.server.port=18082' in matrix_bot_draupnir_labels_lines" + - "'traefik.http.routers.matrix-bot-draupnir-web-abuseReporting.rule=Host(`draupnir-reports.molecule.local`) && PathRegexp(`^/molecule-report/(v1)/rooms/([^/]*)/event/(.*)$`)' in matrix_bot_draupnir_labels_lines" + - "'traefik.http.routers.matrix-bot-draupnir-web-abuseReporting.priority=743' in matrix_bot_draupnir_labels_lines" + - "'traefik.http.routers.matrix-bot-draupnir-web-abuseReporting.entrypoints=web' in matrix_bot_draupnir_labels_lines" + - "'traefik.http.routers.matrix-bot-draupnir-web-abuseReporting.tls=false' in matrix_bot_draupnir_labels_lines" + - "'molecule.draupnir.coverage=enabled' in matrix_bot_draupnir_labels_lines" + fail_msg: "The role's label file does not carry the scenario's public report routing" + success_msg: "The role's label file carries the scenario's public report routing" + + - name: Inspect the running Draupnir container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-bot-draupnir + register: matrix_bot_draupnir_container_inspect + changed_when: false + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - matrix_bot_draupnir_runtime.Config.Image == 'ghcr.io/the-draupnir-project/draupnir:' + matrix_bot_draupnir_role_defaults.matrix_bot_draupnir_version + fail_msg: "The running Draupnir container does not use the role's exact image pin" + success_msg: "The running Draupnir container uses the role's exact image pin" + + - name: Assert the running container uses the playbook-supplied identity + ansible.builtin.assert: + that: + - matrix_bot_draupnir_runtime.Config.User.split(':')[0] == matrix_user_uid | string + - matrix_bot_draupnir_runtime.Config.User.split(':')[1] == matrix_user_gid | string + fail_msg: >- + Draupnir runs as {{ matrix_bot_draupnir_runtime.Config.User }} instead of + {{ matrix_user_uid }}:{{ matrix_user_gid }} + success_msg: "The running container uses the playbook-supplied UID and GID" + + - name: Assert the container drops all Linux capabilities + ansible.builtin.assert: + that: + - matrix_bot_draupnir_runtime.HostConfig.CapDrop is sequence + - "'ALL' in matrix_bot_draupnir_runtime.HostConfig.CapDrop" + fail_msg: "The Draupnir container does not drop all Linux capabilities" + success_msg: "The Draupnir container drops all Linux capabilities" + + - name: Assert the container root filesystem is read-only + ansible.builtin.assert: + that: + - matrix_bot_draupnir_runtime.HostConfig.ReadonlyRootfs is sameas true + fail_msg: "The Draupnir container root filesystem is writable" + success_msg: "The Draupnir container root filesystem is read-only" + + - name: Assert the configuration bind mount is read-only + ansible.builtin.assert: + that: + - matrix_bot_draupnir_config_mounts | length == 1 + - matrix_bot_draupnir_config_mounts[0].RW is sameas false + fail_msg: "The Draupnir configuration bind mount is missing or writable" + success_msg: "The Draupnir configuration bind mount is present and read-only" + + - name: Assert the data bind mount is writable + ansible.builtin.assert: + that: + - matrix_bot_draupnir_data_mounts | length == 1 + - matrix_bot_draupnir_data_mounts[0].RW is sameas true + fail_msg: "The Draupnir data bind mount is missing or read-only" + success_msg: "The Draupnir data bind mount is present and writable" + + - name: Assert the container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_bot_draupnir_runtime.NetworkSettings.Networks is mapping + - matrix_bot_draupnir_runtime.NetworkSettings.Networks | length == 1 + - matrix_bot_draupnir_container_network in matrix_bot_draupnir_runtime.NetworkSettings.Networks + fail_msg: >- + Draupnir has unexpected networks: + {{ matrix_bot_draupnir_runtime.NetworkSettings.Networks.keys() | list }} + success_msg: "The Draupnir container is attached only to its dedicated network" + + - name: Ask Docker for Draupnir's published ports + ansible.builtin.command: + argv: + - docker + - container + - port + - matrix-bot-draupnir + register: matrix_bot_draupnir_published_ports + changed_when: false + failed_when: false + + - name: Assert the role did not publish a host port + ansible.builtin.assert: + that: + - matrix_bot_draupnir_runtime.HostConfig.PortBindings | default({}, true) | length == 0 + - matrix_bot_draupnir_published_ports.rc == 0 + - matrix_bot_draupnir_published_ports.stdout | trim | length == 0 + fail_msg: >- + Draupnir unexpectedly publishes a host port: + {{ matrix_bot_draupnir_published_ports.stdout | default('unknown') }} + success_msg: "The role leaves Draupnir's HTTP ports unpublished" + + - name: Assert Docker accepted the role's custom label + ansible.builtin.assert: + that: + - matrix_bot_draupnir_runtime.Config.Labels is mapping + - matrix_bot_draupnir_runtime.Config.Labels['molecule.draupnir.coverage'] == 'enabled' + fail_msg: "Docker did not attach the custom label from the role's label file" + success_msg: "Docker accepted the custom label from the role's label file" diff --git a/roles/custom/matrix-bot-draupnir/tasks/setup_install.yml b/roles/custom/matrix-bot-draupnir/tasks/setup_install.yml index 630d8ec88..6629c9868 100644 --- a/roles/custom/matrix-bot-draupnir/tasks/setup_install.yml +++ b/roles/custom/matrix-bot-draupnir/tasks/setup_install.yml @@ -38,17 +38,25 @@ register: matrix_bot_draupnir_support_files_result - name: Ensure Draupnir Docker image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_bot_draupnir_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_bot_draupnir_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_draupnir_container_image_force_pull }}" + pull: always when: "not matrix_bot_draupnir_container_image_self_build | bool" register: matrix_bot_draupnir_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_bot_draupnir_container_image_pull_result is not failed +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Draupnir repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bot_draupnir_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bot_draupnir_container_image_self_build | bool" + - name: Ensure Draupnir repository is present on self-build ansible.builtin.git: repo: "{{ matrix_bot_draupnir_container_image_self_build_repo }}" @@ -61,15 +69,18 @@ when: "matrix_bot_draupnir_container_image_self_build | bool" - name: Ensure Draupnir Docker image is built - community.docker.docker_image: + # Using docker_image_build with BuildKit for modern, efficient builds. + # Rebuild when the git checkout advanced to a new commit; otherwise keep the build idempotent. + # Technically the idempotency of rebuilds is more that if a build has already been executed for that name:tag + # then we won't rebuild while in idempotent mode even if git moved. That's what the force rebuild logic is for. + community.docker.docker_image_build: name: "{{ matrix_bot_draupnir_container_image }}" - source: build - force_source: "{{ matrix_bot_draupnir_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_bot_draupnir_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_bot_draupnir_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bot_draupnir_git_pull_results.changed | bool else 'never' }}" when: "matrix_bot_draupnir_container_image_self_build | bool" + register: matrix_bot_draupnir_container_image_build_result - name: Ensure matrix-bot-draupnir config installed ansible.builtin.copy: @@ -81,6 +92,7 @@ register: matrix_bot_draupnir_config_result - name: Ensure matrix-bot-draupnir container network is created + when: matrix_bot_draupnir_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_bot_draupnir_container_network }}" @@ -94,6 +106,16 @@ mode: '0644' register: matrix_bot_draupnir_systemd_service_result +# matrix-bot-draupnir and matrix-appservice-draupnir-for-all share the +# same upstream container image. When both are enabled and force-pull is +# on, the second role to run sees the image as already up-to-date (the +# first role just pulled it), so its pull_result.changed is false and +# conditional restart would skip it. To avoid that, we also treat +# force-pull itself as a restart trigger for this role. The downside is +# that both Draupnir services restart on every run when force-pull is +# enabled (e.g. with rolling tags like `latest` or `main`), even when the +# upstream image has not moved. That is wasteful but acceptable. +# See: https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/5186 - name: Determine whether Draupnir needs a restart ansible.builtin.set_fact: matrix_bot_draupnir_restart_necessary: >- @@ -103,6 +125,8 @@ or matrix_bot_draupnir_config_result.changed | default(false) or matrix_bot_draupnir_systemd_service_result.changed | default(false) or matrix_bot_draupnir_container_image_pull_result.changed | default(false) + or matrix_bot_draupnir_container_image_build_result.changed | default(false) + or matrix_bot_draupnir_force_restart | bool }} - name: Ensure matrix-bot-draupnir.service restarted, if necessary diff --git a/roles/custom/matrix-bot-draupnir/tasks/validate_config.yml b/roles/custom/matrix-bot-draupnir/tasks/validate_config.yml index 624cc2cdb..df499d680 100644 --- a/roles/custom/matrix-bot-draupnir/tasks/validate_config.yml +++ b/roles/custom/matrix-bot-draupnir/tasks/validate_config.yml @@ -1,5 +1,5 @@ # SPDX-FileCopyrightText: 2023 - 2025 MDAD project contributors -# SPDX-FileCopyrightText: 2023 - 2025 Catalan Lover +# SPDX-FileCopyrightText: 2023 - 2026 Catalan Lover # SPDX-FileCopyrightText: 2024 - 2025 Slavi Pantaleev # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -37,6 +37,7 @@ - {'old': 'matrix_bot_draupnir_docker_image_registry_prefix_upstream', 'new': 'matrix_bot_draupnir_container_image_registry_prefix_upstream'} - {'old': 'matrix_bot_draupnir_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bot_draupnir_container_image_registry_prefix_upstream_default'} - {'old': 'matrix_bot_draupnir_docker_src_files_path', 'new': 'matrix_bot_draupnir_container_src_files_path'} + - {'old': 'matrix_bot_draupnir_container_image_force_pull', 'new': ' (No longer needed due to new docker module doing this natively only if needed.)'} - name: Fail if required matrix-bot-draupnir variables are undefined ansible.builtin.fail: @@ -44,7 +45,8 @@ with_items: - {'name': 'matrix_bot_draupnir_config_accessToken', when: "{{ not matrix_bot_draupnir_pantalaimon_use and not matrix_bot_draupnir_login_native }}"} - {'name': 'matrix_bot_draupnir_config_accessToken', when: "{{ matrix_bot_draupnir_config_experimentalRustCrypto }}"} - - {'name': 'matrix_bot_draupnir_config_managementRoom', when: true} + - {'name': 'matrix_bot_draupnir_config_managementRoom', when: "{{ not matrix_bot_draupnir_zero_touch_deploy }}"} + - {'name': 'matrix_bot_draupnir_config_initialManager', when: "{{ matrix_bot_draupnir_zero_touch_deploy }}"} - {'name': 'matrix_bot_draupnir_container_network', when: true} - {'name': 'matrix_bot_draupnir_config_homeserverUrl', when: true} - {'name': 'matrix_bot_draupnir_config_rawHomeserverUrl', when: true} @@ -63,6 +65,8 @@ with_items: - {'name': 'matrix_bot_draupnir_config_accessToken', when: "{{ matrix_bot_draupnir_pantalaimon_use }}"} - {'name': 'matrix_bot_draupnir_config_accessToken', when: "{{ matrix_bot_draupnir_login_native }}"} + - {'name': 'matrix_bot_draupnir_config_managementRoom', when: "{{ matrix_bot_draupnir_zero_touch_deploy }}"} + - {'name': 'matrix_bot_draupnir_config_initialManager', when: "{{ not matrix_bot_draupnir_zero_touch_deploy }}"} when: "item.when | bool and not (lookup('vars', item.name, default='') == '' or lookup('vars', item.name, default='') is none)" - name: Fail when matrix_bot_draupnir_config_experimentalRustCrypto is enabled together with matrix_bot_draupnir_pantalaimon_use diff --git a/roles/custom/matrix-bot-draupnir/templates/production.yaml.j2 b/roles/custom/matrix-bot-draupnir/templates/production.yaml.j2 index 874a3badd..e700ba118 100644 --- a/roles/custom/matrix-bot-draupnir/templates/production.yaml.j2 +++ b/roles/custom/matrix-bot-draupnir/templates/production.yaml.j2 @@ -1,6 +1,6 @@ {# SPDX-FileCopyrightText: 2023 - 2024 MDAD project contributors -SPDX-FileCopyrightText: 2023 - 2025 Catalan Lover +SPDX-FileCopyrightText: 2023 - 2026 Catalan Lover SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-FileCopyrightText: 2024 Suguru Hirahara @@ -63,6 +63,7 @@ autojoinOnlyIfManager: true # Whether Draupnir should report ignored invites to the management room (if autojoinOnlyIfManager is true). recordIgnoredInvites: false +{% if not matrix_bot_draupnir_zero_touch_deploy %} # The room ID (or room alias) of the management room, anyone in this room can issue commands to Draupnir. # # Draupnir has no more granular access controls other than this, be sure you trust everyone in this room - secure it! @@ -72,6 +73,13 @@ recordIgnoredInvites: false # Note: By default, Draupnir is fairly verbose - expect a lot of messages in this room. # (see verboseLogging to adjust this a bit.) managementRoom: {{ matrix_bot_draupnir_config_managementRoom | to_json }} +{% endif %} + +{% if matrix_bot_draupnir_zero_touch_deploy %} +# The initial manager to invite if the management room has to be created. +# Leave this commented out when using a pre-existing management room. +initialManager: {{ matrix_bot_draupnir_config_initialManager | to_json }} +{% endif %} # The log level of terminal (or container) output, # can be one of DEBUG, INFO, WARN and ERROR, in increasing order of importance and severity. @@ -148,6 +156,13 @@ commands: # will address only my_moderator_bot. allowNoPrefix: false + # Controls which symbol will prefix a secondary prefix that is described in additionalPrefixes. + # For example the `!` in `!draupnir`. + # If you wish the bot to use "slash commands" with the "/" character instead of the exclamation mark "!" change the value to `"/"` and the bot will start responding to slash commands. + + symbolPrefixes: + - "!" + # Any additional bot prefixes that Draupnir will listen to. i.e. adding `mod` will allow `!mod help`. additionalPrefixes: - "draupnir-bot" diff --git a/roles/custom/matrix-bot-draupnir/templates/systemd/matrix-bot-draupnir.service.j2 b/roles/custom/matrix-bot-draupnir/templates/systemd/matrix-bot-draupnir.service.j2 index debcc7644..75438e5b0 100644 --- a/roles/custom/matrix-bot-draupnir/templates/systemd/matrix-bot-draupnir.service.j2 +++ b/roles/custom/matrix-bot-draupnir/templates/systemd/matrix-bot-draupnir.service.j2 @@ -36,9 +36,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {{ matrix_bot_draupnir_container_image }} \ bot --draupnir-config /data/config/production.yaml +{% if matrix_bot_draupnir_container_network != 'host' %} {% for network in matrix_bot_draupnir_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-draupnir {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-draupnir diff --git a/roles/custom/matrix-bot-go-neb/defaults/main.yml b/roles/custom/matrix-bot-go-neb/defaults/main.yml deleted file mode 100644 index 556bb39dd..000000000 --- a/roles/custom/matrix-bot-go-neb/defaults/main.yml +++ /dev/null @@ -1,365 +0,0 @@ -# SPDX-FileCopyrightText: 2021 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2021 Yannick Goossens -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# SPDX-FileCopyrightText: 2022 Nikita Chernyi -# SPDX-FileCopyrightText: 2023 Samuel Meenzen -# SPDX-FileCopyrightText: 2024 Suguru Hirahara -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -# Go-NEB is a Matrix bot written in Go. It is the successor to Matrix-NEB, the original Matrix bot written in Python. -# Project source code URL: https://github.com/matrix-org/go-neb - -matrix_bot_go_neb_enabled: true - -# renovate: datasource=docker depName=matrixdotorg/go-neb -matrix_bot_go_neb_version: latest - -matrix_bot_go_neb_scheme: https - -# The hostname at which Go-NEB is served. -matrix_bot_go_neb_hostname: '' - -# The path at which Go-NEB is exposed. -# This value must either be `/` or not end with a slash (e.g. `/go-neb`). -matrix_bot_go_neb_path_prefix: / - -matrix_bot_go_neb_base_url: "{{ matrix_bot_go_neb_scheme }}://{{ matrix_bot_go_neb_hostname }}{{ matrix_bot_go_neb_path_prefix }}{{ '' if matrix_bot_go_neb_path_prefix == '/' else '/' }}" - -matrix_bot_go_neb_base_path: "{{ matrix_base_data_path }}/go-neb" -matrix_bot_go_neb_config_path: "{{ matrix_bot_go_neb_base_path }}/config" -matrix_bot_go_neb_config_path_in_container: "/config/config.yaml" -matrix_bot_go_neb_data_path: "{{ matrix_bot_go_neb_base_path }}/data" -matrix_bot_go_neb_data_store_path: "{{ matrix_bot_go_neb_data_path }}/store" - -matrix_bot_go_neb_container_image: "{{ matrix_bot_go_neb_container_image_registry_prefix }}matrixdotorg/go-neb:{{ matrix_bot_go_neb_container_image_tag }}" -matrix_bot_go_neb_container_image_tag: "{{ matrix_bot_go_neb_version }}" -matrix_bot_go_neb_container_image_force_pull: "{{ matrix_bot_go_neb_container_image.endswith(':latest') }}" -matrix_bot_go_neb_container_image_registry_prefix: "{{ matrix_bot_go_neb_container_image_registry_prefix_upstream }}" -matrix_bot_go_neb_container_image_registry_prefix_upstream: "{{ matrix_bot_go_neb_container_image_registry_prefix_upstream_default }}" -matrix_bot_go_neb_container_image_registry_prefix_upstream_default: "docker.io/" - -# The base container network. It will be auto-created by this role if it doesn't exist already. -matrix_bot_go_neb_container_network: matrix-bot-go-neb - -# A list of additional container networks that the container would be connected to. -# The role does not create these networks, so make sure they already exist. -# Use this to expose this container to another reverse proxy, which runs in a different container network. -matrix_bot_go_neb_container_additional_networks: [] - -# Controls whether the matrix-bot-go-neb container exposes its HTTP port (tcp/4050 in the container). -# -# Takes an ":" or "" value (e.g. "127.0.0.1:4050"), or empty string to not expose. -matrix_bot_go_neb_container_http_host_bind_port: '' - -# matrix_bot_go_neb_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. -# See `../templates/labels.j2` for details. -# -# To inject your own other container labels, see `matrix_bot_go_neb_container_labels_additional_labels`. -matrix_bot_go_neb_container_labels_traefik_enabled: true -matrix_bot_go_neb_container_labels_traefik_docker_network: "{{ matrix_bot_go_neb_container_network }}" -matrix_bot_go_neb_container_labels_traefik_hostname: "{{ matrix_bot_go_neb_hostname }}" -# The path prefix must either be `/` or not end with a slash (e.g. `/go-neb`). -matrix_bot_go_neb_container_labels_traefik_path_prefix: "{{ matrix_bot_go_neb_path_prefix }}" -matrix_bot_go_neb_container_labels_traefik_rule: "Host(`{{ matrix_bot_go_neb_container_labels_traefik_hostname }}`){% if matrix_bot_go_neb_container_labels_traefik_path_prefix != '/' %} && PathPrefix(`{{ matrix_bot_go_neb_container_labels_traefik_path_prefix }}`){% endif %}" -matrix_bot_go_neb_container_labels_traefik_priority: 0 -matrix_bot_go_neb_container_labels_traefik_entrypoints: web-secure -matrix_bot_go_neb_container_labels_traefik_tls: "{{ matrix_bot_go_neb_container_labels_traefik_entrypoints != 'web' }}" -matrix_bot_go_neb_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls which additional headers to attach to all HTTP responses. -# To add your own headers, use `matrix_bot_go_neb_container_labels_traefik_additional_response_headers_custom` -matrix_bot_go_neb_container_labels_traefik_additional_response_headers: "{{ matrix_bot_go_neb_container_labels_traefik_additional_response_headers_auto | combine(matrix_bot_go_neb_container_labels_traefik_additional_response_headers_custom) }}" -matrix_bot_go_neb_container_labels_traefik_additional_response_headers_auto: | - {{ - {} - | combine ({'X-XSS-Protection': matrix_bot_go_neb_http_header_xss_protection} if matrix_bot_go_neb_http_header_xss_protection else {}) - | combine ({'X-Content-Type-Options': matrix_bot_go_neb_http_header_content_type_options} if matrix_bot_go_neb_http_header_content_type_options else {}) - | combine ({'Content-Security-Policy': matrix_bot_go_neb_http_header_content_security_policy} if matrix_bot_go_neb_http_header_content_security_policy else {}) - | combine ({'Permission-Policy': matrix_bot_go_neb_http_header_content_permission_policy} if matrix_bot_go_neb_http_header_content_permission_policy else {}) - | combine ({'Strict-Transport-Security': matrix_bot_go_neb_http_header_strict_transport_security} if matrix_bot_go_neb_http_header_strict_transport_security and matrix_bot_go_neb_container_labels_traefik_tls else {}) - }} -matrix_bot_go_neb_container_labels_traefik_additional_response_headers_custom: {} - -# matrix_bot_go_neb_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. -# See `../templates/labels.j2` for details. -# -# Example: -# matrix_bot_go_neb_container_labels_additional_labels: | -# my.label=1 -# another.label="here" -matrix_bot_go_neb_container_labels_additional_labels: '' - -# A list of extra arguments to pass to the container -matrix_bot_go_neb_container_extra_arguments: [] - -# List of systemd services that matrix-bot-go-neb.service depends on -matrix_bot_go_neb_systemd_required_services_list: "{{ matrix_bot_go_neb_systemd_required_services_list_default + matrix_bot_go_neb_systemd_required_services_list_auto + matrix_bot_go_neb_systemd_required_services_list_custom }}" -matrix_bot_go_neb_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_bot_go_neb_systemd_required_services_list_auto: [] -matrix_bot_go_neb_systemd_required_services_list_custom: [] - -# List of systemd services that matrix-bot-go-neb.service wants -matrix_bot_go_neb_systemd_wanted_services_list: [] - -# Specifies the value of the `X-XSS-Protection` header -# Stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. -# -# Learn more about it is here: -# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection -# - https://portswigger.net/web-security/cross-site-scripting/reflected -matrix_bot_go_neb_http_header_xss_protection: "1; mode=block" - -# Specifies the value of the `X-Content-Type-Options` header. -# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options -matrix_bot_go_neb_http_header_content_type_options: nosniff - -# Specifies the value of the `Content-Security-Policy` header. -# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy -matrix_bot_go_neb_http_header_content_security_policy: frame-ancestors 'self' - -# Specifies the value of the `Permission-Policy` header. -# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permission-Policy -matrix_bot_go_neb_http_header_content_permission_policy: "{{ 'interest-cohort=()' if matrix_bot_go_neb_floc_optout_enabled else '' }}" - -# Specifies the value of the `Strict-Transport-Security` header. -# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security -matrix_bot_go_neb_http_header_strict_transport_security: "max-age=31536000; includeSubDomains{{ '; preload' if matrix_bot_go_neb_hsts_preload_enabled else '' }}" - -# Controls whether to send a "Permissions-Policy interest-cohort=();" header along with all responses -# -# Learn more about what it is here: -# - https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea -# - https://paramdeo.com/blog/opting-your-website-out-of-googles-floc-network -# - https://amifloced.org/ -# -# Of course, a better solution is to just stop using browsers (like Chrome), which participate in such tracking practices. -# See: `matrix_bot_go_neb_content_permission_policy` -matrix_bot_go_neb_floc_optout_enabled: true - -# Controls if HSTS preloading is enabled -# -# In its strongest and recommended form, the [HSTS policy](https://www.chromium.org/hsts) includes all subdomains, and -# indicates a willingness to be "preloaded" into browsers: -# `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload` -# For more information visit: -# - https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security -# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security -# - https://hstspreload.org/#opt-in -# See: `matrix_bot_go_neb_http_header_strict_transport_security` -matrix_bot_go_neb_hsts_preload_enabled: false - -# Database-related configuration fields. -# -# MUST be "sqlite3". No other type is supported. -matrix_bot_go_neb_database_engine: 'sqlite3' - -matrix_bot_go_neb_sqlite_database_path_local: "{{ matrix_bot_go_neb_data_path }}/bot.db" -matrix_bot_go_neb_sqlite_database_path_in_container: "/data/bot.db" - -matrix_bot_go_neb_storage_database: "{{ - { - 'sqlite3': (matrix_bot_go_neb_sqlite_database_path_in_container + '?_busy_timeout=5000'), - }[matrix_bot_go_neb_database_engine] -}}" - -# The bot's username(s). These users need to be created manually beforehand. -# The access tokens that the bot uses to authenticate. -# Generate one as described in -# https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-dimension.md#access-token -# via curl. With the Element method, you might run into decryption problems (see https://github.com/matrix-org/go-neb#quick-start) -matrix_bot_go_neb_clients: [] -# - UserID: "@goneb:{{ matrix_domain }}" -# AccessToken: "MDASDASJDIASDJASDAFGFRGER" -# DeviceID: "DEVICE1" -# HomeserverURL: "{{ matrix_addons_homeserver_client_api_url }}" -# Sync: true -# AutoJoinRooms: true -# DisplayName: "Go-NEB!" -# AcceptVerificationFromUsers: [":{{ matrix_domain }}"] -# -# - UserID: "@another_goneb:{{ matrix_domain }}" -# AccessToken: "MDASDASJDIASDJASDAFGFRGER" -# DeviceID: "DEVICE2" -# HomeserverURL: "{{ matrix_addons_homeserver_client_api_url }}" -# Sync: false -# AutoJoinRooms: false -# DisplayName: "Go-NEB!" -# AcceptVerificationFromUsers: ["^@admin:{{ matrix_domain }}"] - -# The list of realms which Go-NEB is aware of. -# Delete or modify this list as appropriate. -# See the docs for /configureAuthRealm for the full list of options: -# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureAuthRealmRequest -matrix_bot_go_neb_realms: [] -# - ID: "github_realm" -# Type: "github" -# Config: {} # No need for client ID or Secret as Go-NEB isn't generating OAuth URLs - -# The list of *authenticated* sessions which Go-NEB is aware of. -# Delete or modify this list as appropriate. -# The full list of options are shown below: there is no single HTTP endpoint -# which maps to this section. -# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#Session -matrix_bot_go_neb_sessions: [] -# - SessionID: "your_github_session" -# RealmID: "github_realm" -# UserID: "@alice:{{ matrix_domain }}" # This needs to be the username of the person that's allowed to use the !github commands -# Config: -# # Populate these fields by generating a "Personal Access Token" on github.com -# AccessToken: "YOUR_GITHUB_ACCESS_TOKEN" -# Scopes: "admin:org_hook,admin:repo_hook,repo,user" - -# The list of services which Go-NEB is aware of. -# Delete or modify this list as appropriate. -# See the docs for /configureService for the full list of options: -# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureServiceRequest -matrix_bot_go_neb_services: [] -# - ID: "echo_service" -# Type: "echo" -# UserID: "@goneb:{{ matrix_domain }}" -# Config: {} - -## Can be obtained from https://developers.giphy.com/dashboard/ -# - ID: "giphy_service" -# Type: "giphy" -# UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client -# Config: -# api_key: "qwg4672vsuyfsfe" -# use_downsized: false -# -## This service has been dead for over a year :/ -# - ID: "guggy_service" -# Type: "guggy" -# UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client -# Config: -# api_key: "2356saaqfhgfe" -# -## API Key via https://developers.google.com/custom-search/v1/introduction -## CX via http://www.google.com/cse/manage/all -## https://stackoverflow.com/questions/6562125/getting-a-cx-id-for-custom-search-google-api-python -## 'Search the entire web' and 'Image search' enabled for best results -# - ID: "google_service" -# Type: "google" -# UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client -# Config: -# api_key: "AIzaSyA4FD39m9" -# cx: "AIASDFWSRRtrtr" -# -## Get a key via https://api.imgur.com/oauth2/addclient -## Select "oauth2 without callback url" -# - ID: "imgur_service" -# Type: "imgur" -# UserID: "@imgur:{{ matrix_domain }}" # requires a Syncing client -# Config: -# client_id: "AIzaSyA4FD39m9" -# client_secret: "somesecret" -# -# - ID: "wikipedia_service" -# Type: "wikipedia" -# UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client -# Config: -# -# - ID: "rss_service" -# Type: "rssbot" -# UserID: "@another_goneb:{{ matrix_domain }}" -# Config: -# feeds: -# "http://lorem-rss.herokuapp.com/feed?unit=second&interval=60": -# rooms: ["!qporfwt:localhost"] -# must_include: -# author: -# - author1 -# description: -# - lorem -# - ipsum -# must_not_include: -# title: -# - Lorem -# - Ipsum -# -# - ID: "github_cmd_service" -# Type: "github" -# UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client -# Config: -# RealmID: "github_realm" -# -# # Make sure your BASE_URL can be accessed by Github! -# - ID: "github_webhook_service" -# Type: "github-webhook" -# UserID: "@another_goneb:{{ matrix_domain }}" -# Config: -# RealmID: "github_realm" -# ClientUserID: "@alice:{{ matrix_domain }}" # needs to be an authenticated user so Go-NEB can create webhooks. Check the UserID field in the github_realm in matrix_bot_go_neb_sessions. -# Rooms: -# "!qporfwt:example.com": -# Repos: -# "element-hq/synapse": -# Events: ["push", "issues"] -# "matrix-org/dendron": -# Events: ["pull_request"] -# "!aaabaa:example.com": -# Repos: -# "element-hq/synapse": -# Events: ["push", "issues"] -# "matrix-org/dendron": -# Events: ["pull_request"] -# -# - ID: "slackapi_service" -# Type: "slackapi" -# UserID: "@slackapi:{{ matrix_domain }}" -# Config: -# Hooks: -# "hook1": -# RoomID: "!qporfwt:example.com" -# MessageType: "m.text" # default is m.text -# -# - ID: "alertmanager_service" -# Type: "alertmanager" -# UserID: "@alertmanager:{{ matrix_domain }}" -# Config: -# # This is for information purposes only. It should point to Go-NEB path as follows: -# # `/services/hooks/` -# # Where in this case "service ID" is "alertmanager_service" -# # Make sure your BASE_URL can be accessed by the Alertmanager instance! -# webhook_url: "http://localhost/services/hooks/YWxlcnRtYW5hZ2VyX3NlcnZpY2U" -# # Each room will get the notification with the alert rendered with the given template -# rooms: -# "!qporfwt:example.com": -# text_template: "{% raw %}{{range .Alerts -}} [{{ .Status }}] {{index .Labels \"alertname\"}}: {{index .Annotations \"description\"}} {{ end -}}{% endraw %}" -# html_template: "{% raw %}{{range .Alerts -}} {{ $severity := index .Labels \"severity\"}} {{ if eq .Status \"firing\"}} {{ if eq $severity \"critical\"}} [FIRING - CRITICAL] {{ else if eq $severity \"warning\"}} [FIRING - WARNING] {{ else }} [FIRING - {{ $severity }}] {{ end }} {{ else }} [RESOLVED] {{ end }} {{ index .Labels \"alertname\"}} : {{ index .Annotations \"description\"}} source
{{end -}}{% endraw %}" -# msg_type: "m.text" # Must be either `m.text` or `m.notice` - -# Default configuration template which covers the generic use case. -# You can customize it by controlling the various variables inside it. -# -# For a more advanced customization, you can extend the default (see `matrix_bot_go_neb_configuration_extension_yaml`) -# or completely replace this variable with your own template. -matrix_bot_go_neb_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" - -matrix_bot_go_neb_configuration_extension_yaml: | - # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_bot_go_neb_configuration_yaml`). - # - # You can override individual variables from the default configuration, or introduce new ones. - # - # If you need something more special, you can take full control by - # completely redefining `matrix_bot_go_neb_configuration_yaml`. - -matrix_bot_go_neb_configuration_extension: "{{ matrix_bot_go_neb_configuration_extension_yaml | from_yaml if matrix_bot_go_neb_configuration_extension_yaml | from_yaml is mapping else {} }}" - -# Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_bot_go_neb_configuration_yaml`. -matrix_bot_go_neb_configuration: "{{ matrix_bot_go_neb_configuration_yaml | from_yaml | combine(matrix_bot_go_neb_configuration_extension, recursive=True) }}" - -# matrix_bot_go_neb_restart_necessary controls whether the service -# will be restarted (when true) or merely started (when false) by the -# systemd service manager role (when conditional restart is enabled). -# -# This value is automatically computed during installation based on whether -# any configuration files, the systemd service file, or the container image changed. -# The default of `false` means "no restart needed" — appropriate when the role's -# installation tasks haven't run (e.g., due to --tags skipping them). -matrix_bot_go_neb_restart_necessary: false diff --git a/roles/custom/matrix-bot-go-neb/tasks/install.yml b/roles/custom/matrix-bot-go-neb/tasks/install.yml deleted file mode 100644 index 1fd1fb378..000000000 --- a/roles/custom/matrix-bot-go-neb/tasks/install.yml +++ /dev/null @@ -1,80 +0,0 @@ -# SPDX-FileCopyrightText: 2021 Yannick Goossens -# SPDX-FileCopyrightText: 2022 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 Jim Myhrberg -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# SPDX-FileCopyrightText: 2022 Nikita Chernyi -# SPDX-FileCopyrightText: 2022 Sebastian Gumprich -# SPDX-FileCopyrightText: 2024 David Mehren -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Ensure go-neb paths exist - ansible.builtin.file: - path: "{{ item.path }}" - state: directory - mode: '0750' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - with_items: - - {path: "{{ matrix_bot_go_neb_config_path }}", when: true} - - {path: "{{ matrix_bot_go_neb_data_path }}", when: true} - - {path: "{{ matrix_bot_go_neb_data_store_path }}", when: true} - when: "item.when | bool" - -- name: Ensure go-neb config installed - ansible.builtin.copy: - content: "{{ matrix_bot_go_neb_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_bot_go_neb_config_path }}/config.yaml" - mode: '0644' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - register: matrix_bot_go_neb_config_result - -- name: Ensure go-neb support files installed - ansible.builtin.template: - src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_bot_go_neb_base_path }}/{{ item }}" - mode: '0640' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - with_items: - - env - - labels - register: matrix_bot_go_neb_support_files_result - -- name: Ensure go-neb container image is pulled - community.docker.docker_image: - name: "{{ matrix_bot_go_neb_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_bot_go_neb_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_go_neb_container_image_force_pull }}" - register: matrix_bot_go_neb_container_image_pull_result - retries: "{{ devture_playbook_help_container_retries_count }}" - delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_bot_go_neb_container_image_pull_result is not failed - -- name: Ensure go-neb container network is created - community.general.docker_network: - enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_bot_go_neb_container_network }}" - driver: bridge - driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - -- name: Ensure matrix-bot-go-neb.service installed - ansible.builtin.template: - src: "{{ role_path }}/templates/systemd/matrix-bot-go-neb.service.j2" - dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-go-neb.service" - mode: '0644' - register: matrix_bot_go_neb_systemd_service_result - -- name: Determine whether go-neb needs a restart - ansible.builtin.set_fact: - matrix_bot_go_neb_restart_necessary: >- - {{ - matrix_bot_go_neb_config_result.changed | default(false) - or matrix_bot_go_neb_support_files_result.changed | default(false) - or matrix_bot_go_neb_systemd_service_result.changed | default(false) - or matrix_bot_go_neb_container_image_pull_result.changed | default(false) - }} diff --git a/roles/custom/matrix-bot-go-neb/tasks/main.yml b/roles/custom/matrix-bot-go-neb/tasks/main.yml deleted file mode 100644 index 09cf4bb84..000000000 --- a/roles/custom/matrix-bot-go-neb/tasks/main.yml +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-FileCopyrightText: 2021 Yannick Goossens -# SPDX-FileCopyrightText: 2022 - 2023 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- tags: - - setup-all - - setup-bot-go-neb - - install-all - - install-bot-go-neb - block: - - ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - when: "run_setup | bool and matrix_bot_go_neb_enabled | bool" - - - ansible.builtin.include_tasks: "{{ role_path }}/tasks/install.yml" - when: "run_setup | bool and matrix_bot_go_neb_enabled | bool" - -- tags: - - setup-all - - setup-bot-go-neb - block: - - ansible.builtin.include_tasks: "{{ role_path }}/tasks/uninstall.yml" - when: "run_setup | bool and not matrix_bot_go_neb_enabled | bool" diff --git a/roles/custom/matrix-bot-go-neb/tasks/uninstall.yml b/roles/custom/matrix-bot-go-neb/tasks/uninstall.yml deleted file mode 100644 index ad862821d..000000000 --- a/roles/custom/matrix-bot-go-neb/tasks/uninstall.yml +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-FileCopyrightText: 2021 - 2023 Slavi Pantaleev -# SPDX-FileCopyrightText: 2021 Yannick Goossens -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# SPDX-FileCopyrightText: 2022 Sebastian Gumprich -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Check existence of matrix-go-neb service - ansible.builtin.stat: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-go-neb.service" - register: matrix_bot_go_neb_service_stat - -- when: matrix_bot_go_neb_service_stat.stat.exists | bool - block: - - name: Ensure matrix-go-neb is stopped - ansible.builtin.service: - name: matrix-bot-go-neb - state: stopped - enabled: false - daemon_reload: true - - - name: Ensure matrix-bot-go-neb.service doesn't exist - ansible.builtin.file: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-go-neb.service" - state: absent - - - name: Ensure Matrix go-neb paths don't exist - ansible.builtin.file: - path: "{{ matrix_bot_go_neb_base_path }}" - state: absent diff --git a/roles/custom/matrix-bot-go-neb/tasks/validate_config.yml b/roles/custom/matrix-bot-go-neb/tasks/validate_config.yml deleted file mode 100644 index ead635626..000000000 --- a/roles/custom/matrix-bot-go-neb/tasks/validate_config.yml +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-FileCopyrightText: 2021 Yannick Goossens -# SPDX-FileCopyrightText: 2022 Slavi Pantaleev -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Fail if there's not at least 1 client - ansible.builtin.fail: - msg: >- - You need at least 1 client in the matrix_bot_go_neb_clients block. - when: matrix_bot_go_neb_clients is not defined or matrix_bot_go_neb_clients[0] is not defined - -- name: Fail if there's not at least 1 service - ansible.builtin.fail: - msg: >- - You need at least 1 service in the matrix_bot_go_neb_services block. - when: matrix_bot_go_neb_services is not defined or matrix_bot_go_neb_services[0] is not defined diff --git a/roles/custom/matrix-bot-go-neb/templates/config.yaml.j2 b/roles/custom/matrix-bot-go-neb/templates/config.yaml.j2 deleted file mode 100644 index c72dbf8df..000000000 --- a/roles/custom/matrix-bot-go-neb/templates/config.yaml.j2 +++ /dev/null @@ -1,44 +0,0 @@ -# Go-NEB Configuration File -# -# This file provides an alternative way to configure Go-NEB which does not involve HTTP APIs. -# -# This file can be supplied to go-neb by the environment variable `CONFIG_FILE=config.yaml`. -# It will force Go-NEB to operate in "config" mode. This means: -# - Go-NEB will ONLY use the data contained inside this file. -# - All of Go-NEB's /admin HTTP listeners will be disabled. You will be unable to add new services at runtime. -# - The environment variable `DATABASE_URL` will be ignored and an in-memory database will be used instead. -# -# This file is broken down into 4 sections which matches the following HTTP APIs: -# - /configureClient -# - /configureAuthRealm -# - /configureService -# - /requestAuthSession (redirects not supported) - -# The list of clients which Go-NEB is aware of. -# Delete or modify this list as appropriate. -# See the docs for /configureClient for the full list of options: -# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ClientConfig -clients: - {{ matrix_bot_go_neb_clients|to_json }} - -# The list of realms which Go-NEB is aware of. -# Delete or modify this list as appropriate. -# See the docs for /configureAuthRealm for the full list of options: -# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureAuthRealmRequest -realms: - {{ matrix_bot_go_neb_realms|to_json }} - -# The list of *authenticated* sessions which Go-NEB is aware of. -# Delete or modify this list as appropriate. -# The full list of options are shown below: there is no single HTTP endpoint -# which maps to this section. -# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#Session -sessions: - {{ matrix_bot_go_neb_sessions|to_json }} - -# The list of services which Go-NEB is aware of. -# Delete or modify this list as appropriate. -# See the docs for /configureService for the full list of options: -# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureServiceRequest -services: - {{ matrix_bot_go_neb_services|to_json }} diff --git a/roles/custom/matrix-bot-go-neb/templates/config.yaml.j2.license b/roles/custom/matrix-bot-go-neb/templates/config.yaml.j2.license deleted file mode 100644 index c74bd679c..000000000 --- a/roles/custom/matrix-bot-go-neb/templates/config.yaml.j2.license +++ /dev/null @@ -1,4 +0,0 @@ -SPDX-FileCopyrightText: 2021 Yannick Goossens -SPDX-FileCopyrightText: 2022 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bot-go-neb/templates/env.j2 b/roles/custom/matrix-bot-go-neb/templates/env.j2 deleted file mode 100644 index 7fd62d5d7..000000000 --- a/roles/custom/matrix-bot-go-neb/templates/env.j2 +++ /dev/null @@ -1,14 +0,0 @@ -{# -SPDX-FileCopyrightText: 2023 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later -#} - -BIND_ADDRESS=:4050 - -DATABASE_TYPE={{ matrix_bot_go_neb_database_engine }} -DATABASE_URL={{ matrix_bot_go_neb_storage_database }} - -BASE_URL={{ matrix_bot_go_neb_base_url }} - -CONFIG_FILE={{ matrix_bot_go_neb_config_path_in_container }} diff --git a/roles/custom/matrix-bot-go-neb/templates/labels.j2 b/roles/custom/matrix-bot-go-neb/templates/labels.j2 deleted file mode 100644 index 4f8d18670..000000000 --- a/roles/custom/matrix-bot-go-neb/templates/labels.j2 +++ /dev/null @@ -1,52 +0,0 @@ -{# -SPDX-FileCopyrightText: 2023 - 2024 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later -#} - -{% if matrix_bot_go_neb_container_labels_traefik_enabled %} -traefik.enable=true - -{% if matrix_bot_go_neb_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_bot_go_neb_container_labels_traefik_docker_network }} -{% endif %} - -traefik.http.services.matrix-bot-go-neb.loadbalancer.server.port=4050 - -{% set middlewares = [] %} - -{% if matrix_bot_go_neb_container_labels_traefik_path_prefix != '/' %} -traefik.http.middlewares.matrix-bot-go-neb-slashless-redirect.redirectregex.regex=({{ matrix_bot_go_neb_container_labels_traefik_path_prefix | quote }})$ -traefik.http.middlewares.matrix-bot-go-neb-slashless-redirect.redirectregex.replacement=${1}/ -{% set middlewares = middlewares + ['matrix-bot-go-neb-slashless-redirect'] %} -{% endif %} - -{% if matrix_bot_go_neb_container_labels_traefik_path_prefix != '/' %} -traefik.http.middlewares.matrix-bot-go-neb-strip-prefix.stripprefix.prefixes={{ matrix_bot_go_neb_container_labels_traefik_path_prefix }} -{% set middlewares = middlewares + ['matrix-bot-go-neb-strip-prefix'] %} -{% endif %} - -{% if matrix_bot_go_neb_container_labels_traefik_additional_response_headers.keys() | length > 0 %} -{% for name, value in matrix_bot_go_neb_container_labels_traefik_additional_response_headers.items() %} -traefik.http.middlewares.matrix-bot-go-neb-add-headers.headers.customresponseheaders.{{ name }}={{ value }} -{% endfor %} -{% set middlewares = middlewares + ['matrix-bot-go-neb-add-headers'] %} -{% endif %} - -traefik.http.routers.matrix-bot-go-neb.rule={{ matrix_bot_go_neb_container_labels_traefik_rule }} -{% if matrix_bot_go_neb_container_labels_traefik_priority | int > 0 %} -traefik.http.routers.matrix-bot-go-neb.priority={{ matrix_bot_go_neb_container_labels_traefik_priority }} -{% endif %} -traefik.http.routers.matrix-bot-go-neb.service=matrix-bot-go-neb -{% if middlewares | length > 0 %} -traefik.http.routers.matrix-bot-go-neb.middlewares={{ middlewares | join(',') }} -{% endif %} -traefik.http.routers.matrix-bot-go-neb.entrypoints={{ matrix_bot_go_neb_container_labels_traefik_entrypoints }} -traefik.http.routers.matrix-bot-go-neb.tls={{ matrix_bot_go_neb_container_labels_traefik_tls | to_json }} -{% if matrix_bot_go_neb_container_labels_traefik_tls %} -traefik.http.routers.matrix-bot-go-neb.tls.certResolver={{ matrix_bot_go_neb_container_labels_traefik_tls_certResolver }} -{% endif %} - -{% endif %} - -{{ matrix_bot_go_neb_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bot-go-neb/templates/systemd/matrix-bot-go-neb.service.j2.license b/roles/custom/matrix-bot-go-neb/templates/systemd/matrix-bot-go-neb.service.j2.license deleted file mode 100644 index 99d44ac5b..000000000 --- a/roles/custom/matrix-bot-go-neb/templates/systemd/matrix-bot-go-neb.service.j2.license +++ /dev/null @@ -1,4 +0,0 @@ -SPDX-FileCopyrightText: 2021 Yannick Goossens -SPDX-FileCopyrightText: 2022 - 2025 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bot-honoroit/defaults/main.yml b/roles/custom/matrix-bot-honoroit/defaults/main.yml index b97f0f4b7..7dbdff923 100644 --- a/roles/custom/matrix-bot-honoroit/defaults/main.yml +++ b/roles/custom/matrix-bot-honoroit/defaults/main.yml @@ -35,13 +35,15 @@ matrix_bot_honoroit_container_image: "{{ matrix_bot_honoroit_container_image_reg matrix_bot_honoroit_container_image_registry_prefix: "{{ 'localhost/' if matrix_bot_honoroit_container_image_self_build else matrix_bot_honoroit_container_image_registry_prefix_upstream }}" matrix_bot_honoroit_container_image_registry_prefix_upstream: "{{ matrix_bot_honoroit_container_image_registry_prefix_upstream_default }}" matrix_bot_honoroit_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_bot_honoroit_container_image_force_pull: "{{ matrix_bot_honoroit_container_image.endswith(':latest') }}" matrix_bot_honoroit_base_path: "{{ matrix_base_data_path }}/honoroit" matrix_bot_honoroit_config_path: "{{ matrix_bot_honoroit_base_path }}/config" matrix_bot_honoroit_data_path: "{{ matrix_bot_honoroit_base_path }}/data" matrix_bot_honoroit_data_store_path: "{{ matrix_bot_honoroit_data_path }}/store" +# The TCP port Honoroit listens on inside the container. +matrix_bot_honoroit_container_port: 8080 + # The base container network. It will be auto-created by this role if it doesn't exist already. matrix_bot_honoroit_container_network: "" @@ -115,19 +117,15 @@ matrix_bot_honoroit_database_sslmode: disable matrix_bot_honoroit_database_connection_string: 'postgres://{{ matrix_bot_honoroit_database_username }}:{{ matrix_bot_honoroit_database_password }}@{{ matrix_bot_honoroit_database_hostname }}:{{ matrix_bot_honoroit_database_port }}/{{ matrix_bot_honoroit_database_name }}?sslmode={{ matrix_bot_honoroit_database_sslmode }}' -matrix_bot_honoroit_storage_database: "{{ - { - 'sqlite': matrix_bot_honoroit_sqlite_database_path_in_container, - 'postgres': matrix_bot_honoroit_database_connection_string, - }[matrix_bot_honoroit_database_engine] -}}" +matrix_bot_honoroit_storage_database: "{{ { + 'sqlite': matrix_bot_honoroit_sqlite_database_path_in_container, + 'postgres': matrix_bot_honoroit_database_connection_string, +}[matrix_bot_honoroit_database_engine] }}" -matrix_bot_honoroit_database_dialect: "{{ - { +matrix_bot_honoroit_database_dialect: "{{ { 'sqlite': 'sqlite3', 'postgres': 'postgres', - }[matrix_bot_honoroit_database_engine] -}}" +}[matrix_bot_honoroit_database_engine] }}" # The bot's username. This user needs to be created manually beforehand. diff --git a/roles/custom/matrix-bot-honoroit/molecule/default/converge.yml b/roles/custom/matrix-bot-honoroit/molecule/default/converge.yml new file mode 100644 index 000000000..b57497c64 --- /dev/null +++ b/roles/custom/matrix-bot-honoroit/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-bot-honoroit Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-bot-honoroit Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure matrix-bot-honoroit is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure matrix-bot-honoroit systemd service is started + ansible.builtin.systemd_service: + name: matrix-bot-honoroit.service + state: started diff --git a/roles/custom/matrix-bot-honoroit/molecule/default/molecule.yml b/roles/custom/matrix-bot-honoroit/molecule/default/molecule.yml new file mode 100644 index 000000000..2845f4377 --- /dev/null +++ b/roles/custom/matrix-bot-honoroit/molecule/default/molecule.yml @@ -0,0 +1,122 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-bot-honoroit-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + # setup.yml normally carries this play-wide switch. + run_setup: true + + matrix_bot_honoroit_hostname: honoroit.molecule.local + matrix_bot_honoroit_path_prefix: /molecule-honoroit + matrix_bot_honoroit_metrics_path: /molecule-metrics + matrix_bot_honoroit_container_port: 18080 + matrix_bot_honoroit_container_network: matrix-bot-honoroit-molecule + matrix_bot_honoroit_container_additional_networks: + - matrix-bot-honoroit-molecule-additional + + # verify.yml is a separate play, where the role's defaults are out of scope. + matrix_bot_honoroit_base_path: /matrix/honoroit + matrix_bot_honoroit_config_path: /matrix/honoroit/config + matrix_bot_honoroit_data_path: /matrix/honoroit/data + + # Traefik itself is not deployed, but the full metrics routing contract is rendered + # with non-default values and compared with the live container labels. + matrix_bot_honoroit_container_labels_traefik_enabled: true + matrix_bot_honoroit_container_labels_traefik_docker_network: "{{ matrix_bot_honoroit_container_network }}" + matrix_bot_honoroit_container_labels_traefik_priority: 710 + matrix_bot_honoroit_container_labels_traefik_entrypoints: molecule-web + matrix_bot_honoroit_container_labels_traefik_tls: false + matrix_bot_honoroit_container_labels_traefik_additional_response_headers_custom: + X-Molecule-Honoroit: scenario + X-Robots-Tag: noindex + matrix_bot_honoroit_container_labels_additional_labels: | + molecule.honoroit.scenario=live-postgres-and-metrics + + # Real deployments use Postgres whenever the playbook's Postgres is enabled. All + # identifiers differ from the role defaults, so a migrated schema proves the role + # constructed and passed the configured DSN. + matrix_bot_honoroit_database_engine: postgres + matrix_bot_honoroit_database_hostname: matrix-postgres-molecule + matrix_bot_honoroit_database_username: molecule_honoroit_user + matrix_bot_honoroit_database_password: molecule_honoroit_password_8c45d1 + matrix_bot_honoroit_database_name: molecule_honoroit_database + matrix_bot_honoroit_database_sslmode: disable + + # These differ from both role and upstream defaults. The shared homeserver stub is + # sufficient for password login, crypto initialization and an idle sync loop. + matrix_bot_honoroit_login: molecule-honoroit + matrix_bot_honoroit_password: molecule_matrix_password_74aa5e + matrix_bot_honoroit_homeserver: http://matrix.molecule.local:8008 + matrix_bot_honoroit_roomid: "!molecule-operators:molecule.local" + matrix_bot_honoroit_prefix: "!molecule-help" + matrix_bot_honoroit_loglevel: DEBUG + matrix_bot_honoroit_cachesize: 317 + matrix_bot_honoroit_no_encryption_warning: true + matrix_bot_honoroit_ignorenothread: true + matrix_bot_honoroit_ignoredrooms: + - "!molecule-ignored-one:molecule.local" + - "!molecule-ignored-two:molecule.local" + matrix_bot_honoroit_allowedusers: + - "@support-*:molecule.local" + - "@operator:molecule.local" + matrix_bot_honoroit_text_prefix_open: "[MOLECULE OPEN]" + matrix_bot_honoroit_text_prefix_done: "[MOLECULE DONE]" + matrix_bot_honoroit_text_greetings: Molecule helpdesk greeting + matrix_bot_honoroit_text_done: Molecule helpdesk completion + + # Live metrics authentication forms the primary compatibility gate: correct + # credentials must work and both absent and wrong credentials must not. + matrix_bot_honoroit_auth_metrics_login: molecule-metrics-user + matrix_bot_honoroit_auth_metrics_password: molecule_metrics_password_c9ed32 + # Keep the generic environment extension observable independently of the role's + # first-class port wiring. + matrix_bot_honoroit_environment_variables_extension: | + MOLECULE_HONOROIT_MARKER=role-rendered-environment + + # Exercise arbitrary runtime arguments and a second private network without making + # anything reachable from the Molecule host. + matrix_bot_honoroit_container_extra_arguments: + - --pids-limit=73 + - --tmpfs=/tmp:rw,noexec,nosuid,size=16m + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bot-honoroit/molecule/default/prepare.yml b/roles/custom/matrix-bot-honoroit/molecule/default/prepare.yml new file mode 100644 index 000000000..1827f2cef --- /dev/null +++ b/roles/custom/matrix-bot-honoroit/molecule/default/prepare.yml @@ -0,0 +1,88 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-bot-honoroit Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure Honoroit's container networks exist + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ item }}" + loop: "{{ [matrix_bot_honoroit_container_network] + matrix_bot_honoroit_container_additional_networks }}" + register: matrix_bot_honoroit_molecule_networks + changed_when: matrix_bot_honoroit_molecule_networks.rc == 0 + failed_when: + - matrix_bot_honoroit_molecule_networks.rc != 0 + - "'already exists' not in matrix_bot_honoroit_molecule_networks.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bot_honoroit_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bot_honoroit_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bot_honoroit_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bot_honoroit_database_password }}" + + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bot_honoroit_container_network }}" + molecule_shared_stub_server_name: molecule.local + molecule_shared_stub_user_id: "@{{ matrix_bot_honoroit_login }}:molecule.local" + molecule_shared_stub_joined_rooms: + - "{{ matrix_bot_honoroit_roomid }}" diff --git a/roles/custom/matrix-bot-honoroit/molecule/default/requirements.yml b/roles/custom/matrix-bot-honoroit/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bot-honoroit/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bot-honoroit/molecule/default/verify.yml b/roles/custom/matrix-bot-honoroit/molecule/default/verify.yml new file mode 100644 index 000000000..16addaa24 --- /dev/null +++ b/roles/custom/matrix-bot-honoroit/molecule/default/verify.yml @@ -0,0 +1,441 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Verify matrix-bot-honoroit + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + matrix_bot_honoroit_health_body: "{{ matrix_bot_honoroit_health.stdout_lines[:-1] | join('\n') }}" + matrix_bot_honoroit_metrics_body: "{{ matrix_bot_honoroit_metrics.stdout_lines[:-1] | join('\n') }}" + matrix_bot_honoroit_metrics_lines: "{{ matrix_bot_honoroit_metrics_body.splitlines() | select | list }}" + matrix_bot_honoroit_rendered_env_lines: >- + {{ (matrix_bot_honoroit_env_file.content | b64decode).splitlines() + | select('match', '^[A-Z0-9_]+=') | list }} + matrix_bot_honoroit_rendered_env: >- + {{ dict(matrix_bot_honoroit_rendered_env_lines | map('split', '=', 1)) }} + matrix_bot_honoroit_rendered_labels_lines: >- + {{ (matrix_bot_honoroit_labels_file.content | b64decode).splitlines() + | select('match', '^[A-Za-z0-9_.-]+=') | list }} + matrix_bot_honoroit_rendered_labels: >- + {{ dict(matrix_bot_honoroit_rendered_labels_lines | map('split', '=', 1)) }} + matrix_bot_honoroit_runtime: "{{ (matrix_bot_honoroit_container_inspect.stdout | from_json) | first }}" + matrix_bot_honoroit_runtime_env: "{{ dict(matrix_bot_honoroit_runtime.Config.Env | map('split', '=', 1)) }}" + matrix_bot_honoroit_data_mounts: >- + {{ matrix_bot_honoroit_runtime.Mounts | selectattr('Destination', 'equalto', '/data') | list }} + gather_facts: false + tasks: + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_bot_honoroit_role_defaults + + - name: Wait for the matrix-bot-honoroit service to become active + ansible.builtin.systemd_service: + name: matrix-bot-honoroit.service + register: matrix_bot_honoroit_service + until: matrix_bot_honoroit_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_bot_honoroit_service.status.ActiveState == 'active' + - matrix_bot_honoroit_service.status.NRestarts is defined + - matrix_bot_honoroit_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-bot-honoroit.service is + {{ matrix_bot_honoroit_service.status.ActiveState | default('unknown') }} after + {{ matrix_bot_honoroit_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-bot-honoroit.service is active and has not restarted" + + - name: Wait for Honoroit's health API + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_honoroit_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - "http://matrix-bot-honoroit:{{ matrix_bot_honoroit_container_port }}/_health" + register: matrix_bot_honoroit_health + changed_when: false + until: "'HTTP_STATUS=200' in matrix_bot_honoroit_health.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the configured health API is live and structurally valid + ansible.builtin.assert: + that: + - matrix_bot_honoroit_health.rc == 0 + - matrix_bot_honoroit_health.stdout_lines[-1] == 'HTTP_STATUS=200' + - "matrix_bot_honoroit_health_body | from_json == {'status': 'ok'}" + fail_msg: >- + Honoroit's health API did not answer with its expected JSON + ({{ matrix_bot_honoroit_health.stdout | default('no output') }}) + success_msg: "Honoroit's live health API answers with its structured status" + + - name: Ask the metrics endpoint without credentials + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_honoroit_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - "http://matrix-bot-honoroit:{{ matrix_bot_honoroit_container_port }}/metrics" + register: matrix_bot_honoroit_unauthenticated_metrics + changed_when: false + failed_when: false + + - name: Assert the metrics endpoint requires authentication + ansible.builtin.assert: + that: + - matrix_bot_honoroit_unauthenticated_metrics.rc == 0 + - matrix_bot_honoroit_unauthenticated_metrics.stdout == 'HTTP_STATUS=401' + fail_msg: "Honoroit's metrics endpoint did not reject an unauthenticated request" + success_msg: "Honoroit's metrics endpoint rejects unauthenticated requests" + + - name: Ask the metrics endpoint with incorrect credentials + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_honoroit_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --user + - molecule-metrics-user:incorrect-molecule-password + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - "http://matrix-bot-honoroit:{{ matrix_bot_honoroit_container_port }}/metrics" + register: matrix_bot_honoroit_wrong_metrics_credentials + changed_when: false + failed_when: false + + - name: Assert the metrics endpoint rejects incorrect credentials + ansible.builtin.assert: + that: + - matrix_bot_honoroit_wrong_metrics_credentials.rc == 0 + - matrix_bot_honoroit_wrong_metrics_credentials.stdout == 'HTTP_STATUS=401' + fail_msg: "Honoroit's metrics endpoint accepted incorrect credentials" + success_msg: "Honoroit's metrics endpoint rejects incorrect credentials" + + - name: Ask the metrics endpoint with the configured credentials + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_honoroit_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --user + - molecule-metrics-user:molecule_metrics_password_c9ed32 + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - "http://matrix-bot-honoroit:{{ matrix_bot_honoroit_container_port }}/metrics" + register: matrix_bot_honoroit_metrics + changed_when: false + failed_when: false + + - name: Assert configured credentials unlock genuine Prometheus metrics + ansible.builtin.assert: + that: + - matrix_bot_honoroit_metrics.rc == 0 + - matrix_bot_honoroit_metrics.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_bot_honoroit_metrics_lines | select('match', '^honoroit_messages_operator [0-9]+$') | list | length == 1 + - matrix_bot_honoroit_metrics_lines | select('match', '^honoroit_messages_total [0-9]+$') | list | length == 1 + - matrix_bot_honoroit_metrics_lines | select('match', '^honoroit_request_done [0-9]+$') | list | length == 1 + - matrix_bot_honoroit_metrics_lines | select('match', '^honoroit_request_new [0-9]+$') | list | length == 1 + fail_msg: >- + Configured credentials did not unlock Honoroit's Prometheus metrics + ({{ matrix_bot_honoroit_metrics.stdout | default('no output') }}) + success_msg: "Configured credentials unlock Honoroit's Prometheus metrics" + + - name: Read the environment file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_honoroit_config_path }}/env" + register: matrix_bot_honoroit_env_file + + - name: Assert the parsed environment contains the Matrix and Postgres wiring + ansible.builtin.assert: + that: + - matrix_bot_honoroit_rendered_env.HONOROIT_LOGIN == matrix_bot_honoroit_login + - matrix_bot_honoroit_rendered_env.HONOROIT_PASSWORD == matrix_bot_honoroit_password + - matrix_bot_honoroit_rendered_env.HONOROIT_HOMESERVER == matrix_bot_honoroit_homeserver + - matrix_bot_honoroit_rendered_env.HONOROIT_ROOMID == matrix_bot_honoroit_roomid + - matrix_bot_honoroit_rendered_env.HONOROIT_DB_DIALECT == 'postgres' + - matrix_bot_honoroit_rendered_env.HONOROIT_DB_DSN == 'postgres://molecule_honoroit_user:molecule_honoroit_password_8c45d1@matrix-postgres-molecule:5432/molecule_honoroit_database?sslmode=disable' + fail_msg: "The parsed environment lost the scenario's Matrix or Postgres wiring" + success_msg: "The parsed environment carries the scenario's Matrix and Postgres wiring" + + - name: Assert the parsed environment contains non-default bot behavior + ansible.builtin.assert: + that: + - matrix_bot_honoroit_rendered_env.HONOROIT_PREFIX == '!molecule-help' + - matrix_bot_honoroit_rendered_env.HONOROIT_NOENCRYPTIONWARNING | lower == 'true' + - matrix_bot_honoroit_rendered_env.HONOROIT_LOGLEVEL == 'DEBUG' + - matrix_bot_honoroit_rendered_env.HONOROIT_CACHESIZE == '317' + - matrix_bot_honoroit_rendered_env.HONOROIT_IGNORENOTHREAD | lower == 'true' + - matrix_bot_honoroit_rendered_env.HONOROIT_IGNOREDROOMS == '!molecule-ignored-one:molecule.local !molecule-ignored-two:molecule.local' + - matrix_bot_honoroit_rendered_env.HONOROIT_ALLOWEDUSERS == '@support-*:molecule.local @operator:molecule.local' + - matrix_bot_honoroit_rendered_env.HONOROIT_TEXT_PREFIX_OPEN == '[MOLECULE OPEN]' + - matrix_bot_honoroit_rendered_env.HONOROIT_TEXT_PREFIX_DONE == '[MOLECULE DONE]' + - matrix_bot_honoroit_rendered_env.HONOROIT_TEXT_GREETINGS == 'Molecule helpdesk greeting' + - matrix_bot_honoroit_rendered_env.HONOROIT_TEXT_DONE == 'Molecule helpdesk completion' + fail_msg: "The parsed environment lost non-default Honoroit behavior" + success_msg: "The parsed environment carries non-default Honoroit behavior" + + - name: Assert the parsed environment contains metrics auth and extension values + ansible.builtin.assert: + that: + - matrix_bot_honoroit_rendered_env.HONOROIT_AUTH_METRICS_LOGIN == 'molecule-metrics-user' + - matrix_bot_honoroit_rendered_env.HONOROIT_AUTH_METRICS_PASSWORD == 'molecule_metrics_password_c9ed32' + - matrix_bot_honoroit_rendered_env.HONOROIT_PORT == ':' ~ (matrix_bot_honoroit_container_port | string) + - matrix_bot_honoroit_rendered_env.MOLECULE_HONOROIT_MARKER == 'role-rendered-environment' + fail_msg: "The parsed environment lost the metrics auth or extension values" + success_msg: "The parsed environment carries metrics auth and extension values" + + - name: List the tables Honoroit created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bot_honoroit_database_username }} + - --dbname={{ matrix_bot_honoroit_database_name }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' ORDER BY tablename + register: matrix_bot_honoroit_tables + changed_when: false + + - name: Assert Honoroit migrated a substantial schema into the configured Postgres database + ansible.builtin.assert: + that: + - matrix_bot_honoroit_tables.rc == 0 + - "'crypto_account' in matrix_bot_honoroit_table_names" + - "'crypto_device' in matrix_bot_honoroit_table_names" + - "'crypto_megolm_inbound_session' in matrix_bot_honoroit_table_names" + - "'crypto_olm_session' in matrix_bot_honoroit_table_names" + - "'crypto_secrets' in matrix_bot_honoroit_table_names" + - "'crypto_version' in matrix_bot_honoroit_table_names" + - "'mx_registrations' in matrix_bot_honoroit_table_names" + - "'mx_room_state' in matrix_bot_honoroit_table_names" + - "'mx_user_profile' in matrix_bot_honoroit_table_names" + - "'mx_version' in matrix_bot_honoroit_table_names" + - matrix_bot_honoroit_table_names | length == 17 + fail_msg: >- + Honoroit did not create its crypto schema in {{ matrix_bot_honoroit_database_name }} + (found {{ matrix_bot_honoroit_table_names | length }} table(s): + {{ matrix_bot_honoroit_table_names | join(', ') }}) + success_msg: "Honoroit migrated its crypto schema into the configured Postgres database" + vars: + matrix_bot_honoroit_table_names: "{{ matrix_bot_honoroit_tables.stdout_lines | select | list }}" + + - name: Read Honoroit's database migration markers + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bot_honoroit_database_username }} + - --dbname={{ matrix_bot_honoroit_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT 'crypto:' || version || ':' || compat FROM crypto_version UNION ALL SELECT 'state:' || version || ':' || compat FROM mx_version ORDER BY 1" + register: matrix_bot_honoroit_migration_versions + changed_when: false + + - name: Assert Honoroit's Postgres migrations reached the pinned schema versions + ansible.builtin.assert: + that: + - matrix_bot_honoroit_migration_versions.rc == 0 + - matrix_bot_honoroit_migration_versions.stdout_lines == ['crypto:19:15', 'state:10:3'] + fail_msg: >- + Honoroit's database migration markers are missing or unexpected + ({{ matrix_bot_honoroit_migration_versions.stdout | default('no output') | trim }}) + success_msg: "Honoroit's Postgres migrations reached the pinned schema versions" + + - name: Read Honoroit's full systemd journal + ansible.builtin.command: + argv: + - journalctl + - --unit=matrix-bot-honoroit.service + - --no-pager + register: matrix_bot_honoroit_journal + changed_when: false + + - name: Assert the journal records successful initialization and configured debug logging + ansible.builtin.assert: + that: + - "'Honoroit' in matrix_bot_honoroit_journal_plain" + - "'starting bot...' in matrix_bot_honoroit_journal_plain" + - "'client has been started' in matrix_bot_honoroit_journal_plain" + - "'cannot initialize the bot' not in matrix_bot_honoroit_journal_plain" + - "'matrix bot crashed' not in matrix_bot_honoroit_journal_plain" + fail_msg: "Honoroit's journal does not show a clean debug-level startup" + success_msg: "Honoroit's journal records a clean debug-level startup" + vars: + matrix_bot_honoroit_journal_plain: >- + {{ matrix_bot_honoroit_journal.stdout + | regex_replace('\x1B\[[0-?]*[ -/]*[@-~]', '') }} + + - name: Inspect the running Honoroit container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-bot-honoroit + register: matrix_bot_honoroit_container_inspect + changed_when: false + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - matrix_bot_honoroit_runtime.Config.Image == matrix_bot_honoroit_expected_image + fail_msg: >- + The running image is {{ matrix_bot_honoroit_runtime.Config.Image }}, expected + {{ matrix_bot_honoroit_expected_image }} from defaults/main.yml + success_msg: "The running container uses the exact image pinned by the role" + vars: + matrix_bot_honoroit_expected_image: >- + {{ matrix_bot_honoroit_role_defaults.matrix_bot_honoroit_container_image_registry_prefix_upstream_default }}etkecc/honoroit:{{ matrix_bot_honoroit_role_defaults.matrix_bot_honoroit_version }} + + - name: Assert the running container preserves the image and systemd lifecycle contract + ansible.builtin.assert: + that: + - matrix_bot_honoroit_runtime.Config.Entrypoint == ['/bin/honoroit'] + - matrix_bot_honoroit_runtime.Config.Cmd is none + - matrix_bot_honoroit_runtime.Config.WorkingDir == '/' + - matrix_bot_honoroit_runtime.HostConfig.RestartPolicy.Name == 'no' + - matrix_bot_honoroit_runtime.HostConfig.AutoRemove is sameas true + - matrix_bot_honoroit_runtime.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container has an unexpected command or Docker lifecycle contract" + success_msg: "The running container preserves the image command and systemd lifecycle contract" + + - name: Assert the running container uses the configured identity and hardening + ansible.builtin.assert: + that: + - matrix_bot_honoroit_runtime.Config.User == '1234:1234' + - matrix_bot_honoroit_runtime.HostConfig.ReadonlyRootfs is sameas true + - matrix_bot_honoroit_runtime.HostConfig.CapDrop == ['ALL'] + - matrix_bot_honoroit_runtime.HostConfig.PidsLimit == 73 + - matrix_bot_honoroit_runtime.HostConfig.Tmpfs['/tmp'] == 'rw,noexec,nosuid,size=16m' + fail_msg: "The running container lost its configured identity or hardening" + success_msg: "The running container uses the configured identity and hardening" + + - name: Assert the running container has only private network attachments + ansible.builtin.assert: + that: + - matrix_bot_honoroit_runtime.HostConfig.NetworkMode == matrix_bot_honoroit_container_network + - matrix_bot_honoroit_runtime.NetworkSettings.Networks.keys() | sort == ([matrix_bot_honoroit_container_network] + matrix_bot_honoroit_container_additional_networks) | sort + - matrix_bot_honoroit_runtime.HostConfig.PortBindings | length == 0 + fail_msg: "The running container lost a private network or published a host port" + success_msg: "The running container has both private networks and no published host ports" + + - name: Assert the writable data mount is scoped to Honoroit's data directory + ansible.builtin.assert: + that: + - matrix_bot_honoroit_runtime.Mounts | length == 1 + - matrix_bot_honoroit_data_mounts | length == 1 + - matrix_bot_honoroit_data_mounts[0].Source == matrix_bot_honoroit_data_path + - matrix_bot_honoroit_data_mounts[0].RW is sameas true + fail_msg: "The running container's /data mount does not match the role-managed data path" + success_msg: "The running container has the role-managed writable /data mount" + + - name: Assert the running process received the role-rendered environment + ansible.builtin.assert: + that: + - matrix_bot_honoroit_runtime_env.HONOROIT_DB_DSN == matrix_bot_honoroit_rendered_env.HONOROIT_DB_DSN + - matrix_bot_honoroit_runtime_env.HONOROIT_HOMESERVER == matrix_bot_honoroit_rendered_env.HONOROIT_HOMESERVER + - matrix_bot_honoroit_runtime_env.HONOROIT_AUTH_METRICS_LOGIN == matrix_bot_honoroit_rendered_env.HONOROIT_AUTH_METRICS_LOGIN + - matrix_bot_honoroit_runtime_env.HONOROIT_PORT == ':' ~ (matrix_bot_honoroit_container_port | string) + - matrix_bot_honoroit_runtime_env.MOLECULE_HONOROIT_MARKER == 'role-rendered-environment' + fail_msg: "The live container environment differs from the file the role rendered" + success_msg: "The live container received the role-rendered environment" + + - name: Read the labels file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_honoroit_config_path }}/labels" + register: matrix_bot_honoroit_labels_file + + - name: Assert the parsed labels contain the configured metrics router + ansible.builtin.assert: + that: + - matrix_bot_honoroit_rendered_labels['traefik.enable'] == 'true' + - matrix_bot_honoroit_rendered_labels['traefik.docker.network'] == matrix_bot_honoroit_container_network + - matrix_bot_honoroit_rendered_labels['traefik.http.services.matrix-bot-honoroit-metrics.loadbalancer.server.port'] == (matrix_bot_honoroit_container_port | string) + - matrix_bot_honoroit_rendered_labels['traefik.http.routers.matrix-bot-honoroit-metrics.rule'] == 'Host(`honoroit.molecule.local`) && Path(`/molecule-honoroit/molecule-metrics`)' + - matrix_bot_honoroit_rendered_labels['traefik.http.routers.matrix-bot-honoroit-metrics.priority'] == '710' + - matrix_bot_honoroit_rendered_labels['traefik.http.routers.matrix-bot-honoroit-metrics.service'] == 'matrix-bot-honoroit-metrics' + - matrix_bot_honoroit_rendered_labels['traefik.http.routers.matrix-bot-honoroit-metrics.entrypoints'] == 'molecule-web' + - matrix_bot_honoroit_rendered_labels['traefik.http.routers.matrix-bot-honoroit-metrics.tls'] == 'false' + - matrix_bot_honoroit_rendered_labels['traefik.http.routers.matrix-bot-honoroit-metrics.tls.certResolver'] is not defined + fail_msg: "The parsed labels lost the scenario's metrics router contract" + success_msg: "The parsed labels contain the configured metrics router" + + - name: Assert the parsed labels contain the configured middleware chain + ansible.builtin.assert: + that: + - matrix_bot_honoroit_rendered_labels['traefik.http.middlewares.matrix-bot-honoroit-slashless-redirect.redirectregex.regex'] == '(/molecule-honoroit)$' + - matrix_bot_honoroit_rendered_labels['traefik.http.middlewares.matrix-bot-honoroit-slashless-redirect.redirectregex.replacement'] == '${1}/' + - matrix_bot_honoroit_rendered_labels['traefik.http.middlewares.matrix-bot-honoroit-strip-prefix.stripprefix.prefixes'] == '/molecule-honoroit' + - matrix_bot_honoroit_rendered_labels['traefik.http.middlewares.matrix-bot-honoroit-add-headers.headers.customresponseheaders.X-Molecule-Honoroit'] == 'scenario' + - matrix_bot_honoroit_rendered_labels['traefik.http.middlewares.matrix-bot-honoroit-add-headers.headers.customresponseheaders.X-Robots-Tag'] == 'noindex' + - matrix_bot_honoroit_rendered_labels['traefik.http.routers.matrix-bot-honoroit-metrics.middlewares'] == 'matrix-bot-honoroit-slashless-redirect,matrix-bot-honoroit-strip-prefix,matrix-bot-honoroit-add-headers' + fail_msg: "The parsed labels lost the scenario's path and response-header middlewares" + success_msg: "The parsed labels contain the configured middleware chain" + + - name: Assert the live container received the rendered router and middleware labels + ansible.builtin.assert: + that: + - matrix_bot_honoroit_runtime.Config.Labels['traefik.http.services.matrix-bot-honoroit-metrics.loadbalancer.server.port'] == (matrix_bot_honoroit_container_port | string) + - matrix_bot_honoroit_runtime.Config.Labels['traefik.http.routers.matrix-bot-honoroit-metrics.rule'] == matrix_bot_honoroit_rendered_labels['traefik.http.routers.matrix-bot-honoroit-metrics.rule'] + - matrix_bot_honoroit_runtime.Config.Labels['traefik.http.routers.matrix-bot-honoroit-metrics.priority'] == matrix_bot_honoroit_rendered_labels['traefik.http.routers.matrix-bot-honoroit-metrics.priority'] + - matrix_bot_honoroit_runtime.Config.Labels['traefik.http.routers.matrix-bot-honoroit-metrics.middlewares'] == matrix_bot_honoroit_rendered_labels['traefik.http.routers.matrix-bot-honoroit-metrics.middlewares'] + - matrix_bot_honoroit_runtime.Config.Labels['traefik.http.middlewares.matrix-bot-honoroit-add-headers.headers.customresponseheaders.X-Molecule-Honoroit'] == 'scenario' + - matrix_bot_honoroit_runtime.Config.Labels['molecule.honoroit.scenario'] == 'live-postgres-and-metrics' + fail_msg: "The live container labels differ from the rendered routing contract" + success_msg: "The live container received the rendered router and middleware labels" + + - name: Inspect role-rendered support file ownership and permissions + ansible.builtin.stat: + path: "{{ item }}" + loop: + - "{{ matrix_bot_honoroit_config_path }}/env" + - "{{ matrix_bot_honoroit_config_path }}/labels" + register: matrix_bot_honoroit_support_files + + - name: Assert support files are owned by Matrix and not world-readable + ansible.builtin.assert: + that: + - matrix_bot_honoroit_support_files.results | map(attribute='stat.uid') | unique | list == [1234] + - matrix_bot_honoroit_support_files.results | map(attribute='stat.gid') | unique | list == [1234] + - matrix_bot_honoroit_support_files.results | map(attribute='stat.mode') | unique | list == ['0640'] + fail_msg: "Honoroit's support files have unexpected ownership or permissions" + success_msg: "Honoroit's support files are Matrix-owned and mode 0640" diff --git a/roles/custom/matrix-bot-honoroit/tasks/setup_install.yml b/roles/custom/matrix-bot-honoroit/tasks/setup_install.yml index 7bbfb66da..846bcbf19 100644 --- a/roles/custom/matrix-bot-honoroit/tasks/setup_install.yml +++ b/roles/custom/matrix-bot-honoroit/tasks/setup_install.yml @@ -63,17 +63,25 @@ register: matrix_bot_honoroit_support_files_result - name: Ensure Honoroit image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_bot_honoroit_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_bot_honoroit_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_honoroit_container_image_force_pull }}" + pull: always when: "not matrix_bot_honoroit_container_image_self_build | bool" register: matrix_bot_honoroit_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_bot_honoroit_container_image_pull_result is not failed +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Honoroit repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bot_honoroit_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bot_honoroit_container_image_self_build | bool" + - name: Ensure Honoroit repository is present on self-build ansible.builtin.git: repo: "{{ matrix_bot_honoroit_container_repo }}" @@ -86,18 +94,17 @@ when: "matrix_bot_honoroit_container_image_self_build | bool" - name: Ensure Honoroit image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_bot_honoroit_container_image }}" - source: build - force_source: "{{ matrix_bot_honoroit_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_honoroit_container_image_self_build.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_bot_honoroit_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_bot_honoroit_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bot_honoroit_git_pull_results.changed | bool else 'never' }}" when: "matrix_bot_honoroit_container_image_self_build | bool" + register: matrix_bot_honoroit_container_image_build_result - name: Ensure Honoroit container network is created + when: matrix_bot_honoroit_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_bot_honoroit_container_network }}" @@ -119,6 +126,7 @@ or matrix_bot_honoroit_support_files_result.changed | default(false) or matrix_bot_honoroit_systemd_service_result.changed | default(false) or matrix_bot_honoroit_container_image_pull_result.changed | default(false) + or matrix_bot_honoroit_container_image_build_result.changed | default(false) }} - name: Ensure matrix-bot-honoroit.service restarted, if necessary diff --git a/roles/custom/matrix-bot-honoroit/tasks/validate_config.yml b/roles/custom/matrix-bot-honoroit/tasks/validate_config.yml index e7d93f068..417ce83fb 100644 --- a/roles/custom/matrix-bot-honoroit/tasks/validate_config.yml +++ b/roles/custom/matrix-bot-honoroit/tasks/validate_config.yml @@ -16,6 +16,7 @@ - {'old': 'matrix_bot_honoroit_container_image_name_prefix', 'new': 'matrix_bot_honoroit_container_image_registry_prefix'} - {'old': 'matrix_bot_honoroit_docker_image', 'new': 'matrix_bot_honoroit_container_image'} - {'old': 'matrix_bot_honoroit_docker_image_force_pull', 'new': 'matrix_bot_honoroit_container_image_force_pull'} + - {'old': 'matrix_bot_honoroit_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - {'old': 'matrix_bot_honoroit_docker_image_registry_prefix', 'new': 'matrix_bot_honoroit_container_image_registry_prefix'} - {'old': 'matrix_bot_honoroit_docker_image_registry_prefix_upstream', 'new': 'matrix_bot_honoroit_container_image_registry_prefix_upstream'} - {'old': 'matrix_bot_honoroit_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bot_honoroit_container_image_registry_prefix_upstream_default'} diff --git a/roles/custom/matrix-bot-honoroit/templates/env.j2 b/roles/custom/matrix-bot-honoroit/templates/env.j2 index 5383b6525..7972c9397 100644 --- a/roles/custom/matrix-bot-honoroit/templates/env.j2 +++ b/roles/custom/matrix-bot-honoroit/templates/env.j2 @@ -11,6 +11,7 @@ HONOROIT_LOGIN={{ matrix_bot_honoroit_login }} HONOROIT_PASSWORD={{ matrix_bot_honoroit_password }} HONOROIT_HOMESERVER={{ matrix_bot_honoroit_homeserver }} HONOROIT_ROOMID={{ matrix_bot_honoroit_roomid }} +HONOROIT_PORT=:{{ matrix_bot_honoroit_container_port }} HONOROIT_DB_DSN={{ matrix_bot_honoroit_database_connection_string }} HONOROIT_DB_DIALECT={{ matrix_bot_honoroit_database_dialect }} HONOROIT_PREFIX={{ matrix_bot_honoroit_prefix }} diff --git a/roles/custom/matrix-bot-honoroit/templates/labels.j2 b/roles/custom/matrix-bot-honoroit/templates/labels.j2 index 4a027ddad..c136a1e17 100644 --- a/roles/custom/matrix-bot-honoroit/templates/labels.j2 +++ b/roles/custom/matrix-bot-honoroit/templates/labels.j2 @@ -12,10 +12,9 @@ traefik.enable=true traefik.docker.network={{ matrix_bot_honoroit_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.matrix-bot-honoroit-metrics.loadbalancer.server.port=8080 +traefik.http.services.matrix-bot-honoroit-metrics.loadbalancer.server.port={{ matrix_bot_honoroit_container_port }} {% set middlewares = [] %} -{% set middlewares_metrics = [] %} {% if matrix_bot_honoroit_container_labels_traefik_path_prefix != '/' %} traefik.http.middlewares.matrix-bot-honoroit-slashless-redirect.redirectregex.regex=({{ matrix_bot_honoroit_container_labels_traefik_path_prefix | quote }})$ @@ -35,19 +34,19 @@ traefik.http.middlewares.matrix-bot-honoroit-add-headers.headers.customresponseh {% set middlewares = middlewares + ['matrix-bot-honoroit-add-headers'] %} {% endif %} -{% if middlewares_metrics | length > 0 %} traefik.http.routers.matrix-bot-honoroit-metrics.rule={{ matrix_bot_honoroit_container_labels_traefik_metrics_rule }} {% if matrix_bot_honoroit_container_labels_traefik_priority | int > 0 %} traefik.http.routers.matrix-bot-honoroit-metrics.priority={{ matrix_bot_honoroit_container_labels_traefik_priority }} {% endif %} traefik.http.routers.matrix-bot-honoroit-metrics.service=matrix-bot-honoroit-metrics -traefik.http.routers.matrix-bot-honoroit-metrics.middlewares={{ middlewares_metrics | join(',') }} +{% if middlewares | length > 0 %} +traefik.http.routers.matrix-bot-honoroit-metrics.middlewares={{ middlewares | join(',') }} +{% endif %} traefik.http.routers.matrix-bot-honoroit-metrics.entrypoints={{ matrix_bot_honoroit_container_labels_traefik_entrypoints }} traefik.http.routers.matrix-bot-honoroit-metrics.tls={{ matrix_bot_honoroit_container_labels_traefik_tls | to_json }} {% if matrix_bot_honoroit_container_labels_traefik_tls %} traefik.http.routers.matrix-bot-honoroit-metrics.tls.certResolver={{ matrix_bot_honoroit_container_labels_traefik_tls_certResolver }} {% endif %} -{% endif %} {% endif %} diff --git a/roles/custom/matrix-bot-honoroit/templates/systemd/matrix-bot-honoroit.service.j2 b/roles/custom/matrix-bot-honoroit/templates/systemd/matrix-bot-honoroit.service.j2 index 7ffc8313a..dd802eb6b 100644 --- a/roles/custom/matrix-bot-honoroit/templates/systemd/matrix-bot-honoroit.service.j2 +++ b/roles/custom/matrix-bot-honoroit/templates/systemd/matrix-bot-honoroit.service.j2 @@ -32,9 +32,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_bot_honoroit_container_image }} +{% if matrix_bot_honoroit_container_network != 'host' %} {% for network in matrix_bot_honoroit_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-honoroit {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-honoroit diff --git a/roles/custom/matrix-bot-matrix-registration-bot/defaults/main.yml b/roles/custom/matrix-bot-matrix-registration-bot/defaults/main.yml deleted file mode 100644 index a5062fa47..000000000 --- a/roles/custom/matrix-bot-matrix-registration-bot/defaults/main.yml +++ /dev/null @@ -1,87 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2023 Julian-Samuel Gebühr -# SPDX-FileCopyrightText: 2022 - 2025 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 Erick Wibben -# SPDX-FileCopyrightText: 2022 MDAD project contributors -# SPDX-FileCopyrightText: 2022 Nikita Chernyi -# SPDX-FileCopyrightText: 2023 Samuel Meenzen -# SPDX-FileCopyrightText: 2024 - 2025 Suguru Hirahara -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- -# matrix-registration-bot creates and manages registration tokens for a Matrix server -# Project source code URL: https://github.com/moan0s/matrix-registration-bot - -matrix_bot_matrix_registration_bot_enabled: true -matrix_bot_matrix_registration_bot_container_image_self_build: false -matrix_bot_matrix_registration_bot_container_repo: "https://github.com/moan0s/matrix-registration-bot.git" -matrix_bot_matrix_registration_bot_container_repo_version: "{{ 'main' if matrix_bot_matrix_registration_bot_version == 'latest' else ('v' + matrix_bot_matrix_registration_bot_version) }}" -matrix_bot_matrix_registration_bot_container_src_files_path: "{{ matrix_bot_matrix_registration_bot_base_path }}/docker-src" - -# renovate: datasource=docker depName=moanos/matrix-registration-bot -matrix_bot_matrix_registration_bot_version: 1.3.0 -matrix_bot_matrix_registration_bot_container_iteration: 0 -matrix_bot_matrix_registration_bot_container_tag: "{{ matrix_bot_matrix_registration_bot_version }}-{{ matrix_bot_matrix_registration_bot_container_iteration }}" -matrix_bot_matrix_registration_bot_container_image: "{{ matrix_bot_matrix_registration_bot_container_image_registry_prefix }}moanos/matrix-registration-bot:{{ matrix_bot_matrix_registration_bot_container_tag }}" -matrix_bot_matrix_registration_bot_container_image_registry_prefix: "{{ 'localhost/' if matrix_bot_matrix_registration_bot_container_image_self_build else matrix_bot_matrix_registration_bot_container_image_registry_prefix_upstream }}" -matrix_bot_matrix_registration_bot_container_image_registry_prefix_upstream: "{{ matrix_bot_matrix_registration_bot_container_image_registry_prefix_upstream_default }}" -matrix_bot_matrix_registration_bot_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_bot_matrix_registration_bot_container_image_force_pull: "{{ matrix_bot_matrix_registration_bot_container_image.endswith(':latest') }}" - -matrix_bot_matrix_registration_bot_base_path: "{{ matrix_base_data_path }}/matrix-registration-bot" -matrix_bot_matrix_registration_bot_config_path: "{{ matrix_bot_matrix_registration_bot_base_path }}/config" -matrix_bot_matrix_registration_bot_data_path: "{{ matrix_bot_matrix_registration_bot_base_path }}/data" - -matrix_bot_matrix_registration_bot_bot_server: "{{ matrix_homeserver_url }}" - -# The bot's username. This user needs to be created manually beforehand. -# Also see `matrix_bot_matrix_registration_bot_user_password`. -matrix_bot_matrix_registration_bot_matrix_user_id_localpart: "bot.matrix-registration-bot" - -matrix_bot_matrix_registration_bot_matrix_user_id: '@{{ matrix_bot_matrix_registration_bot_matrix_user_id_localpart }}:{{ matrix_domain }}' - -# The bot's password (can also be used to login via a client like Element Web) -matrix_bot_matrix_registration_bot_bot_password: '' - -# Optional bot command prefix -matrix_bot_matrix_registration_bot_bot_prefix: "" - -# Homeserver base URL -matrix_bot_matrix_registration_bot_api_base_url: "{{ matrix_homeserver_url }}" - -# Optional variable that only needs to be set if the bot account is not admin -# Needs to be a valid access token of an admin account -matrix_bot_matrix_registration_bot_api_token: '' - -matrix_bot_matrix_registration_bot_device_id: "matrix-docker-ansible-deploy" - -# Valid values: ERROR, INFO, DEBUG -matrix_bot_matrix_registration_bot_logging_level: INFO - -matrix_bot_matrix_registration_bot_container_network: "" - -matrix_bot_matrix_registration_bot_container_additional_networks: "{{ matrix_bot_matrix_registration_bot_container_additional_networks_auto + matrix_bot_matrix_registration_bot_container_additional_networks_custom }}" -matrix_bot_matrix_registration_bot_container_additional_networks_auto: [] -matrix_bot_matrix_registration_bot_container_additional_networks_custom: [] - -# A list of extra arguments to pass to the container -matrix_bot_matrix_registration_bot_container_extra_arguments: [] - -# List of systemd services that matrix-bot-matrix-registration-bot.service depends on -matrix_bot_matrix_registration_bot_systemd_required_services_list: "{{ matrix_bot_matrix_registration_bot_systemd_required_services_list_default + matrix_bot_matrix_registration_bot_systemd_required_services_list_auto + matrix_bot_matrix_registration_bot_systemd_required_services_list_custom }}" -matrix_bot_matrix_registration_bot_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_bot_matrix_registration_bot_systemd_required_services_list_auto: [] -matrix_bot_matrix_registration_bot_systemd_required_services_list_custom: [] - -# List of systemd services that matrix-bot-matrix-registration-bot.service wants -matrix_bot_matrix_registration_bot_systemd_wanted_services_list: [] - -# matrix_bot_matrix_registration_bot_restart_necessary controls whether the service -# will be restarted (when true) or merely started (when false) by the -# systemd service manager role (when conditional restart is enabled). -# -# This value is automatically computed during installation based on whether -# any configuration files, the systemd service file, or the container image changed. -# The default of `false` means "no restart needed" — appropriate when the role's -# installation tasks haven't run (e.g., due to --tags skipping them). -matrix_bot_matrix_registration_bot_restart_necessary: false diff --git a/roles/custom/matrix-bot-matrix-registration-bot/tasks/clean_cache.yml b/roles/custom/matrix-bot-matrix-registration-bot/tasks/clean_cache.yml deleted file mode 100644 index c5b600426..000000000 --- a/roles/custom/matrix-bot-matrix-registration-bot/tasks/clean_cache.yml +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Julian-Samuel Gebühr -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Delete cache files - ansible.builtin.file: - state: "{{ item }}" - path: "{{ matrix_bot_matrix_registration_bot_data_path }}" - mode: '0750' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - with_items: - - absent - - directory diff --git a/roles/custom/matrix-bot-matrix-registration-bot/tasks/main.yml b/roles/custom/matrix-bot-matrix-registration-bot/tasks/main.yml deleted file mode 100644 index b420f4cde..000000000 --- a/roles/custom/matrix-bot-matrix-registration-bot/tasks/main.yml +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2023 Julian-Samuel Gebühr -# SPDX-FileCopyrightText: 2022 - 2023 Slavi Pantaleev -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- tags: - - setup-all - - setup-bot-matrix-registration-bot - - install-all - - install-bot-matrix-registration-bot - block: - - when: matrix_bot_matrix_registration_bot_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - - when: matrix_bot_matrix_registration_bot_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - -- tags: - - setup-all - - setup-bot-matrix-registration-bot - block: - - when: not matrix_bot_matrix_registration_bot_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" - -- tags: - - bot-matrix-registration-bot-clean-cache - block: - - when: matrix_bot_matrix_registration_bot_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/clean_cache.yml" diff --git a/roles/custom/matrix-bot-matrix-registration-bot/tasks/setup_install.yml b/roles/custom/matrix-bot-matrix-registration-bot/tasks/setup_install.yml deleted file mode 100644 index c1f2af9cd..000000000 --- a/roles/custom/matrix-bot-matrix-registration-bot/tasks/setup_install.yml +++ /dev/null @@ -1,89 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2023 Julian-Samuel Gebühr -# SPDX-FileCopyrightText: 2022 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 Sebastian Gumprich -# SPDX-FileCopyrightText: 2024 - 2025 Suguru Hirahara -# SPDX-FileCopyrightText: 2024 David Mehren -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Ensure matrix-registration-bot paths exist - ansible.builtin.file: - path: "{{ item.path }}" - state: directory - mode: '0750' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - with_items: - - {path: "{{ matrix_bot_matrix_registration_bot_config_path }}", when: true} - - {path: "{{ matrix_bot_matrix_registration_bot_data_path }}", when: true} - - {path: "{{ matrix_bot_matrix_registration_bot_container_src_files_path }}", when: "{{ matrix_bot_matrix_registration_bot_container_image_self_build }}"} - when: "item.when | bool" - -- name: Ensure matrix-registration-bot configuration file created - ansible.builtin.template: - src: "{{ role_path }}/templates/config.yaml.j2" - dest: "{{ matrix_bot_matrix_registration_bot_config_path }}/config.yaml" - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - mode: '0640' - register: matrix_bot_matrix_registration_bot_config_result - -- name: Ensure matrix-registration-bot image is pulled - community.docker.docker_image: - name: "{{ matrix_bot_matrix_registration_bot_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_bot_matrix_registration_bot_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_matrix_registration_bot_container_image_force_pull }}" - when: "not matrix_bot_matrix_registration_bot_container_image_self_build | bool" - register: matrix_bot_matrix_registration_bot_container_image_pull_result - retries: "{{ devture_playbook_help_container_retries_count }}" - delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_bot_matrix_registration_bot_container_image_pull_result is not failed - -- when: matrix_bot_matrix_registration_bot_container_image_self_build | bool - block: - - name: Ensure matrix-registration-bot repository is present on self-build - ansible.builtin.git: - repo: "{{ matrix_bot_matrix_registration_bot_container_repo }}" - version: "{{ matrix_bot_matrix_registration_bot_container_repo_version }}" - dest: "{{ matrix_bot_matrix_registration_bot_container_src_files_path }}" - force: "yes" - become: true - become_user: "{{ matrix_user_name }}" - register: matrix_bot_matrix_registration_bot_git_pull_results - - - name: Ensure matrix-registration-bot image is built - community.docker.docker_image: - name: "{{ matrix_bot_matrix_registration_bot_container_image }}" - source: build - force_source: "{{ matrix_bot_matrix_registration_bot_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_matrix_registration_bot_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_bot_matrix_registration_bot_container_src_files_path }}" - pull: true - -- name: Ensure matrix-registration-bot container network is created - community.general.docker_network: - enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_bot_matrix_registration_bot_container_network }}" - driver: bridge - driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - -- name: Ensure matrix-bot-matrix-registration-bot.service installed - ansible.builtin.template: - src: "{{ role_path }}/templates/systemd/matrix-bot-matrix-registration-bot.service.j2" - dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-matrix-registration-bot.service" - mode: '0644' - register: matrix_bot_matrix_registration_bot_systemd_service_result - -- name: Determine whether matrix-registration-bot needs a restart - ansible.builtin.set_fact: - matrix_bot_matrix_registration_bot_restart_necessary: >- - {{ - matrix_bot_matrix_registration_bot_config_result.changed | default(false) - or matrix_bot_matrix_registration_bot_systemd_service_result.changed | default(false) - or matrix_bot_matrix_registration_bot_container_image_pull_result.changed | default(false) - }} diff --git a/roles/custom/matrix-bot-matrix-registration-bot/tasks/setup_uninstall.yml b/roles/custom/matrix-bot-matrix-registration-bot/tasks/setup_uninstall.yml deleted file mode 100644 index 662f8e5da..000000000 --- a/roles/custom/matrix-bot-matrix-registration-bot/tasks/setup_uninstall.yml +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Julian-Samuel Gebühr -# SPDX-FileCopyrightText: 2022 Sebastian Gumprich -# SPDX-FileCopyrightText: 2022 Slavi Pantaleev -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Check existence of matrix-matrix-registration-bot service - ansible.builtin.stat: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-matrix-registration-bot.service" - register: matrix_bot_matrix_registration_bot_service_stat - -- when: matrix_bot_matrix_registration_bot_service_stat.stat.exists | bool - block: - - name: Ensure matrix-matrix-registration-bot is stopped - ansible.builtin.service: - name: matrix-bot-matrix-registration-bot - state: stopped - enabled: false - daemon_reload: true - - - name: Ensure matrix-bot-matrix-registration-bot.service doesn't exist - ansible.builtin.file: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-matrix-registration-bot.service" - state: absent - - - name: Ensure Matrix matrix-registration-bot paths don't exist - ansible.builtin.file: - path: "{{ matrix_bot_matrix_registration_bot_base_path }}" - state: absent diff --git a/roles/custom/matrix-bot-matrix-registration-bot/tasks/validate_config.yml b/roles/custom/matrix-bot-matrix-registration-bot/tasks/validate_config.yml deleted file mode 100644 index 73c2bcd3a..000000000 --- a/roles/custom/matrix-bot-matrix-registration-bot/tasks/validate_config.yml +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2023 Julian-Samuel Gebühr -# SPDX-FileCopyrightText: 2022 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2025 Suguru Hirahara -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: (Deprecation) Catch and report renamed settings - ansible.builtin.fail: - msg: >- - Your configuration contains a variable, which now has a different name. - Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). - when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" - with_items: - - {'old': 'matrix_bot_matrix_registration_bot_bot_access_token', 'new': ''} - - {'old': 'matrix_bot_matrix_registration_bot_matrix_homeserver_url', 'new': 'matrix_bot_matrix_registration_bot_api_base_url'} - - {'old': 'matrix_bot_matrix_registration_bot_docker_image', 'new': 'matrix_bot_matrix_registration_bot_container_image'} - - {'old': 'matrix_bot_matrix_registration_bot_docker_image_force_pull', 'new': 'matrix_bot_matrix_registration_bot_container_image_force_pull'} - - {'old': 'matrix_bot_matrix_registration_bot_docker_image_registry_prefix', 'new': 'matrix_bot_matrix_registration_bot_container_image_registry_prefix'} - - {'old': 'matrix_bot_matrix_registration_bot_docker_image_registry_prefix_upstream', 'new': 'matrix_bot_matrix_registration_bot_container_image_registry_prefix_upstream'} - - {'old': 'matrix_bot_matrix_registration_bot_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bot_matrix_registration_bot_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_bot_matrix_registration_bot_docker_iteration', 'new': 'matrix_bot_matrix_registration_bot_container_iteration'} - - {'old': 'matrix_bot_matrix_registration_bot_docker_repo', 'new': 'matrix_bot_matrix_registration_bot_container_repo'} - - {'old': 'matrix_bot_matrix_registration_bot_docker_repo_version', 'new': 'matrix_bot_matrix_registration_bot_container_repo_version'} - - {'old': 'matrix_bot_matrix_registration_bot_docker_src_files_path', 'new': 'matrix_bot_matrix_registration_bot_container_src_files_path'} - - {'old': 'matrix_bot_matrix_registration_bot_docker_tag', 'new': 'matrix_bot_matrix_registration_bot_container_tag'} - -- name: Fail if required settings not defined - ansible.builtin.fail: - msg: >- - You need to define a required configuration setting (`{{ item }}`). - when: "lookup('vars', item, default='') == ''" - with_items: - - "matrix_bot_matrix_registration_bot_bot_password" - - "matrix_bot_matrix_registration_bot_api_base_url" diff --git a/roles/custom/matrix-bot-matrix-registration-bot/templates/config.yaml.j2 b/roles/custom/matrix-bot-matrix-registration-bot/templates/config.yaml.j2 deleted file mode 100644 index c5738594d..000000000 --- a/roles/custom/matrix-bot-matrix-registration-bot/templates/config.yaml.j2 +++ /dev/null @@ -1,24 +0,0 @@ -{# -SPDX-FileCopyrightText: 2022 - 2023 Julian-Samuel Gebühr -SPDX-FileCopyrightText: 2022 Slavi Pantaleev -SPDX-FileCopyrightText: 2024 - 2025 Suguru Hirahara - -SPDX-License-Identifier: AGPL-3.0-or-later -#} - -bot: - server: {{ matrix_bot_matrix_registration_bot_bot_server|to_json }} - username: {{ matrix_bot_matrix_registration_bot_matrix_user_id_localpart|to_json }} - password: {{ matrix_bot_matrix_registration_bot_bot_password|to_json }} - prefix: {{ matrix_bot_matrix_registration_bot_bot_prefix|to_json }} - -api: - # API endpoint of the registration tokens - base_url: {{ matrix_bot_matrix_registration_bot_api_base_url|to_json }} -{% if matrix_bot_matrix_registration_bot_api_token | length > 0 %} - # Access token of an administrator on the server - token: {{ matrix_bot_matrix_registration_bot_api_token|to_json }} -{% endif %} - -logging: - level: {{ matrix_bot_matrix_registration_bot_logging_level|to_json }} diff --git a/roles/custom/matrix-bot-matrix-registration-bot/templates/systemd/matrix-bot-matrix-registration-bot.service.j2 b/roles/custom/matrix-bot-matrix-registration-bot/templates/systemd/matrix-bot-matrix-registration-bot.service.j2 deleted file mode 100644 index e9f0c4204..000000000 --- a/roles/custom/matrix-bot-matrix-registration-bot/templates/systemd/matrix-bot-matrix-registration-bot.service.j2 +++ /dev/null @@ -1,45 +0,0 @@ -#jinja2: lstrip_blocks: True -[Unit] -Description=Matrix registration bot -{% for service in matrix_bot_matrix_registration_bot_systemd_required_services_list %} -Requires={{ service }} -After={{ service }} -{% endfor %} -{% for service in matrix_bot_matrix_registration_bot_systemd_wanted_services_list %} -Wants={{ service }} -{% endfor %} -DefaultDependencies=no - -[Service] -Type=simple -Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-bot-matrix-registration-bot 2>/dev/null || true' -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-bot-matrix-registration-bot 2>/dev/null || true' - -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ - --rm \ - --name=matrix-bot-matrix-registration-bot \ - --log-driver=none \ - --cap-drop=ALL \ - -e "CONFIG_PATH=/config/config.yaml" \ - --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ - --read-only \ - --mount type=bind,src={{ matrix_bot_matrix_registration_bot_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_bot_matrix_registration_bot_data_path }},dst=/data \ - --network={{ matrix_bot_matrix_registration_bot_container_network }} \ - {{ matrix_bot_matrix_registration_bot_container_image }} - -{% for network in matrix_bot_matrix_registration_bot_container_additional_networks %} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-matrix-registration-bot -{% endfor %} - -ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-matrix-registration-bot - -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-bot-matrix-registration-bot 2>/dev/null || true' -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-bot-matrix-registration-bot 2>/dev/null || true' -Restart=always -RestartSec=30 -SyslogIdentifier=matrix-bot-matrix-registration-bot - -[Install] -WantedBy=multi-user.target diff --git a/roles/custom/matrix-bot-matrix-registration-bot/templates/systemd/matrix-bot-matrix-registration-bot.service.j2.license b/roles/custom/matrix-bot-matrix-registration-bot/templates/systemd/matrix-bot-matrix-registration-bot.service.j2.license deleted file mode 100644 index 3a4dec62d..000000000 --- a/roles/custom/matrix-bot-matrix-registration-bot/templates/systemd/matrix-bot-matrix-registration-bot.service.j2.license +++ /dev/null @@ -1,6 +0,0 @@ -SPDX-FileCopyrightText: 2022 - 2025 Slavi Pantaleev -SPDX-FileCopyrightText: 2022 Erick Wibben -SPDX-FileCopyrightText: 2022 Julian-Samuel Gebühr -SPDX-FileCopyrightText: 2024 - 2025 Suguru Hirahara - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bot-matrix-reminder-bot/defaults/main.yml b/roles/custom/matrix-bot-matrix-reminder-bot/defaults/main.yml index c4f14fe2b..9eb2d0662 100644 --- a/roles/custom/matrix-bot-matrix-reminder-bot/defaults/main.yml +++ b/roles/custom/matrix-bot-matrix-reminder-bot/defaults/main.yml @@ -25,7 +25,6 @@ matrix_bot_matrix_reminder_bot_container_image: "{{ matrix_bot_matrix_reminder_b matrix_bot_matrix_reminder_bot_container_image_registry_prefix: "{{ 'localhost/' if matrix_bot_matrix_reminder_bot_container_image_self_build else matrix_bot_matrix_reminder_bot_container_image_registry_prefix_upstream }}" matrix_bot_matrix_reminder_bot_container_image_registry_prefix_upstream: "{{ matrix_bot_matrix_reminder_bot_container_image_registry_prefix_upstream_default }}" matrix_bot_matrix_reminder_bot_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_bot_matrix_reminder_bot_container_image_force_pull: "{{ matrix_bot_matrix_reminder_bot_container_image.endswith(':latest') }}" matrix_bot_matrix_reminder_bot_base_path: "{{ matrix_base_data_path }}/matrix-reminder-bot" matrix_bot_matrix_reminder_bot_config_path: "{{ matrix_bot_matrix_reminder_bot_base_path }}/config" @@ -72,12 +71,10 @@ matrix_bot_matrix_reminder_bot_database_name: 'matrix_reminder_bot' matrix_bot_matrix_reminder_bot_database_connection_string: 'postgres://{{ matrix_bot_matrix_reminder_bot_database_username }}:{{ matrix_bot_matrix_reminder_bot_database_password }}@{{ matrix_bot_matrix_reminder_bot_database_hostname }}:{{ matrix_bot_matrix_reminder_bot_database_port }}/{{ matrix_bot_matrix_reminder_bot_database_name }}' -matrix_bot_matrix_reminder_bot_storage_database: "{{ - { - 'sqlite': ('sqlite://' + matrix_bot_matrix_reminder_bot_sqlite_database_path_in_container), - 'postgres': matrix_bot_matrix_reminder_bot_database_connection_string, - }[matrix_bot_matrix_reminder_bot_database_engine] -}}" +matrix_bot_matrix_reminder_bot_storage_database: "{{ { + 'sqlite': ('sqlite://' + matrix_bot_matrix_reminder_bot_sqlite_database_path_in_container), + 'postgres': matrix_bot_matrix_reminder_bot_database_connection_string, +}[matrix_bot_matrix_reminder_bot_database_engine] }}" # The bot's username. This user needs to be created manually beforehand. diff --git a/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/converge.yml b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/converge.yml new file mode 100644 index 000000000..f309aa8d2 --- /dev/null +++ b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/converge.yml @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# The devture base roles carry the variables this role reads, the same way they do when +# the playbook runs. `matrix-base` is deliberately NOT included: it does far more than this +# role needs, and what it would supply comes from molecule-shared/playbook-context.yml. +- name: Include roles for matrix-reminder-bot Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-reminder-bot Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +# The role installs the unit but does not start it; in the playbook that is +# `systemd_service_manager`'s job. +- name: Ensure matrix-reminder-bot is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure matrix-bot-matrix-reminder-bot systemd service is started + ansible.builtin.systemd_service: + name: matrix-bot-matrix-reminder-bot.service + state: started diff --git a/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/molecule.yml b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/molecule.yml new file mode 100644 index 000000000..ed3ad33b3 --- /dev/null +++ b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/molecule.yml @@ -0,0 +1,97 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-reminder-bot-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bot_matrix_reminder_bot_container_network: matrix-reminder-bot-molecule + + # Unlike the bridges, this bot is not an appservice: it logs in as an ordinary user + # with a password. The stub answers /_matrix/client/v3/login with an access token, + # which is all the bot needs to reach its sync loop. + matrix_bot_matrix_reminder_bot_matrix_homeserver_url: http://matrix.molecule.local:8008 + + # Different from the role's default localpart, so verify.yml can tell what the role + # rendered apart from what it would have rendered anyway. + matrix_bot_matrix_reminder_bot_matrix_user_id_localpart: molecule.reminder-bot + matrix_bot_matrix_reminder_bot_matrix_user_password: molecule_bot_password_4f2a91 + + # The role has no default here and refuses to run without one. Also different from the + # bot's own fallback, and it reaches the container twice: the config file and TZ. + matrix_bot_matrix_reminder_bot_reminders_timezone: Europe/Sofia + + # The role and the bot both default to `!`. + matrix_bot_matrix_reminder_bot_command_prefix: "%%" + + # Both lists default to off with no entries, so turning them on exercises the + # `_auto + _custom` composition. + matrix_bot_matrix_reminder_bot_allowlist_enabled: true + matrix_bot_matrix_reminder_bot_allowlist_regexes_custom: + - "@molecule-allowed:molecule.local" + matrix_bot_matrix_reminder_bot_blocklist_enabled: true + matrix_bot_matrix_reminder_bot_blocklist_regexes_custom: + - ".*:blocked.molecule.local" + + # The device name is hardcoded in the role's template, so overriding it is only + # possible through the extension mechanism - which tests that merge too. + matrix_bot_matrix_reminder_bot_configuration_extension_yaml: | + matrix: + device_name: Molecule Reminder Bot + + # Postgres, because that is what `group_vars/matrix_servers` selects whenever postgres + # is enabled - which is the default, so it is what essentially every real deployment + # runs. prepare.yml stands one up. Name and user differ from the role's defaults, so + # reaching the database proves the role built its connection string out of these. + matrix_bot_matrix_reminder_bot_database_engine: postgres + matrix_bot_matrix_reminder_bot_database_hostname: matrix-postgres-molecule + matrix_bot_matrix_reminder_bot_database_name: molecule_reminder_bot + matrix_bot_matrix_reminder_bot_database_username: molecule_reminder_bot + matrix_bot_matrix_reminder_bot_database_password: molecule_pg_password_3c9b02 + + # verify.yml runs as its own play, where the role's defaults are out of scope, + # so the paths it reads are pinned here to match what the role derives. + matrix_bot_matrix_reminder_bot_base_path: /matrix/matrix-reminder-bot + matrix_bot_matrix_reminder_bot_config_path: /matrix/matrix-reminder-bot/config + matrix_bot_matrix_reminder_bot_data_path: /matrix/matrix-reminder-bot/data + matrix_bot_matrix_reminder_bot_data_store_path: /matrix/matrix-reminder-bot/data/store + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/prepare.yml b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/prepare.yml new file mode 100644 index 000000000..1daca59d8 --- /dev/null +++ b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/prepare.yml @@ -0,0 +1,91 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-reminder-bot Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks set owner/group by name, which Ansible resolves through the + # passwd database, so they have to exist first. `matrix-base` creates them for real. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role creates this network itself during converge, but the stub has to be on it + # before the bot starts. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bot_matrix_reminder_bot_container_network }}" + register: matrix_bot_matrix_reminder_bot_molecule_network + changed_when: matrix_bot_matrix_reminder_bot_molecule_network.rc == 0 + failed_when: + - matrix_bot_matrix_reminder_bot_molecule_network.rc != 0 + - "'already exists' not in matrix_bot_matrix_reminder_bot_molecule_network.stderr" + + # Not an appservice: it logs in with the username and password the role rendered, retrying + # every 15 seconds until that succeeds. The stub answers with an access token, which is + # enough to reach the sync loop. Nothing is asserted about the stub itself. + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bot_matrix_reminder_bot_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bot_matrix_reminder_bot_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bot_matrix_reminder_bot_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bot_matrix_reminder_bot_database_password }}" + + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bot_matrix_reminder_bot_container_network }}" + molecule_shared_stub_user_id: "@{{ matrix_bot_matrix_reminder_bot_matrix_user_id_localpart }}:{{ matrix_domain }}" diff --git a/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/requirements.yml b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/verify.yml b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/verify.yml new file mode 100644 index 000000000..d6f93d79e --- /dev/null +++ b/roles/custom/matrix-bot-matrix-reminder-bot/molecule/default/verify.yml @@ -0,0 +1,225 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves matrix-reminder-bot starts on the configuration the role rendered, logs in as the +# user the role gave it, opens the database at the path the role gave it, and is the version +# the role pins. +# +# The bot has no HTTP surface to probe, so the evidence is what it says about itself in the +# journal plus what it left on disk. It does NOT set real reminders. See docs/molecule-testing.md. +- name: Verify matrix-reminder-bot + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + + vars: + matrix_bot_matrix_reminder_bot_molecule_user_id: "@{{ matrix_bot_matrix_reminder_bot_matrix_user_id_localpart }}:{{ matrix_domain }}" + matrix_bot_matrix_reminder_bot_molecule_container_user: "{{ matrix_user_uid }}:{{ matrix_user_gid }}" + + tasks: + # Read from the role's own defaults rather than pinned in molecule.yml, so the version + # assertion compares the running image against what defaults/main.yml ships. + # Pinning it here would make that assertion compare the scenario with itself. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_bot_matrix_reminder_bot_role_defaults + + - name: Wait for the matrix-reminder-bot service to become active + ansible.builtin.systemd_service: + name: matrix-bot-matrix-reminder-bot.service + register: matrix_bot_matrix_reminder_bot_service + until: matrix_bot_matrix_reminder_bot_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # `Restart=always` means a bot crash-looping on unreadable config still reports `active`, + # so the restart counter is checked too. The config file is parsed before the bot's own + # catch-all retry loop starts, so anything wrong in what the role rendered shows up here + # as restarts. Asserted `is defined` because `| int` turns a missing property into 0. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - matrix_bot_matrix_reminder_bot_service.status.ActiveState == 'active' + - matrix_bot_matrix_reminder_bot_service.status.NRestarts is defined + - matrix_bot_matrix_reminder_bot_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-bot-matrix-reminder-bot.service is + {{ matrix_bot_matrix_reminder_bot_service.status.ActiveState | default('unknown') }} + after {{ matrix_bot_matrix_reminder_bot_service.status.NRestarts | default('?') }} + automatic restart(s) + success_msg: "matrix-bot-matrix-reminder-bot.service is active and has not restarted" + + # The unit runs `docker start --attach`, so the container's output is in the journal + # despite `--log-driver=none`. It is the only thing this bot reports about itself. + # + # Filtered rather than tailed: startup lines are the OLDEST in the journal, so a + # `--lines=N` tail loses them behind anything logged later, and reading it whole pulls + # unbounded text into a variable. The filter keeps the failure line too, so the + # "did not fail to log in" assertion below still has something to see. + - name: Wait for the bot to report that it finished starting up + ansible.builtin.shell: + cmd: >- + set -o pipefail; + journalctl --unit=matrix-bot-matrix-reminder-bot.service --no-pager --output=cat --lines=all + | grep -E 'Logged in as|Startup complete|Failed to login|Database initialization' | head -n 50 || true + executable: /bin/bash + register: matrix_bot_matrix_reminder_bot_journal + changed_when: false + until: "'Startup complete' in matrix_bot_matrix_reminder_bot_journal.stdout" + retries: 24 + delay: 5 + failed_when: false + + # "Logged in as ..." is only reached once the login call returned something other than a + # LoginError, so this covers the whole chain at once: homeserver URL, user ID and password + # were all good enough for a real login round-trip. + - name: Assert the bot logged in as the user the role configured + ansible.builtin.assert: + that: + - "'Startup complete' in matrix_bot_matrix_reminder_bot_journal.stdout" + - "'Logged in as ' + matrix_bot_matrix_reminder_bot_molecule_user_id in matrix_bot_matrix_reminder_bot_journal.stdout" + - "'Failed to login' not in matrix_bot_matrix_reminder_bot_journal.stdout" + fail_msg: >- + The bot did not log in as {{ matrix_bot_matrix_reminder_bot_molecule_user_id }} + and reach startup + success_msg: >- + The bot logged in as {{ matrix_bot_matrix_reminder_bot_molecule_user_id }} and finished starting up + + # The role picks the storage engine by building the connection string the bot parses, + # and the bot names the type it settled on once the database is open. + - name: Assert the bot opened the database engine the role selected + ansible.builtin.assert: + that: + - "\"Database initialization of type 'postgres' complete\" in matrix_bot_matrix_reminder_bot_journal.stdout" + fail_msg: "The bot did not report a completed Postgres database initialization" + success_msg: "The bot initialized the Postgres database the role pointed it at" + + - name: Read the configuration file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_matrix_reminder_bot_config_path }}/config.yaml" + register: matrix_bot_matrix_reminder_bot_config_file + + # Every one differs from both the role's defaults and the bot's own fallbacks, so their + # presence means the role rendered this file rather than coinciding with it. + - name: Assert the rendered configuration carries this scenario's values + ansible.builtin.assert: + that: + - matrix_bot_matrix_reminder_bot_molecule_user_id in matrix_bot_matrix_reminder_bot_config_rendered + - matrix_bot_matrix_reminder_bot_matrix_user_password in matrix_bot_matrix_reminder_bot_config_rendered + - matrix_bot_matrix_reminder_bot_matrix_homeserver_url in matrix_bot_matrix_reminder_bot_config_rendered + - matrix_bot_matrix_reminder_bot_reminders_timezone in matrix_bot_matrix_reminder_bot_config_rendered + - matrix_bot_matrix_reminder_bot_command_prefix in matrix_bot_matrix_reminder_bot_config_rendered + - matrix_bot_matrix_reminder_bot_database_username in matrix_bot_matrix_reminder_bot_config_rendered + - matrix_bot_matrix_reminder_bot_database_name in matrix_bot_matrix_reminder_bot_config_rendered + - matrix_bot_matrix_reminder_bot_database_hostname in matrix_bot_matrix_reminder_bot_config_rendered + - "'@molecule-allowed:molecule.local' in matrix_bot_matrix_reminder_bot_config_rendered" + - "'.*:blocked.molecule.local' in matrix_bot_matrix_reminder_bot_config_rendered" + fail_msg: "The rendered configuration does not carry the scenario's settings" + success_msg: "The rendered configuration carries the scenario's settings" + vars: + matrix_bot_matrix_reminder_bot_config_rendered: "{{ matrix_bot_matrix_reminder_bot_config_file.content | b64decode }}" + + # `device_name` is hardcoded in the role's template, so this value can only be here if + # `..._configuration_extension_yaml` was merged over it rather than ignored. + - name: Assert the configuration extension was merged over the template + ansible.builtin.assert: + that: + - "'device_name: Molecule Reminder Bot' in matrix_bot_matrix_reminder_bot_config_rendered" + - "'device_name: Reminder Bot' not in matrix_bot_matrix_reminder_bot_config_rendered" + fail_msg: >- + The configuration extension did not override the device name the + role's template hardcodes + success_msg: "The configuration extension was merged over the role's template" + vars: + matrix_bot_matrix_reminder_bot_config_rendered: "{{ matrix_bot_matrix_reminder_bot_config_file.content | b64decode }}" + + # With no HTTP surface, the schema in Postgres is the evidence that the storage + # configuration reached the running process rather than only the file on disk. The bot can + # only have created tables by resolving the hostname, authenticating with the credentials + # the role rendered, and running its migrations. + - name: List the tables the bot created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bot_matrix_reminder_bot_database_username }} + - --dbname={{ matrix_bot_matrix_reminder_bot_database_name }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: matrix_bot_matrix_reminder_bot_tables + changed_when: false + + - name: Assert the bot created its schema in the database the role pointed it at + ansible.builtin.assert: + that: + - matrix_bot_matrix_reminder_bot_tables.rc == 0 + - matrix_bot_matrix_reminder_bot_table_names | length > 0 + fail_msg: >- + The bot created no tables in {{ matrix_bot_matrix_reminder_bot_database_name }} + success_msg: "The bot created its schema in the database the role pointed it at" + vars: + matrix_bot_matrix_reminder_bot_table_names: "{{ matrix_bot_matrix_reminder_bot_tables.stdout_lines | select | list }}" + + # matrix-nio writes its encryption store here once login succeeds, so a populated directory + # means the bot could use the store path the role created inside a read-only container. + - name: List the encryption store the role created + ansible.builtin.find: + paths: "{{ matrix_bot_matrix_reminder_bot_data_store_path }}" + file_type: file + register: matrix_bot_matrix_reminder_bot_store_files + + - name: Assert the bot wrote its encryption store where the role put it + ansible.builtin.assert: + that: + - matrix_bot_matrix_reminder_bot_store_files.matched | int > 0 + fail_msg: >- + {{ matrix_bot_matrix_reminder_bot_data_store_path }} is empty, so the bot never + got far enough to open its encryption store + success_msg: "The bot wrote its encryption store under the role's data path" + + - name: Read the running container's user and environment + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-bot-matrix-reminder-bot + - --format + - "{{ '{{' }} .Config.User {{ '}}' }} {{ '{{' }} json .Config.Env {{ '}}' }} {{ '{{' }} .Config.Image {{ '}}' }}" + register: matrix_bot_matrix_reminder_bot_container + changed_when: false + + # The timezone reaches the container twice, through the config file checked above and + # through TZ on the unit. The uid/gid come from the playbook context, not from the image. + - name: Assert the container runs as the role's user with the configured timezone + ansible.builtin.assert: + that: + - "'\"TZ=' + matrix_bot_matrix_reminder_bot_reminders_timezone + '\"' in matrix_bot_matrix_reminder_bot_container.stdout" + - matrix_bot_matrix_reminder_bot_molecule_container_user in matrix_bot_matrix_reminder_bot_container.stdout + fail_msg: >- + The container does not run as {{ matrix_user_uid }}:{{ matrix_user_gid }} with + TZ={{ matrix_bot_matrix_reminder_bot_reminders_timezone }} + ({{ matrix_bot_matrix_reminder_bot_container.stdout }}) + success_msg: >- + The container runs as {{ matrix_user_uid }}:{{ matrix_user_gid }} with + TZ={{ matrix_bot_matrix_reminder_bot_reminders_timezone }} + + - name: Assert the running container is the version defaults/main.yml pins + ansible.builtin.assert: + that: + - matrix_bot_matrix_reminder_bot_role_defaults.matrix_bot_matrix_reminder_bot_version | string in matrix_bot_matrix_reminder_bot_container.stdout + fail_msg: >- + The running container is {{ matrix_bot_matrix_reminder_bot_container.stdout }}, which + does not carry the pinned version + {{ matrix_bot_matrix_reminder_bot_role_defaults.matrix_bot_matrix_reminder_bot_version }} + success_msg: "The running container is the version defaults/main.yml pins" diff --git a/roles/custom/matrix-bot-matrix-reminder-bot/tasks/setup_install.yml b/roles/custom/matrix-bot-matrix-reminder-bot/tasks/setup_install.yml index 56df00ef1..448d4bb8e 100644 --- a/roles/custom/matrix-bot-matrix-reminder-bot/tasks/setup_install.yml +++ b/roles/custom/matrix-bot-matrix-reminder-bot/tasks/setup_install.yml @@ -53,17 +53,25 @@ when: "item.when | bool" - name: Ensure matrix-reminder-bot image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_bot_matrix_reminder_bot_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_bot_matrix_reminder_bot_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_matrix_reminder_bot_container_image_force_pull }}" + pull: always when: "not matrix_bot_matrix_reminder_bot_container_image_self_build | bool" register: matrix_bot_matrix_reminder_bot_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_bot_matrix_reminder_bot_container_image_pull_result is not failed +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure matrix-reminder-bot repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bot_matrix_reminder_bot_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bot_matrix_reminder_bot_container_image_self_build | bool" + - name: Ensure matrix-reminder-bot repository is present on self-build ansible.builtin.git: repo: "{{ matrix_bot_matrix_reminder_bot_container_repo }}" @@ -76,16 +84,14 @@ when: "matrix_bot_matrix_reminder_bot_container_image_self_build | bool" - name: Ensure matrix-reminder-bot image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_bot_matrix_reminder_bot_container_image }}" - source: build - force_source: "{{ matrix_bot_matrix_reminder_bot_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_matrix_reminder_bot_git_pull_results.changed }}" - build: - dockerfile: docker/Dockerfile - path: "{{ matrix_bot_matrix_reminder_bot_container_src_files_path }}" - pull: true + dockerfile: docker/Dockerfile + path: "{{ matrix_bot_matrix_reminder_bot_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bot_matrix_reminder_bot_git_pull_results.changed | bool else 'never' }}" when: "matrix_bot_matrix_reminder_bot_container_image_self_build | bool" + register: matrix_bot_matrix_reminder_bot_container_image_build_result - name: Ensure matrix-reminder-bot config installed ansible.builtin.copy: @@ -97,6 +103,7 @@ register: matrix_bot_matrix_reminder_bot_config_result - name: Ensure matrix-reminder-bot container network is created + when: matrix_bot_matrix_reminder_bot_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_bot_matrix_reminder_bot_container_network }}" @@ -118,6 +125,7 @@ or matrix_bot_matrix_reminder_bot_config_result.changed | default(false) or matrix_bot_matrix_reminder_bot_systemd_service_result.changed | default(false) or matrix_bot_matrix_reminder_bot_container_image_pull_result.changed | default(false) + or matrix_bot_matrix_reminder_bot_container_image_build_result.changed | default(false) }} - name: Ensure matrix-bot-matrix-reminder-bot.service restarted, if necessary diff --git a/roles/custom/matrix-bot-matrix-reminder-bot/tasks/validate_config.yml b/roles/custom/matrix-bot-matrix-reminder-bot/tasks/validate_config.yml index 69a031784..b5f56db05 100644 --- a/roles/custom/matrix-bot-matrix-reminder-bot/tasks/validate_config.yml +++ b/roles/custom/matrix-bot-matrix-reminder-bot/tasks/validate_config.yml @@ -23,6 +23,7 @@ - {'old': 'matrix_bot_matrix_reminder_bot_docker_repo', 'new': 'matrix_bot_matrix_reminder_bot_container_repo'} - {'old': 'matrix_bot_matrix_reminder_bot_docker_repo_version', 'new': 'matrix_bot_matrix_reminder_bot_container_repo_version'} - {'old': 'matrix_bot_matrix_reminder_bot_docker_src_files_path', 'new': 'matrix_bot_matrix_reminder_bot_container_src_files_path'} + - {'old': 'matrix_bot_matrix_reminder_bot_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required matrix-reminder-bot settings not defined ansible.builtin.fail: diff --git a/roles/custom/matrix-bot-matrix-reminder-bot/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2 b/roles/custom/matrix-bot-matrix-reminder-bot/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2 index 4fb64420b..263ca1131 100644 --- a/roles/custom/matrix-bot-matrix-reminder-bot/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2 +++ b/roles/custom/matrix-bot-matrix-reminder-bot/templates/systemd/matrix-bot-matrix-reminder-bot.service.j2 @@ -34,9 +34,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {{ matrix_bot_matrix_reminder_bot_container_image }} \ -c "matrix-reminder-bot /config/config.yaml" +{% if matrix_bot_matrix_reminder_bot_container_network != 'host' %} {% for network in matrix_bot_matrix_reminder_bot_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-matrix-reminder-bot {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-matrix-reminder-bot diff --git a/roles/custom/matrix-bot-maubot/defaults/main.yml b/roles/custom/matrix-bot-maubot/defaults/main.yml index 045761599..ba09915f6 100644 --- a/roles/custom/matrix-bot-maubot/defaults/main.yml +++ b/roles/custom/matrix-bot-maubot/defaults/main.yml @@ -23,6 +23,9 @@ matrix_bot_maubot_initial_password: '' matrix_bot_maubot_scheme: https matrix_bot_maubot_hostname: '' + +# The path at which maubot is exposed. +# This value must either be `/` or not end with a slash (e.g. `/_matrix/maubot`). matrix_bot_maubot_path_prefix: /_matrix/maubot matrix_bot_maubot_container_image_self_build: false @@ -35,7 +38,6 @@ matrix_bot_maubot_container_image: "{{ matrix_bot_maubot_container_image_registr matrix_bot_maubot_container_image_registry_prefix: "{{ 'localhost/' if matrix_bot_maubot_container_image_self_build else matrix_bot_maubot_container_image_registry_prefix_upstream }}" matrix_bot_maubot_container_image_registry_prefix_upstream: "{{ matrix_bot_maubot_container_image_registry_prefix_upstream_default }}" matrix_bot_maubot_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_bot_maubot_container_image_force_pull: "{{ matrix_bot_maubot_container_image.endswith(':latest') }}" # matrix_bot_maubot_container_image_customized is the name of the locally built maubot image # which adds various customizations on top of the original (upstream) maubot image. @@ -58,11 +60,9 @@ matrix_bot_maubot_config_path: "{{ matrix_bot_maubot_base_path }}/config" matrix_bot_maubot_container_src_files_path: "{{ matrix_bot_maubot_base_path }}/docker-src" matrix_bot_maubot_customized_container_src_files_path: "{{ matrix_bot_maubot_base_path }}/customized-docker-src" -matrix_bot_maubot_bot_server_public_url: "{{ matrix_bot_maubot_scheme }}://{{ matrix_bot_maubot_hostname }}" -matrix_bot_maubot_bot_server_base_path: "{{ matrix_bot_maubot_path_prefix }}/v1" -matrix_bot_maubot_bot_server_ui_base_path: "{{ matrix_bot_maubot_path_prefix }}" -matrix_bot_maubot_bot_server_plugin_base_path: "{{ matrix_bot_maubot_path_prefix }}/plugin/" -matrix_bot_maubot_bot_server_appservice_base_path: "{{ matrix_bot_maubot_bot_server_base_path }}" +matrix_bot_maubot_bot_server_public_url: "{{ matrix_bot_maubot_scheme }}://{{ matrix_bot_maubot_hostname }}{{ '' if matrix_bot_maubot_path_prefix == '/' else matrix_bot_maubot_path_prefix }}" +matrix_bot_maubot_bot_server_ui_base_path: / +matrix_bot_maubot_bot_server_plugin_base_path: /_matrix/maubot/plugin/ matrix_bot_maubot_proxy_management_interface: true @@ -79,12 +79,10 @@ matrix_bot_maubot_database_sslmode: disable matrix_bot_maubot_database_connection_string: postgres://{{ matrix_bot_maubot_database_username }}:{{ matrix_bot_maubot_database_password }}@{{ matrix_bot_maubot_database_hostname }}:{{ matrix_bot_maubot_database_port }}/{{ matrix_bot_maubot_database_name }}?sslmode={{ matrix_bot_maubot_database_sslmode }} -matrix_bot_maubot_database_uri: "{{ - { - 'sqlite': ('sqlite:///' + matrix_bot_maubot_sqlite_database_path_in_container), - 'postgres': matrix_bot_maubot_database_connection_string, - }[matrix_bot_maubot_database_engine] - }}" +matrix_bot_maubot_database_uri: "{{ { + 'sqlite': ('sqlite:///' + matrix_bot_maubot_sqlite_database_path_in_container), + 'postgres': matrix_bot_maubot_database_connection_string, +}[matrix_bot_maubot_database_engine] }}" # Defines the port number where the management interface is # To actually expose the management interface outside of the container, use `matrix_bot_maubot_container_management_interface_http_bind_port` @@ -154,7 +152,7 @@ matrix_bot_maubot_container_labels_traefik_tls_certResolver: default # noqa var matrix_bot_maubot_container_labels_management_enabled: true matrix_bot_maubot_container_labels_management_hostname: "{{ matrix_bot_maubot_hostname }}" matrix_bot_maubot_container_labels_management_prefix: "{{ matrix_bot_maubot_path_prefix }}" -matrix_bot_maubot_container_labels_management_traefik_rule: "Host(`{{ matrix_bot_maubot_container_labels_management_hostname }}`) && PathPrefix(`{{ matrix_bot_maubot_path_prefix }}`)" +matrix_bot_maubot_container_labels_management_traefik_rule: "Host(`{{ matrix_bot_maubot_container_labels_management_hostname }}`) && PathPrefix(`{{ matrix_bot_maubot_container_labels_management_prefix }}`)" matrix_bot_maubot_container_labels_management_traefik_priority: 0 matrix_bot_maubot_container_labels_management_traefik_entrypoints: "{{ matrix_bot_maubot_container_labels_traefik_entrypoints }}" matrix_bot_maubot_container_labels_management_traefik_tls: "{{ matrix_bot_maubot_container_labels_management_traefik_entrypoints != 'web' }}" diff --git a/roles/custom/matrix-bot-maubot/molecule/default/converge.yml b/roles/custom/matrix-bot-maubot/molecule/default/converge.yml new file mode 100644 index 000000000..2d82b926c --- /dev/null +++ b/roles/custom/matrix-bot-maubot/molecule/default/converge.yml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-bot-maubot Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-bot-maubot Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +# Component roles install their unit; the complete playbook's systemd service manager starts +# it. Keep that boundary explicit rather than pulling the manager into this role test. +- name: Ensure matrix-bot-maubot is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure matrix-bot-maubot systemd service is started + ansible.builtin.systemd_service: + name: matrix-bot-maubot.service + state: started diff --git a/roles/custom/matrix-bot-maubot/molecule/default/molecule.yml b/roles/custom/matrix-bot-maubot/molecule/default/molecule.yml new file mode 100644 index 000000000..56d654924 --- /dev/null +++ b/roles/custom/matrix-bot-maubot/molecule/default/molecule.yml @@ -0,0 +1,100 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-bot-maubot-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bot_maubot_container_network: matrix-bot-maubot-molecule + + # verify.yml runs as a separate play, where role defaults are out of scope. Pin + # paths it reads to the values the role derives during converge. + matrix_bot_maubot_base_path: /matrix/maubot + matrix_bot_maubot_config_path: /matrix/maubot/config + matrix_bot_maubot_data_path: /matrix/maubot/data + + # Postgres is the normal playbook path. The non-default database and user mean + # successful migrations prove that the role assembled and Maubot consumed this URI. + matrix_bot_maubot_database_engine: postgres + matrix_bot_maubot_database_hostname: matrix-postgres-molecule + matrix_bot_maubot_database_name: molecule_maubot + matrix_bot_maubot_database_username: molecule_maubot + matrix_bot_maubot_database_password: molecule_pg_password_27c541 + matrix_bot_maubot_database_sslmode: disable + + # Both the port and public path differ from the role and Maubot defaults. The scenario + # proves the internal endpoints and the public-prefix/StripPrefix mapping separately. + matrix_bot_maubot_server_port: 29427 + matrix_bot_maubot_scheme: https + matrix_bot_maubot_hostname: maubot.molecule.local + matrix_bot_maubot_path_prefix: /molecule-maubot + matrix_bot_maubot_unshared_secret: molecule_unshared_secret_b9317a + + # The homeserver is only recorded as a convenient management-interface preset. + # Maubot has no clients or instances yet, so it does not contact this deliberately + # nonexistent service during startup and no external Matrix credentials are needed. + matrix_bot_maubot_homeserver_name: molecule-homeserver + matrix_bot_maubot_homeserver_url: https://matrix-no-such-service.invalid + matrix_bot_maubot_homeserver_secret: molecule_registration_secret_98e127 + matrix_bot_maubot_initial_password: molecule_matrix_password_unused_62aa11 + + # This account belongs only to Maubot's management API. Logging in below proves the + # running process loaded it, rather than merely proving that a YAML file exists. + matrix_bot_maubot_admins: + molecule-admin: molecule_admin_password_61bd93 + matrix_bot_maubot_logging_level: DEBUG + + # No Traefik is deployed. Non-default values still let the scenario verify the role's + # public-routing contract in both the label file and Docker's accepted labels. + matrix_bot_maubot_container_labels_traefik_enabled: true + matrix_bot_maubot_container_labels_traefik_docker_network: matrix-bot-maubot-molecule + matrix_bot_maubot_container_labels_management_enabled: true + matrix_bot_maubot_container_labels_management_hostname: maubot.molecule.local + matrix_bot_maubot_container_labels_management_traefik_priority: 719 + matrix_bot_maubot_container_labels_management_traefik_entrypoints: web + matrix_bot_maubot_container_labels_management_traefik_tls: false + matrix_bot_maubot_container_labels_additional_labels: | + molecule.maubot.coverage=enabled + + # Keep the production-like no-host-port path: probes join the container network. + matrix_bot_maubot_container_management_interface_http_bind_port: '' + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bot-maubot/molecule/default/prepare.yml b/roles/custom/matrix-bot-maubot/molecule/default/prepare.yml new file mode 100644 index 000000000..8058a5364 --- /dev/null +++ b/roles/custom/matrix-bot-maubot/molecule/default/prepare.yml @@ -0,0 +1,80 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-bot-maubot Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # matrix-base creates this identity in the complete playbook. The component role's file + # tasks resolve owner/group by name, so a role-scoped scenario supplies that side effect. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role also creates this during converge, but Postgres must join it first. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bot_maubot_container_network }}" + register: matrix_bot_maubot_molecule_network + changed_when: matrix_bot_maubot_molecule_network.rc == 0 + failed_when: + - matrix_bot_maubot_molecule_network.rc != 0 + - "'already exists' not in matrix_bot_maubot_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bot_maubot_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bot_maubot_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bot_maubot_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bot_maubot_database_password }}" diff --git a/roles/custom/matrix-bot-maubot/molecule/default/requirements.yml b/roles/custom/matrix-bot-maubot/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bot-maubot/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bot-maubot/molecule/default/verify.yml b/roles/custom/matrix-bot-maubot/molecule/default/verify.yml new file mode 100644 index 000000000..a5e88bf7a --- /dev/null +++ b/roles/custom/matrix-bot-maubot/molecule/default/verify.yml @@ -0,0 +1,406 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Maubot starts without a Matrix client configured. Its real management API and Postgres +# migrations are the weight-bearing evidence, so this needs no homeserver or credentials. +- name: Verify matrix-bot-maubot + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + matrix_bot_maubot_config: "{{ matrix_bot_maubot_config_file.content | b64decode | from_yaml }}" + matrix_bot_maubot_ui_body: "{{ matrix_bot_maubot_ui_http.stdout_lines[:-1] | join('\n') }}" + matrix_bot_maubot_paths_body: "{{ matrix_bot_maubot_paths_http.stdout_lines[:-1] | join('\n') }}" + matrix_bot_maubot_paths: "{{ matrix_bot_maubot_paths_body | from_json }}" + matrix_bot_maubot_login_body: "{{ matrix_bot_maubot_login_http.stdout_lines[:-1] | join('\n') }}" + matrix_bot_maubot_login_response: "{{ matrix_bot_maubot_login_body | from_json }}" + matrix_bot_maubot_expected_database_uri: >- + postgres://{{ matrix_bot_maubot_database_username }}:{{ matrix_bot_maubot_database_password }}@{{ matrix_bot_maubot_database_hostname }}:5432/{{ matrix_bot_maubot_database_name }}?sslmode={{ matrix_bot_maubot_database_sslmode }} + matrix_bot_maubot_labels_lines: "{{ (matrix_bot_maubot_labels_file.content | b64decode).splitlines() }}" + matrix_bot_maubot_runtime: "{{ (matrix_bot_maubot_container_inspect.stdout | from_json) | first }}" + matrix_bot_maubot_config_mounts: "{{ matrix_bot_maubot_runtime.Mounts | selectattr('Destination', 'equalto', '/config') | list }}" + matrix_bot_maubot_data_mounts: "{{ matrix_bot_maubot_runtime.Mounts | selectattr('Destination', 'equalto', '/data') | list }}" + gather_facts: false + tasks: + # Read the version from the role itself, so a role pin bump changes what is expected. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_bot_maubot_role_defaults + + - name: Wait for the matrix-bot-maubot service to become active + ansible.builtin.systemd_service: + name: matrix-bot-maubot.service + register: matrix_bot_maubot_service + until: matrix_bot_maubot_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always can hide a crash loop behind ActiveState=active. + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_bot_maubot_service.status.ActiveState == 'active' + - matrix_bot_maubot_service.status.NRestarts is defined + - matrix_bot_maubot_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-bot-maubot.service is + {{ matrix_bot_maubot_service.status.ActiveState | default('unknown') }} after + {{ matrix_bot_maubot_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-bot-maubot.service is active and has not restarted" + + - name: Read the configuration file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_maubot_config_path }}/config.yaml" + register: matrix_bot_maubot_config_file + + - name: Assert the parsed server configuration carries the scenario's values + ansible.builtin.assert: + that: + - matrix_bot_maubot_config.server.hostname == '0.0.0.0' + - matrix_bot_maubot_config.server.port == matrix_bot_maubot_server_port + - matrix_bot_maubot_config.server.public_url == 'https://maubot.molecule.local/molecule-maubot' + - matrix_bot_maubot_config.server.ui_base_path == '/' + - matrix_bot_maubot_config.server.plugin_base_path == '/_matrix/maubot/plugin/' + - "'base_path' not in matrix_bot_maubot_config.server" + - "'appservice_base_path' not in matrix_bot_maubot_config.server" + - matrix_bot_maubot_config.server.unshared_secret == matrix_bot_maubot_unshared_secret + fail_msg: "The parsed server block does not carry the scenario's non-default values" + success_msg: "The parsed server block carries the scenario's non-default values" + + - name: Assert the parsed database configuration carries the scenario's Postgres URI + ansible.builtin.assert: + that: + - matrix_bot_maubot_config.database == matrix_bot_maubot_expected_database_uri + - matrix_bot_maubot_config.database.startswith('postgres://') + - matrix_bot_maubot_database_username in matrix_bot_maubot_config.database + - matrix_bot_maubot_database_password in matrix_bot_maubot_config.database + - matrix_bot_maubot_database_hostname in matrix_bot_maubot_config.database + - matrix_bot_maubot_database_name in matrix_bot_maubot_config.database + fail_msg: "The parsed configuration does not point at the scenario's Postgres database" + success_msg: "The parsed configuration points at the scenario's Postgres database" + + - name: Assert the parsed homeserver preset carries the scenario's values + ansible.builtin.assert: + that: + - matrix_bot_maubot_homeserver_name in matrix_bot_maubot_config.homeservers + - matrix_bot_maubot_config.homeservers[matrix_bot_maubot_homeserver_name].url == matrix_bot_maubot_homeserver_url + - matrix_bot_maubot_config.homeservers[matrix_bot_maubot_homeserver_name].secret == matrix_bot_maubot_homeserver_secret + fail_msg: "The parsed homeserver preset does not carry the scenario's values" + success_msg: "The parsed homeserver preset carries the scenario's values" + + - name: Assert the parsed management configuration carries scenario values + ansible.builtin.assert: + that: + - matrix_bot_maubot_config.admins['molecule-admin'] == 'molecule_admin_password_61bd93' + - matrix_bot_maubot_config.admins.root == '' + - matrix_bot_maubot_config.api_features.values() | select('equalto', true) | list | length == matrix_bot_maubot_config.api_features | length + fail_msg: "The parsed management configuration lost the admin or API features" + success_msg: "The parsed management configuration carries the admin and API features" + + - name: Assert the parsed logging configuration carries the scenario's level + ansible.builtin.assert: + that: + - matrix_bot_maubot_config.logging.loggers.maubot.level == matrix_bot_maubot_logging_level + - matrix_bot_maubot_config.logging.loggers.mau.level == matrix_bot_maubot_logging_level + - matrix_bot_maubot_config.logging.loggers.aiohttp.level == matrix_bot_maubot_logging_level + - matrix_bot_maubot_config.logging.root.level == matrix_bot_maubot_logging_level + fail_msg: "The parsed logging configuration does not carry the scenario's level" + success_msg: "The parsed logging configuration carries the scenario's level" + + # Traefik strips the configured public prefix before proxying, so the role deliberately + # configures the process UI at /. Probe that exact internal contract over the network. + - name: Wait for Maubot's management UI on the configured internal port and path + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_maubot_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - "http://matrix-bot-maubot:{{ matrix_bot_maubot_server_port }}/" + register: matrix_bot_maubot_ui_http + changed_when: false + until: "'HTTP_STATUS=200' in matrix_bot_maubot_ui_http.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert Maubot serves its real management UI at the configured internal address + ansible.builtin.assert: + that: + - matrix_bot_maubot_ui_http.rc == 0 + - matrix_bot_maubot_ui_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_bot_maubot_ui_body | trim | length > 100 + - "'- + Maubot did not derive the prefixed browser API path from server.public_url + ({{ matrix_bot_maubot_paths_http.stdout | default('no output') }}) + success_msg: "Maubot advertises its browser API under the configured public prefix" + + # This authenticates against the live management API with the non-default admin from + # the rendered YAML. It proves both the API base path and account reached the process. + - name: Log in to Maubot's management API + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_maubot_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --header + - 'Content-Type: application/json' + - --data + - '{"username":"molecule-admin","password":"molecule_admin_password_61bd93"}' + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - "http://matrix-bot-maubot:{{ matrix_bot_maubot_server_port }}/_matrix/maubot/v1/auth/login" + register: matrix_bot_maubot_login_http + changed_when: false + failed_when: false + + - name: Assert the management API authenticated the configured admin + ansible.builtin.assert: + that: + - matrix_bot_maubot_login_http.rc == 0 + - matrix_bot_maubot_login_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_bot_maubot_login_response is mapping + - matrix_bot_maubot_login_response.token is string + - matrix_bot_maubot_login_response.token | length > 20 + fail_msg: >- + Maubot's live management API rejected the admin the role configured + ({{ matrix_bot_maubot_login_http.stdout | default('no output') }}) + success_msg: "Maubot's live management API authenticated the configured admin" + + # The role's default port must not answer. Otherwise reaching the custom port would not + # prove that the configured value made it into the running process. + - name: Probe the role's default Maubot port + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_maubot_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --max-time + - '3' + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-bot-maubot:29316/ + register: matrix_bot_maubot_default_port_http + changed_when: false + failed_when: false + + - name: Assert Maubot is not listening on the role's default port + ansible.builtin.assert: + that: + - matrix_bot_maubot_default_port_http.rc != 0 + - "'HTTP_STATUS=200' not in matrix_bot_maubot_default_port_http.stdout" + fail_msg: "Maubot still answers on 29316, so the configured port is not proven" + success_msg: "Maubot does not listen on the role's default port" + + # Tables can only appear after hostname resolution, authentication and migrations. + - name: List the tables Maubot created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bot_maubot_database_username }} + - --dbname={{ matrix_bot_maubot_database_name }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: matrix_bot_maubot_tables + changed_when: false + + - name: Assert Maubot migrated its schema into the configured Postgres database + ansible.builtin.assert: + that: + - matrix_bot_maubot_tables.rc == 0 + - "'version' in matrix_bot_maubot_table_names" + - "'client' in matrix_bot_maubot_table_names" + - "'instance' in matrix_bot_maubot_table_names" + - "'database_owner' in matrix_bot_maubot_table_names" + - matrix_bot_maubot_table_names | length > 5 + fail_msg: >- + Maubot did not create its schema in {{ matrix_bot_maubot_database_name }} + (found {{ matrix_bot_maubot_table_names | length }} table(s)) + success_msg: "Maubot migrated its schema into the configured Postgres database" + vars: + matrix_bot_maubot_table_names: "{{ matrix_bot_maubot_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_maubot_base_path }}/labels" + register: matrix_bot_maubot_labels_file + + - name: Assert the labels carry the configured management exposure + ansible.builtin.assert: + that: + - "'traefik.enable=true' in matrix_bot_maubot_labels_lines" + - "'traefik.docker.network=matrix-bot-maubot-molecule' in matrix_bot_maubot_labels_lines" + - "'traefik.http.services.matrix-bot-maubot.loadbalancer.server.port=29427' in matrix_bot_maubot_labels_lines" + - "'traefik.http.routers.matrix-bot-maubot-management.rule=Host(`maubot.molecule.local`) && PathPrefix(`/molecule-maubot`)' in matrix_bot_maubot_labels_lines" + - "'traefik.http.routers.matrix-bot-maubot-management.priority=719' in matrix_bot_maubot_labels_lines" + - "'traefik.http.middlewares.matrix-bot-maubot-management-strip-prefix.stripprefix.prefixes=/molecule-maubot' in matrix_bot_maubot_labels_lines" + - "'traefik.http.routers.matrix-bot-maubot-management.middlewares=matrix-bot-maubot-management-strip-prefix' in matrix_bot_maubot_labels_lines" + - "'traefik.http.routers.matrix-bot-maubot-management.entrypoints=web' in matrix_bot_maubot_labels_lines" + - "'traefik.http.routers.matrix-bot-maubot-management.tls=false' in matrix_bot_maubot_labels_lines" + - "'molecule.maubot.coverage=enabled' in matrix_bot_maubot_labels_lines" + fail_msg: "The role's labels do not carry the scenario's public management wiring" + success_msg: "The role's labels carry the scenario's public management wiring" + + - name: Inspect the running Maubot container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-bot-maubot + register: matrix_bot_maubot_container_inspect + changed_when: false + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - matrix_bot_maubot_runtime.Config.Image == 'dock.mau.dev/maubot/maubot:' + matrix_bot_maubot_role_defaults.matrix_bot_maubot_version + fail_msg: >- + The running image {{ matrix_bot_maubot_runtime.Config.Image }} is not the exact + dock.mau.dev/maubot/maubot:{{ matrix_bot_maubot_role_defaults.matrix_bot_maubot_version }} pin + success_msg: "The running container uses the exact image pinned by the role" + + - name: Assert the running container uses the playbook's matrix identity + ansible.builtin.assert: + that: + - matrix_bot_maubot_runtime.Config.User.split(':')[0] == matrix_user_uid | string + - matrix_bot_maubot_runtime.Config.User.split(':')[1] == matrix_user_gid | string + fail_msg: >- + Maubot runs as {{ matrix_bot_maubot_runtime.Config.User }} instead of + {{ matrix_user_uid }}:{{ matrix_user_gid }} + success_msg: "The running container uses the playbook's matrix UID and GID" + + - name: Assert the container root filesystem is read-only + ansible.builtin.assert: + that: + - matrix_bot_maubot_runtime.HostConfig.ReadonlyRootfs is sameas true + fail_msg: "The Maubot container root filesystem is writable" + success_msg: "The Maubot container root filesystem is read-only" + + - name: Assert all Linux capabilities are dropped + ansible.builtin.assert: + that: + - matrix_bot_maubot_runtime.HostConfig.CapDrop == ['ALL'] + fail_msg: "The Maubot container does not drop all Linux capabilities" + success_msg: "The Maubot container drops all Linux capabilities" + + - name: Assert the container has the role's writable temporary filesystem + ansible.builtin.assert: + that: + - matrix_bot_maubot_runtime.HostConfig.Tmpfs['/tmp'] == 'rw,noexec,nosuid,size=1024m' + fail_msg: "The Maubot container is missing its constrained /tmp tmpfs" + success_msg: "The Maubot container has its constrained writable /tmp tmpfs" + + - name: Assert the configuration bind mount is read-only + ansible.builtin.assert: + that: + - matrix_bot_maubot_config_mounts | length == 1 + - matrix_bot_maubot_config_mounts[0].RW is sameas false + fail_msg: "The Maubot configuration bind mount is missing or writable" + success_msg: "The Maubot configuration bind mount is present and read-only" + + - name: Assert the data bind mount is writable + ansible.builtin.assert: + that: + - matrix_bot_maubot_data_mounts | length == 1 + - matrix_bot_maubot_data_mounts[0].RW is sameas true + fail_msg: "The Maubot data bind mount is missing or read-only" + success_msg: "The Maubot data bind mount is present and writable" + + - name: Assert the container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_bot_maubot_runtime.NetworkSettings.Networks is mapping + - matrix_bot_maubot_runtime.NetworkSettings.Networks | length == 1 + - matrix_bot_maubot_container_network in matrix_bot_maubot_runtime.NetworkSettings.Networks + fail_msg: >- + Maubot has unexpected networks: + {{ matrix_bot_maubot_runtime.NetworkSettings.Networks.keys() | list }} + success_msg: "The Maubot container is attached only to its dedicated network" + + - name: Ask Docker for Maubot's published ports + ansible.builtin.command: + argv: + - docker + - container + - port + - matrix-bot-maubot + register: matrix_bot_maubot_published_ports + changed_when: false + failed_when: false + + - name: Assert the role did not publish a host port + ansible.builtin.assert: + that: + - matrix_bot_maubot_runtime.HostConfig.PortBindings | default({}, true) | length == 0 + - matrix_bot_maubot_published_ports.rc == 0 + - matrix_bot_maubot_published_ports.stdout | trim | length == 0 + fail_msg: >- + Maubot unexpectedly publishes a host port: + {{ matrix_bot_maubot_published_ports.stdout | default('unknown') }} + success_msg: "The role leaves Maubot's management port unpublished" + + - name: Assert Docker accepted the role's custom label + ansible.builtin.assert: + that: + - matrix_bot_maubot_runtime.Config.Labels is mapping + - matrix_bot_maubot_runtime.Config.Labels['molecule.maubot.coverage'] == 'enabled' + fail_msg: "Docker did not attach the custom label from the role's label file" + success_msg: "Docker accepted the custom label from the role's label file" diff --git a/roles/custom/matrix-bot-maubot/tasks/setup_install.yml b/roles/custom/matrix-bot-maubot/tasks/setup_install.yml index 0aa4915a2..3486bcc56 100644 --- a/roles/custom/matrix-bot-maubot/tasks/setup_install.yml +++ b/roles/custom/matrix-bot-maubot/tasks/setup_install.yml @@ -37,11 +37,9 @@ register: matrix_bot_maubot_config_result - name: Ensure maubot image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_bot_maubot_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_bot_maubot_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_maubot_container_image_force_pull }}" + pull: always when: "not matrix_bot_maubot_container_image_self_build|bool" register: matrix_bot_maubot_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -50,6 +48,15 @@ - when: matrix_bot_maubot_container_image_self_build | bool block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure maubot repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bot_maubot_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure maubot repository is present on self-build ansible.builtin.git: repo: "{{ matrix_bot_maubot_container_repo }}" @@ -61,15 +68,13 @@ register: matrix_bot_maubot_git_pull_results - name: Ensure maubot image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_bot_maubot_container_image }}" - source: build - force_source: "{{ matrix_bot_maubot_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_maubot_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_bot_maubot_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_bot_maubot_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bot_maubot_git_pull_results.changed | bool else 'never' }}" + register: matrix_bot_maubot_container_image_build_result - when: "matrix_bot_maubot_container_image_customizations_enabled | bool" block: @@ -83,14 +88,12 @@ register: matrix_bot_maubot_container_image_customizations_dockerfile_result - name: Ensure customized Docker image for maubot is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_bot_maubot_container_image_customized }}" - source: build - force_source: "{{ matrix_bot_maubot_container_image_customizations_dockerfile_result.changed or matrix_bot_maubot_container_image_customized_force_source }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_bot_maubot_customized_container_src_files_path }}" - nocache: "{{ matrix_bot_maubot_container_image_customized_build_nocache }}" + dockerfile: Dockerfile + path: "{{ matrix_bot_maubot_customized_container_src_files_path }}" + nocache: "{{ matrix_bot_maubot_container_image_customized_build_nocache }}" + rebuild: "{{ 'always' if (matrix_bot_maubot_container_image_customizations_dockerfile_result.changed or matrix_bot_maubot_container_image_customized_force_source) | bool else 'never' }}" - name: Ensure maubot support files installed ansible.builtin.template: @@ -104,6 +107,7 @@ register: matrix_bot_maubot_support_files_result - name: Ensure maubot container network is created + when: matrix_bot_maubot_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_bot_maubot_container_network }}" @@ -125,4 +129,5 @@ or matrix_bot_maubot_support_files_result.changed | default(false) or matrix_bot_maubot_systemd_service_result.changed | default(false) or matrix_bot_maubot_container_image_pull_result.changed | default(false) + or matrix_bot_maubot_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-bot-maubot/tasks/validate_config.yml b/roles/custom/matrix-bot-maubot/tasks/validate_config.yml index 1201184cc..332c0c6f3 100644 --- a/roles/custom/matrix-bot-maubot/tasks/validate_config.yml +++ b/roles/custom/matrix-bot-maubot/tasks/validate_config.yml @@ -31,6 +31,9 @@ - {'old': 'matrix_bot_maubot_docker_repo_version', 'new': 'matrix_bot_maubot_container_repo_version'} - {'old': 'matrix_bot_maubot_docker_src_files_path', 'new': 'matrix_bot_maubot_container_src_files_path'} - {'old': 'matrix_bot_maubot_customized_docker_src_files_path', 'new': 'matrix_bot_maubot_customized_container_src_files_path'} + - {'old': 'matrix_bot_maubot_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bot_maubot_bot_server_base_path', 'new': ' (maubot no longer supports a custom management API path)'} + - {'old': 'matrix_bot_maubot_bot_server_appservice_base_path', 'new': ' (maubot no longer supports a custom appservice API path)'} - name: Fail if required maubot settings not defined ansible.builtin.fail: diff --git a/roles/custom/matrix-bot-maubot/templates/config.yaml.j2 b/roles/custom/matrix-bot-maubot/templates/config.yaml.j2 index e5c5be630..11b34f03f 100644 --- a/roles/custom/matrix-bot-maubot/templates/config.yaml.j2 +++ b/roles/custom/matrix-bot-maubot/templates/config.yaml.j2 @@ -47,8 +47,6 @@ server: port: {{ matrix_bot_maubot_server_port | to_json }} # Public base URL where the server is visible. public_url: {{ matrix_bot_maubot_bot_server_public_url | to_json }} - # The base management API path. - base_path: {{ matrix_bot_maubot_bot_server_base_path | to_json }} # The base path for the UI. ui_base_path: {{ matrix_bot_maubot_bot_server_ui_base_path | to_json }} # The base path for plugin endpoints. The instance ID will be appended directly. @@ -56,8 +54,6 @@ server: # Override path from where to load UI resources. # Set to false to using pkg_resources to find the path. override_resource_path: /opt/maubot/frontend - # The base appservice API path. Use / for legacy appservice API and /_matrix/app/v1 for v1. - appservice_base_path: {{ matrix_bot_maubot_bot_server_appservice_base_path | to_json }} # The shared secret to sign API access tokens. # Set to "generate" to generate and save a new token at startup. unshared_secret: {{ matrix_bot_maubot_unshared_secret | to_json }} diff --git a/roles/custom/matrix-bot-maubot/templates/labels.j2 b/roles/custom/matrix-bot-maubot/templates/labels.j2 index e937775d4..12f0a40a0 100644 --- a/roles/custom/matrix-bot-maubot/templates/labels.j2 +++ b/roles/custom/matrix-bot-maubot/templates/labels.j2 @@ -27,6 +27,10 @@ traefik.http.routers.matrix-bot-maubot-management.priority={{ matrix_bot_maubot_ {% endif %} traefik.http.routers.matrix-bot-maubot-management.service=matrix-bot-maubot +{% if matrix_bot_maubot_container_labels_management_prefix != '/' %} +traefik.http.middlewares.matrix-bot-maubot-management-strip-prefix.stripprefix.prefixes={{ matrix_bot_maubot_container_labels_management_prefix }} +traefik.http.routers.matrix-bot-maubot-management.middlewares=matrix-bot-maubot-management-strip-prefix +{% endif %} traefik.http.routers.matrix-bot-maubot-management.entrypoints={{ matrix_bot_maubot_container_labels_management_traefik_entrypoints }} traefik.http.routers.matrix-bot-maubot-management.tls={{ matrix_bot_maubot_container_labels_management_traefik_tls | to_json }} diff --git a/roles/custom/matrix-bot-maubot/templates/systemd/matrix-bot-maubot.service.j2 b/roles/custom/matrix-bot-maubot/templates/systemd/matrix-bot-maubot.service.j2 index eddacdf8c..6e0206f8f 100644 --- a/roles/custom/matrix-bot-maubot/templates/systemd/matrix-bot-maubot.service.j2 +++ b/roles/custom/matrix-bot-maubot/templates/systemd/matrix-bot-maubot.service.j2 @@ -41,9 +41,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {{ matrix_bot_maubot_container_image_final }} \ python3 -m maubot -c /config/config.yaml --no-update +{% if matrix_bot_maubot_container_network != 'host' %} {% for network in matrix_bot_maubot_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-maubot {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-maubot diff --git a/roles/custom/matrix-bot-meowlnir/defaults/main.yml b/roles/custom/matrix-bot-meowlnir/defaults/main.yml new file mode 100644 index 000000000..fc883a255 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/defaults/main.yml @@ -0,0 +1,563 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# An opinionated Matrix moderation bot +# Project source code URL: https://github.com/maunium/meowlnir + +matrix_bot_meowlnir_enabled: true + +# renovate: datasource=docker depName=dock.mau.dev/maunium/meowlnir +matrix_bot_meowlnir_version: v0.2608.0 + +matrix_bot_meowlnir_container_image_self_build: false +matrix_bot_meowlnir_container_image_self_build_repo: "https://github.com/maunium/meowlnir.git" + +matrix_bot_meowlnir_container_image: "{{ matrix_bot_meowlnir_container_image_registry_prefix }}{{ matrix_bot_meowlnir_container_image_registry_namespace_identifier }}:{{ matrix_bot_meowlnir_version }}" +matrix_bot_meowlnir_container_image_registry_namespace_identifier: "maunium/meowlnir" +matrix_bot_meowlnir_container_image_registry_prefix: "{{ 'localhost/' if matrix_bot_meowlnir_container_image_self_build else matrix_bot_meowlnir_container_image_registry_prefix_upstream }}" +matrix_bot_meowlnir_container_image_registry_prefix_upstream: "{{ matrix_bot_meowlnir_container_image_registry_prefix_upstream_default }}" +matrix_bot_meowlnir_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bot_meowlnir_base_path: "{{ matrix_base_data_path }}/meowlnir" +matrix_bot_meowlnir_config_path: "{{ matrix_bot_meowlnir_base_path }}/config" +matrix_bot_meowlnir_data_path: "{{ matrix_bot_meowlnir_base_path }}/data" +matrix_bot_meowlnir_bin_path: "{{ matrix_bot_meowlnir_base_path }}/bin" +matrix_bot_meowlnir_container_src_files_path: "{{ matrix_bot_meowlnir_base_path }}/docker-src" + +matrix_bot_meowlnir_container_network: "" + +matrix_bot_meowlnir_container_additional_networks: "{{ matrix_bot_meowlnir_container_additional_networks_auto + matrix_bot_meowlnir_container_additional_networks_custom }}" +matrix_bot_meowlnir_container_additional_networks_auto: [] +matrix_bot_meowlnir_container_additional_networks_custom: [] + +# Controls whether the matrix-bot-meowlnir container exposes its HTTP port. +# +# Takes an ":" or "" value (e.g. +# "127.0.0.1:29339"), or empty string to not expose. +matrix_bot_meowlnir_container_http_host_bind_port: '' + +# A list of extra arguments to pass to the container +matrix_bot_meowlnir_container_extra_arguments: [] + +# List of systemd services that matrix-bot-meowlnir.service depends on +matrix_bot_meowlnir_systemd_required_services_list: "{{ matrix_bot_meowlnir_systemd_required_services_list_default + matrix_bot_meowlnir_systemd_required_services_list_auto + matrix_bot_meowlnir_systemd_required_services_list_custom }}" +matrix_bot_meowlnir_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bot_meowlnir_systemd_required_services_list_auto: [] +matrix_bot_meowlnir_systemd_required_services_list_custom: [] + +# List of systemd services that matrix-bot-meowlnir.service wants +matrix_bot_meowlnir_systemd_wanted_services_list: [] + + +######################################################################## +# # +# Appservice registration # +# # +######################################################################## + +# Meowlnir runs as an appservice. +# Unlike Draupnir in bot mode, it does not log in with an access token — the homeserver is told about it via a registration file. +# +# Bots themselves are created at runtime through Meowlnir's management API, within the user namespace declared below. +# See the role's documentation page for details. + +matrix_bot_meowlnir_appservice_id: meowlnir + +# The localpart of the appservice's own user. +# This user does not act as a moderation bot; it is the appservice's sender. +# Individual bots get their own users. +matrix_bot_meowlnir_appservice_sender_localpart: meowlnir + +# The prefix for bot users created via the management API. +# Must line up with `matrix_bot_meowlnir_config_meowlnir4all_localpart_template`. +matrix_bot_meowlnir_user_prefix: "meowlnir_" + + +######################################################################## +# # +# Managed bots # +# # +######################################################################## + +# Meowlnir hosts multiple bots, each with one or more management rooms, and creates them at runtime through its management API, not from its configuration file. +# +# The bots listed here are created (and kept up to date) by the playbook when running with the `ensure-matrix-users-created` tag, so that you do not need to call that API yourself. +# +# The fields below are required on every entry, so that each bot's setup can be understood without having to know what the playbook defaults to. +# +# - `username`: the localpart of the bot user. Must begin with `matrix_bot_meowlnir_user_prefix`, or the homeserver will not let Meowlnir operate it. Pick it carefully — it becomes the bot's Matrix user ID and is awkward to change later. +# - `displayname`: the name shown in rooms. Safe to change at any time. +# - `avatar_url`: an `mxc://` URI, or an empty string for no avatar. +# - `management_room_auto_create`: whether the playbook creates a management room for this bot. Mutually exclusive with `management_rooms` — see below. +# - `management_rooms`: the rooms you send commands to. A list, because Meowlnir supports several per bot. Each entry needs an `id` (a room ID, not an alias) and an `encrypted` flag saying whether that room is encrypted. +# +# `management_room_auto_create` and `management_rooms` are mutually exclusive: +# +# - `management_room_auto_create: false` requires at least one entry in `management_rooms`. You create the room yourself, and invite the bot after the first run. +# - `management_room_auto_create: true` requires `management_rooms` to be empty. The playbook creates the room, invites the bot's initial managers and gives them the power level needed to command the bot. The room's encryption follows `matrix_bot_meowlnir_config_encryption_enable`. +# +# One optional field is also recognized: +# +# - `initial_managers`: the users invited to a management room the playbook creates for this bot. Omit it to use `matrix_bot_meowlnir_initial_managers`. An explicitly empty list means nobody, which is an error for a bot relying on `management_room_auto_create`. +# +# Example: +# matrix_bot_meowlnir_bots_custom: +# - username: meowlnir_bot +# displayname: Meowlnir +# avatar_url: "" +# management_room_auto_create: false +# management_rooms: +# - id: "!qporfwt:example.com" +# encrypted: false +matrix_bot_meowlnir_bots: "{{ matrix_bot_meowlnir_bots_auto + matrix_bot_meowlnir_bots_custom }}" +matrix_bot_meowlnir_bots_auto: [] +matrix_bot_meowlnir_bots_custom: [] + +# The users invited to management rooms that the playbook creates, and given the power level required to command the bot there. +# Full Matrix user IDs (`@alice:example.com`). +# +# Only consulted by bots with `management_room_auto_create: true`, and only as the default for those which do not carry their own `initial_managers` list. +# The playbook points this at `matrix_admin` by default. +matrix_bot_meowlnir_initial_managers: [] + +# Controls whether the bot list above is authoritative for this Meowlnir instance. +# +# When enabled, bots and management rooms which are registered with Meowlnir but no longer declared are removed, so that the list describes the whole installation, not merely additions to it. +# +# Note that removing a bot only makes Meowlnir forget it. +# The bot's Matrix user is not deactivated and stays in the rooms it had joined, so clean that up separately if you want it gone for good. +matrix_bot_meowlnir_bots_pruning_enabled: true + +# Controls whether pruning also happens when no bots are declared at all. +# +# Disabled by default, because an empty list is far more often a mistake (a commented-out block, an unset variable) than a genuine instruction to remove every bot. +# With this off, the playbook refuses that particular run. +# +# Only relevant when `matrix_bot_meowlnir_bots_pruning_enabled` is enabled. +matrix_bot_meowlnir_bots_pruning_on_empty_roster_enabled: false + +# How long to wait after starting the Meowlnir service and before creating bots. +# Only waited on when the service was not already running. +matrix_bot_meowlnir_bots_start_wait_time_seconds: 15 + +# How long a single request made through the helper scripts in `bin/` may take, in seconds. +# Applies to requests against both Meowlnir's management API and the homeserver's Client-Server API. +# Bounded so that an API which accepts connections but never answers turns into a clear error instead of hanging the playbook (or a human caller) forever. +matrix_bot_meowlnir_api_request_timeout_seconds: 60 + +# The systemd services to restart if the homeserver turns out to be running without Meowlnir's appservice registration when bots are about to be provisioned. +# +# The homeserver only reads appservice registrations on startup, so on the run which first enables Meowlnir it typically still runs without this one and rejects Meowlnir's appservice token (`M_UNKNOWN_TOKEN`). +# When that is detected, the services listed here are restarted so that provisioning can proceed within the same run. +# +# A playbook may inject the homeserver's own systemd service here for homeserver implementations whose appservice registrations it manages. +# When the list is empty, no restart is attempted and provisioning fails with instructions instead. +matrix_bot_meowlnir_homeserver_restart_systemd_services_list: [] + +# How many times (and how many seconds apart) to re-ask the homeserver whether it accepts Meowlnir's appservice token, while waiting for it to come up. +matrix_bot_meowlnir_appservice_token_check_retries_count: 30 +matrix_bot_meowlnir_appservice_token_check_retries_delay_seconds: 5 + +# The name and topic given to management rooms that the playbook creates. +# Only used by bots with `management_room_auto_create` enabled. +matrix_bot_meowlnir_management_room_name: Meowlnir management room +matrix_bot_meowlnir_management_room_topic: >- + Moderation commands for this Meowlnir bot are sent here. + +# Regular expressions matching the users this appservice owns. +# +# Defined here, because they are used both in the appservice registration file below and when telling other components (Ketesa, for one) which users are appservice-managed. +# Writing them twice invites the two from drifting apart. +# +# The character class covers what the Matrix specification allows in a user ID localpart. +matrix_bot_meowlnir_user_regex: "^@{{ matrix_bot_meowlnir_user_prefix | regex_escape }}[a-zA-Z0-9._=/+-]+:{{ matrix_bot_meowlnir_config_homeserver_domain | regex_escape }}$" +matrix_bot_meowlnir_appservice_sender_regex: "^@{{ matrix_bot_meowlnir_appservice_sender_localpart | regex_escape }}:{{ matrix_bot_meowlnir_config_homeserver_domain | regex_escape }}$" + +# Tokens shared between Meowlnir and the homeserver. +# Set these to strong, unique values. +# The playbook derives them from `matrix_homeserver_generic_secret_key` by default. +matrix_bot_meowlnir_appservice_token: '' +matrix_bot_meowlnir_homeserver_token: '' + +matrix_bot_meowlnir_registration_yaml: | + id: {{ matrix_bot_meowlnir_appservice_id | to_json }} + as_token: {{ matrix_bot_meowlnir_appservice_token | to_json }} + hs_token: {{ matrix_bot_meowlnir_homeserver_token | to_json }} + url: {{ matrix_bot_meowlnir_appservice_url | to_json }} + sender_localpart: {{ matrix_bot_meowlnir_appservice_sender_localpart | to_json }} + rate_limited: false + namespaces: + users: + - exclusive: true + regex: {{ matrix_bot_meowlnir_user_regex | to_json }} + - exclusive: true + regex: {{ matrix_bot_meowlnir_appservice_sender_regex | to_json }} + {% if matrix_bot_meowlnir_config_encryption_enable %} + de.sorunome.msc2409.push_ephemeral: true + push_ephemeral: true + receive_ephemeral: true + org.matrix.msc3202: true + io.element.msc4190: true + {% endif %} + +matrix_bot_meowlnir_registration: "{{ matrix_bot_meowlnir_registration_yaml | from_yaml }}" + + +######################################################################## +# # +# Configuration: homeserver # +# # +######################################################################## + +# The address that Meowlnir can use to connect to the homeserver (client-server API). +matrix_bot_meowlnir_config_homeserver_address: '' + +# The server name (base domain) of the homeserver. +matrix_bot_meowlnir_config_homeserver_domain: '' + + +######################################################################## +# # +# Configuration: meowlnir # +# # +######################################################################## + +# The hostname and port that Meowlnir listens on, inside the container. +matrix_bot_meowlnir_config_meowlnir_hostname: 0.0.0.0 +matrix_bot_meowlnir_config_meowlnir_port: 29339 + +# The address that the homeserver can use to connect to Meowlnir. +matrix_bot_meowlnir_appservice_url: "http://matrix-bot-meowlnir:{{ matrix_bot_meowlnir_config_meowlnir_port }}" + +# Secret for the management API (`/_meowlnir/v1/...`), which is how bots and management rooms get created. +# Set to `disable` to turn the API off entirely. +# The playbook derives a value from `matrix_homeserver_generic_secret_key` by default. +matrix_bot_meowlnir_config_meowlnir_management_secret: '' + +# Secret for the `/_meowlnir/data` API. +# The playbook derives a value from `matrix_homeserver_generic_secret_key` by default. +matrix_bot_meowlnir_config_meowlnir_data_secret: '' + +# Whether the `/_meowlnir/mxauth` APIs are enabled, which allow querying certain data using any Matrix account. +# Needed by the (not yet released) management web interface. +matrix_bot_meowlnir_config_meowlnir_federation_auth: false + +# When enabled, Meowlnir does everything except take actual moderation actions. +# Useful for trialling Meowlnir alongside an existing moderation bot. +matrix_bot_meowlnir_config_meowlnir_dry_run: false + +# Whether all bots should be considered untrusted, which enables additional checks (e.g. preventing subscription to a policy list without being in the room). +matrix_bot_meowlnir_config_meowlnir_untrusted: false + +# The ID of the management room that handles requests to the Matrix report API. +# Requires `matrix_bot_meowlnir_config_reporting_enabled` to be enabled to be of use. +matrix_bot_meowlnir_config_meowlnir_report_room: '' + +# The ID of the management room in charge of deleting rooms from the server. +# Room bans are not processed in other management rooms. +matrix_bot_meowlnir_config_meowlnir_room_ban_room: '' + +# Whether Meowlnir should load all room IDs from the Synapse database on startup. +# Requires `matrix_bot_meowlnir_synapse_database_uri` to be set. +matrix_bot_meowlnir_config_meowlnir_load_all_room_hashes: "{{ matrix_bot_meowlnir_synapse_database_uri != '' }}" + +# Entities (user IDs or server names) whose policies are ignored entirely. +# A blunt safety net against overly-wide policies from subscribed lists. +# +# Meowlnir always ignores policies matching its own homeserver domain, so there is no need to list it here. +matrix_bot_meowlnir_config_meowlnir_hacky_rule_filter: "{{ matrix_bot_meowlnir_config_meowlnir_hacky_rule_filter_auto + matrix_bot_meowlnir_config_meowlnir_hacky_rule_filter_custom }}" +matrix_bot_meowlnir_config_meowlnir_hacky_rule_filter_auto: [] +matrix_bot_meowlnir_config_meowlnir_hacky_rule_filter_custom: [] + +# Glob patterns matched against policy reasons. +# When a policy matches, all messages from the banned target are redacted automatically. +# The reason `spam` is implicit. +matrix_bot_meowlnir_config_meowlnir_hacky_redact_patterns: "{{ matrix_bot_meowlnir_config_meowlnir_hacky_redact_patterns_default + matrix_bot_meowlnir_config_meowlnir_hacky_redact_patterns_auto + matrix_bot_meowlnir_config_meowlnir_hacky_redact_patterns_custom }}" +matrix_bot_meowlnir_config_meowlnir_hacky_redact_patterns_default: + - spam +matrix_bot_meowlnir_config_meowlnir_hacky_redact_patterns_auto: [] +matrix_bot_meowlnir_config_meowlnir_hacky_redact_patterns_custom: [] + +# Custom Synapse admin access tokens, per bot user ID. +# +# A few features (suspending or deactivating users, deleting rooms during a takedown) call Synapse's admin API, which requires the caller to be a server admin. +# Bots are not server admins, so those calls fail with `M_FORBIDDEN` until a token is supplied here. Nothing else is affected. +# +# When left empty, each bot falls back to the appservice token. That is fine for the client-server API, but carries no admin rights. +# +# The key is the bot the token is used for; the token itself belongs to an administrator account. +# Under Matrix Authentication Service it has to be issued by MAS, since Synapse no longer decides who is an admin. See the role's documentation page. +# +# Example: +# matrix_bot_meowlnir_config_meowlnir_admin_tokens: +# "@meowlnir_bot:example.com": "ADMIN_TOKEN_HERE" +matrix_bot_meowlnir_config_meowlnir_admin_tokens: {} + + +######################################################################## +# # +# Configuration: meowlnir4all (provisioning bots for other people) # +# # +######################################################################## + +# None of this is relevant unless you offer moderation bots to other users. + +# The management room ID that is allowed to use the `!provision` command. +matrix_bot_meowlnir_config_meowlnir4all_admin_room: '' + +# The user ID template for newly provisioned bots. +matrix_bot_meowlnir_config_meowlnir4all_localpart_template: "{{ matrix_bot_meowlnir_user_prefix }}{{ '{{ uuidgen }}' }}" + +matrix_bot_meowlnir_config_meowlnir4all_displayname: Administrator +matrix_bot_meowlnir_config_meowlnir4all_avatar_url: '' +matrix_bot_meowlnir_config_meowlnir4all_room_name: Meowlnir Management Room + +# The policy lists that newly provisioned bots subscribe to by default. +# +# Note that the order of this list is meaningful: when several lists carry a policy for the same entity, the first match wins. +# Put your own list first if you want to be able to override policies from community lists with `!add-unban`. +matrix_bot_meowlnir_config_meowlnir4all_default_watched_lists: "{{ matrix_bot_meowlnir_config_meowlnir4all_default_watched_lists_auto + matrix_bot_meowlnir_config_meowlnir4all_default_watched_lists_custom }}" +matrix_bot_meowlnir_config_meowlnir4all_default_watched_lists_auto: [] +matrix_bot_meowlnir_config_meowlnir4all_default_watched_lists_custom: [] + + +######################################################################## +# # +# Configuration: antispam (synapse-http-antispam integration) # +# # +######################################################################## + +# Certain Meowlnir features (blocking invites and joins before they happen) require the synapse-http-antispam module: https://github.com/maunium/synapse-http-antispam +# +# The module has a single consumer, so this cannot be enabled at the same time as `matrix_bot_draupnir_config_web_synapseHTTPAntispam_enabled`. +matrix_bot_meowlnir_synapse_http_antispam_enabled: false + +# Secret shared between Meowlnir and the synapse-http-antispam module. +# The playbook derives a value from `matrix_homeserver_generic_secret_key` by default. +matrix_bot_meowlnir_config_antispam_secret: '' + +# Whether Meowlnir should check local invites for spam too. +matrix_bot_meowlnir_config_antispam_filter_local_invites: false + +# When set, Meowlnir uses this token to reject pending invites from users who get banned. +# This should be an appservice token with access to all local users — the double-puppeting appservice token works well here. +matrix_bot_meowlnir_config_antispam_auto_reject_invites_token: '' + +# Whether the management room receives a notice about blocked invites. +matrix_bot_meowlnir_config_antispam_notify_management_room: false + +# Inviting any of the users listed here is blocked by default, unless separately allowed with the `!allow-invite` command. +matrix_bot_meowlnir_config_antispam_block_invites_to: "{{ matrix_bot_meowlnir_config_antispam_block_invites_to_auto + matrix_bot_meowlnir_config_antispam_block_invites_to_custom }}" +matrix_bot_meowlnir_config_antispam_block_invites_to_auto: [] +matrix_bot_meowlnir_config_antispam_block_invites_to_custom: [] + +# The ID of the management room whose policies the synapse-http-antispam module consults. +# +# Meowlnir can host several bots, each with its own management room, so the module needs to be told which one to ask. +# Required when `matrix_bot_meowlnir_synapse_http_antispam_enabled` is on. +matrix_bot_meowlnir_synapse_http_antispam_management_room_id: '' + +# The URL that the synapse-http-antispam module targets in Meowlnir. +# +# Meowlnir serves the antispam API at `/_meowlnir/antispam//`; the module appends the callback name to this base URL. +matrix_bot_meowlnir_synapse_http_antispam_config_base_url: "{{ matrix_bot_meowlnir_appservice_url }}/_meowlnir/antispam/{{ matrix_bot_meowlnir_synapse_http_antispam_management_room_id }}" + +matrix_bot_meowlnir_synapse_http_antispam_config_enabled_callbacks: + - user_may_invite + - user_may_join_room + +matrix_bot_meowlnir_synapse_http_antispam_config_fail_open: + user_may_invite: true + user_may_join_room: true + +matrix_bot_meowlnir_synapse_http_antispam_config_async: {} + + +######################################################################## +# # +# Configuration: policy server (MSC4284) # +# # +######################################################################## + +# Whether Meowlnir acts as a policy server, letting rooms ask it to vet events before they are accepted. +# Rooms opt in by pointing at this server. +# +# Enabling this exposes `/_matrix/policy/` on the Matrix federation endpoint, so that other servers in the room can reach it. +matrix_bot_meowlnir_policy_server_enabled: false + +# Whether to always issue redactions for events blocked by the policy server. +matrix_bot_meowlnir_config_policy_server_always_redact: true + +# The Synapse-style private signing key used by the policy server. +# +# Must NOT be left as the literal `generate`: +# Meowlnir re-runs its config upgrader on every start, so `generate` would mint a fresh key on each restart. +# The playbook derives a stable key from `matrix_homeserver_generic_secret_key` by default. +matrix_bot_meowlnir_config_policy_server_signing_key: '' + + +######################################################################## +# # +# Configuration: reporting # +# # +######################################################################## + +# Meowlnir can intercept the report API endpoints of the client-server API, so that abuse reports land in a management room. +# This requires integration with the reverse proxy in front of the homeserver, which the playbook sets up for you when using Traefik. +# +# Also set `matrix_bot_meowlnir_config_meowlnir_report_room` to the management room that should receive the reports. +matrix_bot_meowlnir_config_reporting_enabled: false + + +######################################################################## +# # +# Configuration: encryption # +# # +######################################################################## + +# Whether Meowlnir bots support end-to-end encryption. +# +# This requires MSC3202, MSC4190 and MSC4203 support on the homeserver, plus `experimental_features.msc2409_to_device_messages_enabled`. +# On Synapse, the playbook turns these on for you when this is enabled. +matrix_bot_meowlnir_config_encryption_enable: false + +# Pickle key used for encrypting encryption keys in the crypto store. +# +# A fixed constant, like the mautrix bridge roles use, and for the same reason: the crypto store can't be read with a different key than it was written with, so a value that may change would cost the bots their encryption sessions. +# +# When migrating a Meowlnir installation that this playbook did not set up, set this to the `pickle_key` from its old configuration file. +matrix_bot_meowlnir_config_encryption_pickle_key: go.mau.fi/meowlnir + + +######################################################################## +# # +# Configuration: databases # +# # +######################################################################## + +matrix_bot_meowlnir_database_engine: postgres + +matrix_bot_meowlnir_database_username: matrix_bot_meowlnir +matrix_bot_meowlnir_database_password: '' +matrix_bot_meowlnir_database_hostname: '' +matrix_bot_meowlnir_database_port: 5432 +matrix_bot_meowlnir_database_name: matrix_bot_meowlnir +matrix_bot_meowlnir_database_sslmode: disable + +matrix_bot_meowlnir_database_connection_string: "postgresql://{{ matrix_bot_meowlnir_database_username }}:{{ matrix_bot_meowlnir_database_password }}@{{ matrix_bot_meowlnir_database_hostname }}:{{ matrix_bot_meowlnir_database_port }}/{{ matrix_bot_meowlnir_database_name }}?sslmode={{ matrix_bot_meowlnir_database_sslmode }}" + +matrix_bot_meowlnir_config_database_max_open_conns: 20 +matrix_bot_meowlnir_config_database_max_idle_conns: 2 +matrix_bot_meowlnir_config_database_max_conn_idle_time: '' +matrix_bot_meowlnir_config_database_max_conn_lifetime: '' + +# Access to the Synapse database. +# Optional: it powers room-hash lookups used by the room takedown features. +# Leave disabled to run without it. +# +# Upstream expects a user with read-only (SELECT) permissions. +# The playbook does not create one, so enabling the integration below hands Meowlnir the same credentials Synapse itself uses — which grant write access too. +# Enable it only if you are comfortable with that; otherwise set `matrix_bot_meowlnir_synapse_database_uri` yourself, pointing at a read-only user you have created. +matrix_bot_meowlnir_synapse_database_integration_enabled: false + +# Only Postgres is supported. +# Example: +# matrix_bot_meowlnir_synapse_database_uri: postgresql://user:password@matrix-postgres:5432/synapse?sslmode=disable +matrix_bot_meowlnir_synapse_database_uri: '' + +matrix_bot_meowlnir_config_synapse_db_max_open_conns: 2 +matrix_bot_meowlnir_config_synapse_db_max_idle_conns: 1 +matrix_bot_meowlnir_config_synapse_db_max_conn_idle_time: '' +matrix_bot_meowlnir_config_synapse_db_max_conn_lifetime: '' + + +######################################################################## +# # +# Configuration: logging # +# # +######################################################################## + +matrix_bot_meowlnir_config_logging_min_level: info + +matrix_bot_meowlnir_config_logging_writers: + - type: stdout + format: pretty-colored + + +######################################################################## +# # +# Traefik labels # +# # +######################################################################## + +# Controls whether labels will be added that route certain paths to Meowlnir. +# Regardless of whether this is enabled, it may or may not take effect due to the value of other variables. +# See `matrix_synapse_container_labels_traefik_enabled` or `matrix_synapse_container_labels_matrix_related_labels_enabled`. +matrix_bot_meowlnir_container_labels_traefik_enabled: "{{ matrix_bot_meowlnir_config_reporting_enabled or matrix_bot_meowlnir_policy_server_enabled }}" +matrix_bot_meowlnir_container_labels_traefik_docker_network: "{{ matrix_bot_meowlnir_container_network }}" + +# Reports (/_matrix/client/../rooms/../report and /_matrix/client/../users/../report) +# +# Only `v3` is matched on purpose: +# Meowlnir does not serve the legacy `r0` paths, so routing those here would break reporting for old clients. +matrix_bot_meowlnir_container_labels_reporting_traefik_hostname: "{{ matrix_synapse_container_labels_traefik_hostname }}" +matrix_bot_meowlnir_container_labels_reporting_traefik_path_regexp: "^/_matrix/client/v3/(rooms|users)/[^/]+/report(/.*)?$" +matrix_bot_meowlnir_container_labels_reporting_traefik_rule: "Host(`{{ matrix_bot_meowlnir_container_labels_reporting_traefik_hostname }}`) && PathRegexp(`{{ matrix_bot_meowlnir_container_labels_reporting_traefik_path_regexp }}`)" +matrix_bot_meowlnir_container_labels_reporting_traefik_priority: 0 +matrix_bot_meowlnir_container_labels_reporting_traefik_entrypoints: "{{ matrix_synapse_container_labels_traefik_entrypoints }}" +matrix_bot_meowlnir_container_labels_reporting_traefik_tls: "{{ matrix_bot_meowlnir_container_labels_reporting_traefik_entrypoints != 'web' }}" +matrix_bot_meowlnir_container_labels_reporting_traefik_tls_certResolver: "{{ matrix_synapse_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# Policy server (/_matrix/policy), served on the federation endpoint +matrix_bot_meowlnir_container_labels_policy_server_traefik_hostname: "{{ matrix_synapse_container_labels_public_federation_api_traefik_hostname }}" +matrix_bot_meowlnir_container_labels_policy_server_traefik_path_prefix: /_matrix/policy +matrix_bot_meowlnir_container_labels_policy_server_traefik_rule: "Host(`{{ matrix_bot_meowlnir_container_labels_policy_server_traefik_hostname }}`) && PathPrefix(`{{ matrix_bot_meowlnir_container_labels_policy_server_traefik_path_prefix }}`)" +matrix_bot_meowlnir_container_labels_policy_server_traefik_priority: 0 +matrix_bot_meowlnir_container_labels_policy_server_traefik_entrypoints: "{{ matrix_synapse_container_labels_public_federation_api_traefik_entrypoints }}" +matrix_bot_meowlnir_container_labels_policy_server_traefik_tls: "{{ matrix_bot_meowlnir_container_labels_policy_server_traefik_entrypoints != 'web' }}" +matrix_bot_meowlnir_container_labels_policy_server_traefik_tls_certResolver: "{{ matrix_synapse_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bot_meowlnir_container_labels_traefik_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# See `../templates/labels.j2` for details. +# +# Example: +# matrix_bot_meowlnir_container_labels_traefik_labels_additional_labels: | +# my.label=1 +# another.label="here" +matrix_bot_meowlnir_container_labels_traefik_labels_additional_labels: '' + + +######################################################################## +# # +# Configuration assembly # +# # +######################################################################## + +# Default configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_bot_meowlnir_configuration_extension_yaml`) or completely replace this variable with your own template. +matrix_bot_meowlnir_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" + +matrix_bot_meowlnir_configuration_extension_yaml: | + # Your custom YAML configuration goes here. + # This configuration extends the default starting configuration (`matrix_bot_meowlnir_configuration_yaml`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by completely redefining `matrix_bot_meowlnir_configuration_yaml`. + +matrix_bot_meowlnir_configuration_extension: "{{ matrix_bot_meowlnir_configuration_extension_yaml | from_yaml if matrix_bot_meowlnir_configuration_extension_yaml | from_yaml is mapping else {} }}" + +# Holds the final configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. +# Instead, see `matrix_bot_meowlnir_configuration_yaml`. +matrix_bot_meowlnir_configuration: "{{ matrix_bot_meowlnir_configuration_yaml | from_yaml | combine(matrix_bot_meowlnir_configuration_extension, recursive=True) }}" + +# matrix_bot_meowlnir_restart_necessary controls whether the service will be restarted (when true) or merely started (when false) by the systemd service manager role (when conditional restart is enabled). +# +# This value is automatically computed during installation based on whether any configuration files, the systemd service file, or the container image changed. +# The default of `false` means "no restart needed" — appropriate when the role's installation tasks haven't run (e.g., due to --tags skipping them). +matrix_bot_meowlnir_restart_necessary: false diff --git a/roles/custom/matrix-bot-meowlnir/molecule/default/converge.yml b/roles/custom/matrix-bot-meowlnir/molecule/default/converge.yml new file mode 100644 index 000000000..fcbbf1c32 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/molecule/default/converge.yml @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-bot-meowlnir Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-bot-meowlnir Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +# Component roles install their unit; the complete playbook's service manager starts it. +- name: Ensure matrix-bot-meowlnir is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure matrix-bot-meowlnir systemd service is started + ansible.builtin.systemd_service: + name: matrix-bot-meowlnir.service + state: started diff --git a/roles/custom/matrix-bot-meowlnir/molecule/default/molecule.yml b/roles/custom/matrix-bot-meowlnir/molecule/default/molecule.yml new file mode 100644 index 000000000..0e5c355be --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/molecule/default/molecule.yml @@ -0,0 +1,155 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-bot-meowlnir-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bot_meowlnir_container_network: matrix-bot-meowlnir-molecule + + # verify.yml is a separate play where role defaults are out of scope. Pin only + # paths it reads; the component version comes from the role's defaults directly. + matrix_bot_meowlnir_base_path: /matrix/meowlnir + matrix_bot_meowlnir_config_path: /matrix/meowlnir/config + matrix_bot_meowlnir_data_path: /matrix/meowlnir/data + + # A local stub is available for bounded Matrix API calls. The empty-roster + # startup used here currently makes no outbound homeserver request, so the + # weight-bearing appservice gate is the authenticated inbound transaction in + # verify.yml. No real Matrix or third-party account is involved. + matrix_bot_meowlnir_config_homeserver_address: http://matrix.molecule.local:8008 + matrix_bot_meowlnir_config_homeserver_domain: molecule.local + matrix_bot_meowlnir_appservice_id: molecule-meowlnir + matrix_bot_meowlnir_appservice_sender_localpart: molecule_meowlnir_as + matrix_bot_meowlnir_user_prefix: molecule_meowlnir_bot_ + matrix_bot_meowlnir_appservice_token: molecule_as_token_2cf519 + matrix_bot_meowlnir_homeserver_token: molecule_hs_token_c20dc3 + + # Real Postgres is the normal playbook path. The non-default credentials make its + # migrated schema evidence that Meowlnir consumed the URI assembled by the role. + matrix_bot_meowlnir_database_engine: postgres + matrix_bot_meowlnir_database_hostname: matrix-postgres-molecule + matrix_bot_meowlnir_database_name: molecule_meowlnir + matrix_bot_meowlnir_database_username: molecule_meowlnir + matrix_bot_meowlnir_database_password: molecule_pg_password_da31bc + matrix_bot_meowlnir_database_sslmode: disable + matrix_bot_meowlnir_config_database_max_open_conns: 13 + matrix_bot_meowlnir_config_database_max_idle_conns: 3 + matrix_bot_meowlnir_config_database_max_conn_idle_time: 47s + matrix_bot_meowlnir_config_database_max_conn_lifetime: 11m + + # These differ from both role and upstream defaults. The authenticated management + # API below proves that the running process accepted the listener and secret. + matrix_bot_meowlnir_config_meowlnir_port: 29439 + matrix_bot_meowlnir_appservice_url: http://matrix-bot-meowlnir:29439 + matrix_bot_meowlnir_config_meowlnir_management_secret: molecule_management_secret_a64528 + matrix_bot_meowlnir_config_meowlnir_data_secret: molecule_data_secret_e8c7b4 + matrix_bot_meowlnir_config_meowlnir_federation_auth: true + matrix_bot_meowlnir_config_meowlnir_dry_run: true + matrix_bot_meowlnir_config_meowlnir_untrusted: true + matrix_bot_meowlnir_config_meowlnir_report_room: "!molecule-reports:molecule.local" + matrix_bot_meowlnir_config_meowlnir_room_ban_room: "!molecule-bans:molecule.local" + matrix_bot_meowlnir_config_meowlnir_hacky_rule_filter_custom: + - '@trusted:molecule.local' + - trusted.invalid + matrix_bot_meowlnir_config_meowlnir_hacky_redact_patterns_custom: + - molecule-abuse-* + matrix_bot_meowlnir_config_meowlnir_admin_tokens: + '@molecule-admin:molecule.local': molecule_admin_token_7e6ce0 + + matrix_bot_meowlnir_config_meowlnir4all_admin_room: "!molecule-provisioning:molecule.local" + matrix_bot_meowlnir_config_meowlnir4all_displayname: Molecule Provisioned Meowlnir + matrix_bot_meowlnir_config_meowlnir4all_avatar_url: mxc://molecule.local/meowlnir-avatar + matrix_bot_meowlnir_config_meowlnir4all_room_name: Molecule Meowlnir Control + matrix_bot_meowlnir_config_meowlnir4all_default_watched_lists_custom: + - name: Molecule policy list + room_id: "!molecule-policy:molecule.local" + shortcode: molecule + auto_unban: false + + matrix_bot_meowlnir_config_antispam_secret: molecule_antispam_secret_59d553 + matrix_bot_meowlnir_config_antispam_filter_local_invites: true + matrix_bot_meowlnir_config_antispam_auto_reject_invites_token: molecule_reject_token_a9812f + matrix_bot_meowlnir_config_antispam_notify_management_room: true + matrix_bot_meowlnir_config_antispam_block_invites_to_custom: + - '@blocked:molecule.local' + + # Both integrations render public routing labels. Their real handlers are not the + # readiness gate; the management API and database provide stronger process evidence. + matrix_bot_meowlnir_policy_server_enabled: true + matrix_bot_meowlnir_config_policy_server_always_redact: false + matrix_bot_meowlnir_config_policy_server_signing_key: >- + ed25519 policy_server MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY + matrix_bot_meowlnir_config_reporting_enabled: true + + matrix_bot_meowlnir_config_encryption_enable: false + matrix_bot_meowlnir_config_encryption_pickle_key: molecule_pickle_key_6f370e + matrix_bot_meowlnir_config_logging_min_level: debug + matrix_bot_meowlnir_config_logging_writers: + - type: stdout + format: json + + # No bot is declared: this avoids accepting provisioning behavior which is green only + # because a deliberately permissive homeserver stub papered over it. + matrix_bot_meowlnir_bots_custom: [] + matrix_bot_meowlnir_bots_pruning_enabled: false + + # Traefik is not deployed. Distinct non-default routes still prove the role's label + # contract both on disk and in Docker's accepted container labels. + matrix_bot_meowlnir_container_labels_traefik_enabled: true + matrix_bot_meowlnir_container_labels_traefik_docker_network: matrix-bot-meowlnir-molecule + matrix_bot_meowlnir_container_labels_reporting_traefik_hostname: reports.molecule.local + matrix_bot_meowlnir_container_labels_reporting_traefik_path_regexp: ^/molecule-report/(rooms|users)/[^/]+$$ + matrix_bot_meowlnir_container_labels_reporting_traefik_priority: 731 + matrix_bot_meowlnir_container_labels_reporting_traefik_entrypoints: web + matrix_bot_meowlnir_container_labels_reporting_traefik_tls: false + matrix_bot_meowlnir_container_labels_policy_server_traefik_hostname: federation.molecule.local + matrix_bot_meowlnir_container_labels_policy_server_traefik_path_prefix: /molecule-policy + matrix_bot_meowlnir_container_labels_policy_server_traefik_priority: 733 + matrix_bot_meowlnir_container_labels_policy_server_traefik_entrypoints: web + matrix_bot_meowlnir_container_labels_policy_server_traefik_tls: false + matrix_bot_meowlnir_container_labels_traefik_labels_additional_labels: | + molecule.meowlnir.coverage=enabled + + # Preserve the production-like no-host-port path; probes join its Docker network. + matrix_bot_meowlnir_container_http_host_bind_port: '' + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bot-meowlnir/molecule/default/prepare.yml b/roles/custom/matrix-bot-meowlnir/molecule/default/prepare.yml new file mode 100644 index 000000000..137b630b7 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/molecule/default/prepare.yml @@ -0,0 +1,91 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-bot-meowlnir Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # matrix-base creates this identity in the complete playbook. Role file tasks resolve + # owner/group by name, so the role-scoped scenario supplies that side effect. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # Postgres and the stub must join this network before the role's converge creates it. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bot_meowlnir_container_network }}" + register: matrix_bot_meowlnir_molecule_network + changed_when: matrix_bot_meowlnir_molecule_network.rc == 0 + failed_when: + - matrix_bot_meowlnir_molecule_network.rc != 0 + - "'already exists' not in matrix_bot_meowlnir_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bot_meowlnir_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bot_meowlnir_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bot_meowlnir_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bot_meowlnir_database_password }}" + + # Keep a local Matrix API available for bounded diagnostics and future provisioning + # coverage. Empty-roster startup currently makes no outbound homeserver request; the + # verifier therefore does not claim this stub as readiness evidence. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bot_meowlnir_container_network }}" + molecule_shared_stub_server_name: molecule.local + molecule_shared_stub_user_id: "@{{ matrix_bot_meowlnir_appservice_sender_localpart }}:{{ matrix_bot_meowlnir_config_homeserver_domain }}" diff --git a/roles/custom/matrix-bot-meowlnir/molecule/default/requirements.yml b/roles/custom/matrix-bot-meowlnir/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bot-meowlnir/molecule/default/verify.yml b/roles/custom/matrix-bot-meowlnir/molecule/default/verify.yml new file mode 100644 index 000000000..e4292903b --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/molecule/default/verify.yml @@ -0,0 +1,504 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Meowlnir's authenticated management API and Postgres schema are the readiness evidence. +# The homeserver is a deliberately limited local stub, so no claim is made about moderation. +- name: Verify matrix-bot-meowlnir + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + matrix_bot_meowlnir_rendered_config: "{{ matrix_bot_meowlnir_config_file.content | b64decode | from_yaml }}" + matrix_bot_meowlnir_rendered_registration: "{{ matrix_bot_meowlnir_registration_file.content | b64decode | from_yaml }}" + matrix_bot_meowlnir_api_body: "{{ matrix_bot_meowlnir_api_http.stdout_lines[:-1] | join('\n') }}" + matrix_bot_meowlnir_api_response: "{{ matrix_bot_meowlnir_api_body | from_json }}" + matrix_bot_meowlnir_expected_database_uri: >- + postgresql://{{ matrix_bot_meowlnir_database_username }}:{{ matrix_bot_meowlnir_database_password }}@{{ matrix_bot_meowlnir_database_hostname }}:5432/{{ matrix_bot_meowlnir_database_name }}?sslmode={{ matrix_bot_meowlnir_database_sslmode }} + matrix_bot_meowlnir_labels_lines: "{{ (matrix_bot_meowlnir_labels_file.content | b64decode).splitlines() }}" + matrix_bot_meowlnir_runtime: "{{ (matrix_bot_meowlnir_container_inspect.stdout | from_json) | first }}" + matrix_bot_meowlnir_config_mounts: "{{ matrix_bot_meowlnir_runtime.Mounts | selectattr('Destination', 'equalto', '/data/config') | list }}" + matrix_bot_meowlnir_data_mounts: "{{ matrix_bot_meowlnir_runtime.Mounts | selectattr('Destination', 'equalto', '/data') | list }}" + gather_facts: false + tasks: + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_bot_meowlnir_role_defaults + + - name: Wait for the matrix-bot-meowlnir service to become active + ansible.builtin.systemd_service: + name: matrix-bot-meowlnir.service + register: matrix_bot_meowlnir_service + until: matrix_bot_meowlnir_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_service.status.ActiveState == 'active' + - matrix_bot_meowlnir_service.status.NRestarts is defined + - matrix_bot_meowlnir_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-bot-meowlnir.service is + {{ matrix_bot_meowlnir_service.status.ActiveState | default('unknown') }} after + {{ matrix_bot_meowlnir_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-bot-meowlnir.service is active and has not restarted" + + - name: Wait for Meowlnir's authenticated management API + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_meowlnir_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --header + - 'Authorization: Bearer molecule_management_secret_a64528' + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-bot-meowlnir:29439/_meowlnir/v1/bots + register: matrix_bot_meowlnir_api_http + changed_when: false + until: "'HTTP_STATUS=200' in matrix_bot_meowlnir_api_http.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the management API authenticated the configured secret + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_api_http.rc == 0 + - matrix_bot_meowlnir_api_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_bot_meowlnir_api_response is mapping + - matrix_bot_meowlnir_api_response.bots is sequence + - matrix_bot_meowlnir_api_response.bots | length == 0 + fail_msg: >- + Meowlnir's management API did not authenticate or return its empty bot roster + ({{ matrix_bot_meowlnir_api_http.stdout | default('no output') }}) + success_msg: "Meowlnir's live management API authenticated the configured secret" + + - name: Ask the management API with a wrong secret + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_meowlnir_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --header + - 'Authorization: Bearer molecule_wrong_secret' + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-bot-meowlnir:29439/_meowlnir/v1/bots + register: matrix_bot_meowlnir_wrong_secret_http + changed_when: false + failed_when: false + + - name: Assert the management API rejects a wrong secret + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_wrong_secret_http.rc == 0 + - matrix_bot_meowlnir_wrong_secret_http.stdout in ['HTTP_STATUS=401', 'HTTP_STATUS=403'] + fail_msg: "Meowlnir's management API accepted the wrong bearer secret" + success_msg: "Meowlnir's management API rejects a wrong bearer secret" + + # This is the appservice half of the live homeserver handshake. A valid empty + # transaction can only reach the dispatcher if the process loaded its hs_token. + - name: Send a homeserver transaction to Meowlnir's appservice API + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_meowlnir_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --request + - PUT + - --header + - 'Authorization: Bearer molecule_hs_token_c20dc3' + - --header + - 'Content-Type: application/json' + - --data + - '{"events":[],"ephemeral":[],"to_device":[]}' + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-bot-meowlnir:29439/_matrix/app/v1/transactions/molecule-transaction + register: matrix_bot_meowlnir_transaction_http + changed_when: false + failed_when: false + + - name: Assert Meowlnir accepts a transaction authenticated with the configured homeserver token + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_transaction_http.rc == 0 + - matrix_bot_meowlnir_transaction_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_bot_meowlnir_transaction_http.stdout_lines[:-1] | join('\n') | from_json == {} + fail_msg: >- + Meowlnir rejected an empty appservice transaction carrying the configured hs_token + ({{ matrix_bot_meowlnir_transaction_http.stdout | default('no output') }}) + success_msg: "Meowlnir accepts transactions carrying the configured homeserver token" + + - name: Send an appservice transaction with a wrong homeserver token + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_meowlnir_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --request + - PUT + - --header + - 'Authorization: Bearer molecule_wrong_hs_token' + - --header + - 'Content-Type: application/json' + - --data + - '{"events":[]}' + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-bot-meowlnir:29439/_matrix/app/v1/transactions/molecule-wrong-token + register: matrix_bot_meowlnir_wrong_transaction_http + changed_when: false + failed_when: false + + - name: Assert Meowlnir rejects a transaction with the wrong homeserver token + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_wrong_transaction_http.rc == 0 + - matrix_bot_meowlnir_wrong_transaction_http.stdout == 'HTTP_STATUS=401' + fail_msg: "Meowlnir accepted an appservice transaction carrying a wrong hs_token" + success_msg: "Meowlnir rejects transactions carrying a wrong homeserver token" + + - name: Probe the role's default Meowlnir port + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bot_meowlnir_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --max-time + - '3' + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-bot-meowlnir:29339/_meowlnir/v1/bots + register: matrix_bot_meowlnir_default_port_http + changed_when: false + failed_when: false + + - name: Assert Meowlnir is not listening on the role's default port + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_default_port_http.rc != 0 + - matrix_bot_meowlnir_default_port_http.stdout == 'HTTP_STATUS=000' + fail_msg: "Meowlnir still answers on 29339, so the configured port is not proven" + success_msg: "Meowlnir does not listen on the role's default port" + + - name: Read the configuration file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_meowlnir_config_path }}/config.yaml" + register: matrix_bot_meowlnir_config_file + + - name: Assert the parsed homeserver and appservice configuration + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_rendered_config.homeserver.address == matrix_bot_meowlnir_config_homeserver_address + - matrix_bot_meowlnir_rendered_config.homeserver.domain == matrix_bot_meowlnir_config_homeserver_domain + - matrix_bot_meowlnir_rendered_config.meowlnir.id == matrix_bot_meowlnir_appservice_id + - matrix_bot_meowlnir_rendered_config.meowlnir.as_token == matrix_bot_meowlnir_appservice_token + - matrix_bot_meowlnir_rendered_config.meowlnir.hs_token == matrix_bot_meowlnir_homeserver_token + - matrix_bot_meowlnir_rendered_config.meowlnir.address == matrix_bot_meowlnir_appservice_url + - matrix_bot_meowlnir_rendered_config.meowlnir.hostname == '0.0.0.0' + - matrix_bot_meowlnir_rendered_config.meowlnir.port == matrix_bot_meowlnir_config_meowlnir_port + fail_msg: "The parsed configuration lost the scenario's Matrix/appservice wiring" + success_msg: "The parsed configuration carries the scenario's Matrix/appservice wiring" + + - name: Assert the parsed Meowlnir behavior and secrets + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_rendered_config.meowlnir.management_secret == matrix_bot_meowlnir_config_meowlnir_management_secret + - matrix_bot_meowlnir_rendered_config.meowlnir.data_secret == matrix_bot_meowlnir_config_meowlnir_data_secret + - matrix_bot_meowlnir_rendered_config.meowlnir.federation_auth is sameas true + - matrix_bot_meowlnir_rendered_config.meowlnir.dry_run is sameas true + - matrix_bot_meowlnir_rendered_config.meowlnir.untrusted is sameas true + - matrix_bot_meowlnir_rendered_config.meowlnir.report_room == '!molecule-reports:molecule.local' + - matrix_bot_meowlnir_rendered_config.meowlnir.room_ban_room == '!molecule-bans:molecule.local' + - matrix_bot_meowlnir_rendered_config.meowlnir.hacky_rule_filter == ['@trusted:molecule.local', 'trusted.invalid'] + - matrix_bot_meowlnir_rendered_config.meowlnir.hacky_redact_patterns == ['spam', 'molecule-abuse-*'] + - matrix_bot_meowlnir_rendered_config.meowlnir.admin_tokens['@molecule-admin:molecule.local'] == 'molecule_admin_token_7e6ce0' + fail_msg: "The parsed configuration lost the non-default Meowlnir behavior" + success_msg: "The parsed configuration carries the non-default Meowlnir behavior" + + - name: Assert the parsed provisioning, antispam and policy configuration + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_rendered_config.meowlnir4all.admin_room == '!molecule-provisioning:molecule.local' + - matrix_bot_meowlnir_rendered_config.meowlnir4all.localpart_template == matrix_bot_meowlnir_user_prefix + ('{' + '{ uuidgen }' + '}') + - matrix_bot_meowlnir_rendered_config.meowlnir4all.displayname == 'Molecule Provisioned Meowlnir' + - matrix_bot_meowlnir_rendered_config.meowlnir4all.avatar_url == 'mxc://molecule.local/meowlnir-avatar' + - matrix_bot_meowlnir_rendered_config.meowlnir4all.room_name == 'Molecule Meowlnir Control' + - matrix_bot_meowlnir_rendered_config.meowlnir4all.default_watched_lists | length == 1 + - matrix_bot_meowlnir_rendered_config.meowlnir4all.default_watched_lists[0].name == 'Molecule policy list' + - matrix_bot_meowlnir_rendered_config.meowlnir4all.default_watched_lists[0].room_id == '!molecule-policy:molecule.local' + - matrix_bot_meowlnir_rendered_config.meowlnir4all.default_watched_lists[0].shortcode == 'molecule' + - matrix_bot_meowlnir_rendered_config.meowlnir4all.default_watched_lists[0].auto_unban is sameas false + - matrix_bot_meowlnir_rendered_config.antispam.secret == matrix_bot_meowlnir_config_antispam_secret + - matrix_bot_meowlnir_rendered_config.antispam.filter_local_invites is sameas true + - matrix_bot_meowlnir_rendered_config.antispam.auto_reject_invites_token == 'molecule_reject_token_a9812f' + - matrix_bot_meowlnir_rendered_config.antispam.notify_management_room is sameas true + - matrix_bot_meowlnir_rendered_config.antispam.block_invites_to == ['@blocked:molecule.local'] + - matrix_bot_meowlnir_rendered_config.policy_server.always_redact is sameas false + - matrix_bot_meowlnir_rendered_config.policy_server.signing_key.startswith('ed25519 policy_server ') + fail_msg: "The parsed provisioning/antispam/policy blocks lost scenario values" + success_msg: "The parsed provisioning/antispam/policy blocks carry scenario values" + + - name: Assert the parsed Postgres and logging configuration + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_rendered_config.database.type == 'postgres' + - matrix_bot_meowlnir_rendered_config.database.uri == matrix_bot_meowlnir_expected_database_uri + - matrix_bot_meowlnir_rendered_config.database.max_open_conns == 13 + - matrix_bot_meowlnir_rendered_config.database.max_idle_conns == 3 + - matrix_bot_meowlnir_rendered_config.database.max_conn_idle_time == '47s' + - matrix_bot_meowlnir_rendered_config.database.max_conn_lifetime == '11m' + - matrix_bot_meowlnir_rendered_config.synapse_db.type == 'postgres' + - matrix_bot_meowlnir_rendered_config.synapse_db.uri == '' + - matrix_bot_meowlnir_rendered_config.logging.min_level == 'debug' + - "matrix_bot_meowlnir_rendered_config.logging.writers == [{'type': 'stdout', 'format': 'json'}]" + fail_msg: "The parsed database/logging blocks lost scenario values" + success_msg: "The parsed database/logging blocks carry scenario values" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_meowlnir_config_path }}/registration.yaml" + register: matrix_bot_meowlnir_registration_file + + - name: Assert the parsed appservice registration contract + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_rendered_registration.id == matrix_bot_meowlnir_appservice_id + - matrix_bot_meowlnir_rendered_registration.as_token == matrix_bot_meowlnir_appservice_token + - matrix_bot_meowlnir_rendered_registration.hs_token == matrix_bot_meowlnir_homeserver_token + - matrix_bot_meowlnir_rendered_registration.url == matrix_bot_meowlnir_appservice_url + - matrix_bot_meowlnir_rendered_registration.sender_localpart == matrix_bot_meowlnir_appservice_sender_localpart + - matrix_bot_meowlnir_rendered_registration.rate_limited is sameas false + - matrix_bot_meowlnir_rendered_registration.namespaces.users | length == 2 + - matrix_bot_meowlnir_rendered_registration.namespaces.users[0].exclusive is sameas true + - matrix_bot_meowlnir_rendered_registration.namespaces.users[0].regex == '^@molecule_meowlnir_bot_[a-zA-Z0-9._=/+-]+:molecule\\.local$' + - matrix_bot_meowlnir_rendered_registration.namespaces.users[1].regex == '^@molecule_meowlnir_as:molecule\\.local$' + - matrix_bot_meowlnir_rendered_registration['de.sorunome.msc2409.push_ephemeral'] is not defined + fail_msg: "The appservice registration lost its tokens, address or namespaces" + success_msg: "The appservice registration carries its tokens, address and namespaces" + + - name: List the tables Meowlnir created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bot_meowlnir_database_username }} + - --dbname={{ matrix_bot_meowlnir_database_name }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: matrix_bot_meowlnir_tables + changed_when: false + + - name: Assert Meowlnir migrated its schema into the configured Postgres database + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_tables.rc == 0 + - "'version' in matrix_bot_meowlnir_table_names" + - "'bot' in matrix_bot_meowlnir_table_names" + - "'management_room' in matrix_bot_meowlnir_table_names" + - "'mx_version' in matrix_bot_meowlnir_table_names" + - "'mx_room_state' in matrix_bot_meowlnir_table_names" + - "'policy_server_signature' in matrix_bot_meowlnir_table_names" + - matrix_bot_meowlnir_table_names | length == 10 + fail_msg: >- + Meowlnir did not create a substantial schema in {{ matrix_bot_meowlnir_database_name }} + (found {{ matrix_bot_meowlnir_table_names | length }} table(s)) + success_msg: "Meowlnir migrated its schema into the configured Postgres database" + vars: + matrix_bot_meowlnir_table_names: "{{ matrix_bot_meowlnir_tables.stdout_lines | select | list }}" + + - name: Read Meowlnir's two database migration markers + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bot_meowlnir_database_username }} + - --dbname={{ matrix_bot_meowlnir_database_name }} + - --tuples-only + - --no-align + - --command=SELECT 'main:' || version || ':' || compat FROM version UNION ALL SELECT 'matrix_state:' || version || ':' || compat FROM mx_version ORDER BY 1 + register: matrix_bot_meowlnir_migration_versions + changed_when: false + + - name: Assert both Meowlnir schema sections reached their expected versions + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_migration_versions.rc == 0 + - matrix_bot_meowlnir_migration_versions.stdout_lines | select | list == ['main:3:1', 'matrix_state:11:3'] + fail_msg: >- + Meowlnir's main and Matrix-state migrations did not reach versions 3 and 11 + ({{ matrix_bot_meowlnir_migration_versions.stdout_lines | select | list }}) + success_msg: "Both Meowlnir database schema sections reached their expected versions" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bot_meowlnir_base_path }}/labels" + register: matrix_bot_meowlnir_labels_file + + - name: Assert the labels carry the configured reporting and policy routes + ansible.builtin.assert: + that: + - "'traefik.enable=true' in matrix_bot_meowlnir_labels_lines" + - "'traefik.docker.network=matrix-bot-meowlnir-molecule' in matrix_bot_meowlnir_labels_lines" + - "'traefik.http.services.matrix-bot-meowlnir.loadbalancer.server.port=29439' in matrix_bot_meowlnir_labels_lines" + - "'traefik.http.routers.matrix-bot-meowlnir-reporting.rule=Host(`reports.molecule.local`) && PathRegexp(`^/molecule-report/(rooms|users)/[^/]+$`)' in matrix_bot_meowlnir_labels_lines" + - "'traefik.http.routers.matrix-bot-meowlnir-reporting.priority=731' in matrix_bot_meowlnir_labels_lines" + - "'traefik.http.routers.matrix-bot-meowlnir-reporting.entrypoints=web' in matrix_bot_meowlnir_labels_lines" + - "'traefik.http.routers.matrix-bot-meowlnir-reporting.tls=false' in matrix_bot_meowlnir_labels_lines" + - "'traefik.http.routers.matrix-bot-meowlnir-policy-server.rule=Host(`federation.molecule.local`) && PathPrefix(`/molecule-policy`)' in matrix_bot_meowlnir_labels_lines" + - "'traefik.http.routers.matrix-bot-meowlnir-policy-server.priority=733' in matrix_bot_meowlnir_labels_lines" + - "'traefik.http.routers.matrix-bot-meowlnir-policy-server.entrypoints=web' in matrix_bot_meowlnir_labels_lines" + - "'traefik.http.routers.matrix-bot-meowlnir-policy-server.tls=false' in matrix_bot_meowlnir_labels_lines" + - "'molecule.meowlnir.coverage=enabled' in matrix_bot_meowlnir_labels_lines" + fail_msg: "The role's labels lost the non-default public routing contract" + success_msg: "The role's labels carry the non-default public routing contract" + + - name: Inspect the running Meowlnir container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-bot-meowlnir + register: matrix_bot_meowlnir_container_inspect + changed_when: false + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_runtime.Config.Image == matrix_bot_meowlnir_expected_image + fail_msg: "The running Meowlnir container does not use the role's exact image pin" + success_msg: "The running container uses the exact image pinned by the role" + vars: + matrix_bot_meowlnir_expected_image: >- + {{ matrix_bot_meowlnir_role_defaults.matrix_bot_meowlnir_container_image_registry_prefix_upstream_default }}{{ matrix_bot_meowlnir_role_defaults.matrix_bot_meowlnir_container_image_registry_namespace_identifier }}:{{ matrix_bot_meowlnir_role_defaults.matrix_bot_meowlnir_version }} + + - name: Assert the running container uses the playbook's matrix identity + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_runtime.Config.User.split(':')[0] == matrix_user_uid | string + - matrix_bot_meowlnir_runtime.Config.User.split(':')[1] == matrix_user_gid | string + fail_msg: >- + Meowlnir runs as {{ matrix_bot_meowlnir_runtime.Config.User }} instead of + {{ matrix_user_uid }}:{{ matrix_user_gid }} + success_msg: "The running container uses the playbook's matrix UID and GID" + + - name: Assert the running container has the role's exact command + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_runtime.Config.Cmd == ['/usr/bin/meowlnir', '--config=/data/config/config.yaml', '--no-update'] + fail_msg: "The running Meowlnir container command differs from the role contract" + success_msg: "The running container has the role's exact command" + + - name: Assert the container root filesystem is read-only + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_runtime.HostConfig.ReadonlyRootfs is sameas true + fail_msg: "The Meowlnir container root filesystem is writable" + success_msg: "The Meowlnir container root filesystem is read-only" + + - name: Assert all Linux capabilities are dropped + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_runtime.HostConfig.CapDrop == ['ALL'] + fail_msg: "The Meowlnir container does not drop all Linux capabilities" + success_msg: "The Meowlnir container drops all Linux capabilities" + + - name: Assert the configuration bind mount is read-only + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_config_mounts | length == 1 + - matrix_bot_meowlnir_config_mounts[0].RW is sameas false + - matrix_bot_meowlnir_config_mounts[0].Source == matrix_bot_meowlnir_config_path + fail_msg: "The Meowlnir configuration bind mount is missing, misplaced or writable" + success_msg: "The configuration bind mount is present and read-only" + + - name: Assert the data bind mount is writable + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_data_mounts | length == 1 + - matrix_bot_meowlnir_data_mounts[0].RW is sameas true + - matrix_bot_meowlnir_data_mounts[0].Source == matrix_bot_meowlnir_data_path + fail_msg: "The Meowlnir data bind mount is missing, misplaced or read-only" + success_msg: "The data bind mount is present and writable" + + - name: Assert the container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_runtime.NetworkSettings.Networks is mapping + - matrix_bot_meowlnir_runtime.NetworkSettings.Networks | length == 1 + - matrix_bot_meowlnir_container_network in matrix_bot_meowlnir_runtime.NetworkSettings.Networks + fail_msg: >- + Meowlnir has unexpected networks: + {{ matrix_bot_meowlnir_runtime.NetworkSettings.Networks.keys() | list }} + success_msg: "The container is attached only to its dedicated network" + + - name: Ask Docker for Meowlnir's published ports + ansible.builtin.command: + argv: + - docker + - container + - port + - matrix-bot-meowlnir + register: matrix_bot_meowlnir_published_ports + changed_when: false + failed_when: false + + - name: Assert the role did not publish a host port + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_runtime.HostConfig.PortBindings | default({}, true) | length == 0 + - matrix_bot_meowlnir_published_ports.rc == 0 + - matrix_bot_meowlnir_published_ports.stdout | trim | length == 0 + fail_msg: >- + Meowlnir unexpectedly publishes a host port: + {{ matrix_bot_meowlnir_published_ports.stdout | default('unknown') }} + success_msg: "The role leaves Meowlnir's HTTP port unpublished" + + - name: Assert Docker accepted the role's custom label + ansible.builtin.assert: + that: + - matrix_bot_meowlnir_runtime.Config.Labels is mapping + - matrix_bot_meowlnir_runtime.Config.Labels['molecule.meowlnir.coverage'] == 'enabled' + fail_msg: "Docker did not attach the custom label from the role's label file" + success_msg: "Docker accepted the role's custom label" diff --git a/roles/custom/matrix-bot-meowlnir/tasks/main.yml b/roles/custom/matrix-bot-meowlnir/tasks/main.yml new file mode 100644 index 000000000..081847d61 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/main.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- tags: + - setup-all + - setup-bot-meowlnir + - install-all + - install-bot-meowlnir + block: + - when: matrix_bot_meowlnir_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" + + - when: matrix_bot_meowlnir_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" + +- tags: + - setup-all + - setup-bot-meowlnir + block: + - when: not matrix_bot_meowlnir_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" + +# Creating bots talks to Meowlnir's management API, which means starting the service and writing to its database. +# Like the matrix-user-creator role, this intentionally stays off the `setup-all` tag, so that an initial installation does not populate a database that is about to be replaced by an import. +- tags: + - ensure-matrix-users-created + - ensure-users-created + block: + # Runs when there are bots to create, but also when there are none and pruning is on: an emptied-out bot list is exactly the case the pruning safeguards need to see. + - when: >- + matrix_bot_meowlnir_enabled | bool + and (matrix_bot_meowlnir_bots | length > 0 or matrix_bot_meowlnir_bots_pruning_enabled | bool) + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_bots.yml" diff --git a/roles/custom/matrix-bot-meowlnir/tasks/setup_bots.yml b/roles/custom/matrix-bot-meowlnir/tasks/setup_bots.yml new file mode 100644 index 000000000..e0e7cae1b --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/setup_bots.yml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# Validation lives in validate_config.yml so that it also runs on regular setup/install runs, catching mistakes long before anyone reaches for the `ensure-matrix-users-created` tag. +# It is repeated here because this tag can be run on its own, and creating a bot outside the appservice's user namespace fails in ways that are hard to trace back. +- name: Validate matrix-bot-meowlnir configuration before creating bots + ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" + +- name: Ensure matrix-bot-meowlnir is started before creating bots + ansible.builtin.service: + name: matrix-bot-meowlnir.service + state: started + daemon_reload: true + register: matrix_bot_meowlnir_start_result + +- name: Wait a while, so that Meowlnir can manage to start before creating bots + ansible.builtin.pause: + seconds: "{{ matrix_bot_meowlnir_bots_start_wait_time_seconds }}" + when: matrix_bot_meowlnir_start_result.changed | bool + +- name: Ensure the homeserver accepts Meowlnir's appservice token before creating bots + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/ensure_appservice_token_accepted.yml" + +- name: Read which bots Meowlnir already has + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/read_meowlnir_state.yml" + +- name: Ensure Meowlnir bots created + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/ensure_bot_created.yml" + with_items: "{{ matrix_bot_meowlnir_bots }}" + loop_control: + loop_var: bot + +- name: Remove Meowlnir bots which are no longer declared + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/prune_bots.yml" + when: matrix_bot_meowlnir_bots_pruning_enabled | bool diff --git a/roles/custom/matrix-bot-meowlnir/tasks/setup_install.yml b/roles/custom/matrix-bot-meowlnir/tasks/setup_install.yml new file mode 100644 index 000000000..5fd071b5c --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/setup_install.yml @@ -0,0 +1,128 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Ensure matrix-bot-meowlnir paths exist + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + mode: '0750' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - {path: "{{ matrix_bot_meowlnir_base_path }}", when: true} + - {path: "{{ matrix_bot_meowlnir_config_path }}", when: true} + - {path: "{{ matrix_bot_meowlnir_data_path }}", when: true} + - {path: "{{ matrix_bot_meowlnir_bin_path }}", when: true} + - {path: "{{ matrix_bot_meowlnir_container_src_files_path }}", when: "{{ matrix_bot_meowlnir_container_image_self_build }}"} + when: "item.when | bool" + +- name: Ensure Meowlnir Docker image is pulled + community.docker.docker_image_pull: + name: "{{ matrix_bot_meowlnir_container_image }}" + pull: always + when: "not matrix_bot_meowlnir_container_image_self_build | bool" + register: matrix_bot_meowlnir_container_image_pull_result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: matrix_bot_meowlnir_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Meowlnir repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bot_meowlnir_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bot_meowlnir_container_image_self_build | bool" + +- name: Ensure Meowlnir repository is present on self-build + ansible.builtin.git: + repo: "{{ matrix_bot_meowlnir_container_image_self_build_repo }}" + dest: "{{ matrix_bot_meowlnir_container_src_files_path }}" + version: "{{ matrix_bot_meowlnir_container_image.split(':')[1] }}" + force: "yes" + become: true + become_user: "{{ matrix_user_name }}" + register: matrix_bot_meowlnir_git_pull_results + when: "matrix_bot_meowlnir_container_image_self_build | bool" + +- name: Ensure Meowlnir Docker image is built + community.docker.docker_image_build: + name: "{{ matrix_bot_meowlnir_container_image }}" + dockerfile: Dockerfile.ci + path: "{{ matrix_bot_meowlnir_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bot_meowlnir_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bot_meowlnir_container_image_self_build | bool" + register: matrix_bot_meowlnir_container_image_build_result + +- name: Ensure matrix-bot-meowlnir config installed + ansible.builtin.copy: + content: "{{ matrix_bot_meowlnir_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bot_meowlnir_config_path }}/config.yaml" + mode: '0640' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bot_meowlnir_config_result + +- name: Ensure matrix-bot-meowlnir registration.yaml installed + ansible.builtin.copy: + content: "{{ matrix_bot_meowlnir_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bot_meowlnir_config_path }}/registration.yaml" + mode: '0640' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bot_meowlnir_registration_result + +- name: Ensure matrix-bot-meowlnir scripts installed + ansible.builtin.template: + src: "{{ role_path }}/templates/bin/{{ item }}.j2" + dest: "{{ matrix_bot_meowlnir_bin_path }}/{{ item }}" + mode: '0750' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - meowlnir-api + - meowlnir-bots + - meowlnir-create-management-room + - meowlnir-whoami + +- name: Ensure matrix-bot-meowlnir container network is created + when: matrix_bot_meowlnir_container_network != 'host' + community.general.docker_network: + enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" + name: "{{ matrix_bot_meowlnir_container_network }}" + driver: bridge + driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" + +- name: Ensure matrix-bot-meowlnir container labels installed + ansible.builtin.template: + src: "{{ role_path }}/templates/labels.j2" + dest: "{{ matrix_bot_meowlnir_base_path }}/labels" + mode: '0640' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bot_meowlnir_labels_result + +- name: Ensure matrix-bot-meowlnir.service installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-bot-meowlnir.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-meowlnir.service" + mode: '0644' + register: matrix_bot_meowlnir_systemd_service_result + +- name: Determine whether Meowlnir needs a restart + ansible.builtin.set_fact: + matrix_bot_meowlnir_restart_necessary: >- + {{ + matrix_bot_meowlnir_config_result.changed | default(false) + or matrix_bot_meowlnir_registration_result.changed | default(false) + or matrix_bot_meowlnir_labels_result.changed | default(false) + or matrix_bot_meowlnir_systemd_service_result.changed | default(false) + or matrix_bot_meowlnir_container_image_pull_result.changed | default(false) + or matrix_bot_meowlnir_container_image_build_result.changed | default(false) + }} diff --git a/roles/custom/matrix-bot-meowlnir/tasks/setup_uninstall.yml b/roles/custom/matrix-bot-meowlnir/tasks/setup_uninstall.yml new file mode 100644 index 000000000..5fef82801 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/setup_uninstall.yml @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Check existence of matrix-bot-meowlnir service + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-meowlnir.service" + register: matrix_bot_meowlnir_service_stat + +- when: matrix_bot_meowlnir_service_stat.stat.exists | bool + block: + - name: Ensure matrix-bot-meowlnir is stopped + ansible.builtin.service: + name: matrix-bot-meowlnir + state: stopped + enabled: false + daemon_reload: true + + - name: Ensure matrix-bot-meowlnir.service doesn't exist + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-meowlnir.service" + state: absent + + - name: Ensure matrix-bot-meowlnir paths don't exist + ansible.builtin.file: + path: "{{ matrix_bot_meowlnir_base_path }}" + state: absent diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_appservice_token_accepted.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_appservice_token_accepted.yml new file mode 100644 index 000000000..78adece76 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_appservice_token_accepted.yml @@ -0,0 +1,94 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# The homeserver only reads appservice registrations on startup, so on the run which first enables Meowlnir it typically still runs without this one and rejects Meowlnir's appservice token with `M_UNKNOWN_TOKEN`. +# Meowlnir then cannot register bot users, and the whole provisioning flow below would fail in confusing ways. +# Restarts are normally left to the systemd service manager at the very end of the playbook, which is too late for the provisioning happening here, so this is checked upfront and the homeserver is restarted early when needed. +# +# The checks retry for a while, because the homeserver may still be starting up — an early request fails to connect, or gets a `502` from a reverse proxy in front of the homeserver. + +- name: Check whether the homeserver accepts Meowlnir's appservice token + block: + - name: Ask the homeserver whether it accepts Meowlnir's appservice token + ansible.builtin.command: + cmd: "{{ matrix_bot_meowlnir_bin_path }}/meowlnir-whoami" + register: matrix_bot_meowlnir_whoami_result + changed_when: false + retries: "{{ matrix_bot_meowlnir_appservice_token_check_retries_count }}" + delay: "{{ matrix_bot_meowlnir_appservice_token_check_retries_delay_seconds }}" + until: >- + matrix_bot_meowlnir_whoami_result.rc == 0 + and (matrix_bot_meowlnir_whoami_result.stdout_lines | default([]) | length > 0) + and (matrix_bot_meowlnir_whoami_result.stdout_lines | last in ['200', '401']) + rescue: + - name: Fail because the homeserver could not be asked about Meowlnir's appservice token + ansible.builtin.fail: + msg: >- + {{ + 'Could not get a usable answer from the homeserver about Meowlnir\'s appservice token. The last attempt said: ' + ~ (matrix_bot_meowlnir_whoami_result.stdout | default('') | trim) + ~ ' ' + ~ (matrix_bot_meowlnir_whoami_result.stderr | default('') | trim) + }} + +- name: Ensure the homeserver picks up Meowlnir's appservice registration + when: matrix_bot_meowlnir_whoami_result.stdout_lines | last == '401' + block: + - name: Fail if the homeserver rejects Meowlnir's appservice token and the playbook does not know how to help + ansible.builtin.fail: + msg: >- + {{ + 'The homeserver rejects Meowlnir\'s appservice token (M_UNKNOWN_TOKEN), meaning it runs without Meowlnir\'s appservice registration, ' + ~ 'and `matrix_bot_meowlnir_homeserver_restart_systemd_services_list` is empty, so the playbook does not know which service to restart to fix that. ' + ~ 'If the playbook manages appservice registrations for your homeserver implementation, restart the homeserver (e.g. by running the playbook with `--tags=setup-all,start`) and re-run this tag. ' + ~ 'Otherwise, register `' ~ matrix_bot_meowlnir_config_path ~ '/registration.yaml` with your homeserver manually, restart it, and re-run this tag.' + }} + when: matrix_bot_meowlnir_homeserver_restart_systemd_services_list | length == 0 + + - name: Ensure the homeserver is restarted, so that it picks up Meowlnir's appservice registration + ansible.builtin.service: + name: "{{ item }}" + state: restarted + daemon_reload: true + with_items: "{{ matrix_bot_meowlnir_homeserver_restart_systemd_services_list }}" + + # The re-check deliberately registers a differently-named variable. + # Registration happens even for skipped tasks, so reusing the name would clobber the result which the surrounding block's `when` keeps being evaluated against. + - name: Check whether the homeserver accepts Meowlnir's appservice token after the restart + block: + - name: Ask the homeserver again whether it accepts Meowlnir's appservice token + ansible.builtin.command: + cmd: "{{ matrix_bot_meowlnir_bin_path }}/meowlnir-whoami" + register: matrix_bot_meowlnir_whoami_recheck_result + changed_when: false + retries: "{{ matrix_bot_meowlnir_appservice_token_check_retries_count }}" + delay: "{{ matrix_bot_meowlnir_appservice_token_check_retries_delay_seconds }}" + until: >- + matrix_bot_meowlnir_whoami_recheck_result.rc == 0 + and (matrix_bot_meowlnir_whoami_recheck_result.stdout_lines | default([]) | length > 0) + and (matrix_bot_meowlnir_whoami_recheck_result.stdout_lines | last == '200') + rescue: + - name: Fail because the homeserver still rejects Meowlnir's appservice token after being restarted + ansible.builtin.fail: + msg: >- + {{ + 'The homeserver still rejects Meowlnir\'s appservice token after a restart. The last attempt said: ' + ~ (matrix_bot_meowlnir_whoami_recheck_result.stdout | default('') | trim) + ~ ' ' + ~ (matrix_bot_meowlnir_whoami_recheck_result.stderr | default('') | trim) + ~ ' Check the homeserver\'s logs and make sure it is configured to load Meowlnir\'s appservice registration (`' ~ matrix_bot_meowlnir_config_path ~ '/registration.yaml`).' + }} + + # Until the homeserver restart above, Meowlnir had only ever seen its token rejected. + # It does recover on its own eventually, but a fresh start is quicker and also clears any state left behind by earlier failed provisioning attempts (a bot creation request which never got to finish keeps its management API busy indefinitely). + - name: Ensure matrix-bot-meowlnir is restarted, so that it reconnects to the homeserver cleanly + ansible.builtin.service: + name: matrix-bot-meowlnir.service + state: restarted + + - name: Wait a while, so that Meowlnir can manage to start after reconnecting to the homeserver + ansible.builtin.pause: + seconds: "{{ matrix_bot_meowlnir_bots_start_wait_time_seconds }}" diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_bot_created.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_bot_created.yml new file mode 100644 index 000000000..800540207 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_bot_created.yml @@ -0,0 +1,81 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# The management API endpoints are idempotent PUTs, so re-running is safe. + +# Meowlnir's own record of this bot, as fetched before the loop started. +# Empty when the bot does not exist yet. +- name: Look up what Meowlnir already knows about the bot - {{ bot.username | quote }} + ansible.builtin.set_fact: + matrix_bot_meowlnir_bot_live: >- + {{ + (matrix_bot_meowlnir_live_bots | selectattr('username', 'equalto', bot.username) | list | first) + | default({}, true) + }} + +# `PUT /_meowlnir/v1/bot/…` answers 200 whether it created the bot, updated it, or did nothing at all, so the response cannot tell us whether anything changed. +# Comparing against what Meowlnir already holds lets the request be skipped when it would be a no-op, which both avoids pointless calls and lets the task report an honest changed state. +# +# Note that this trusts Meowlnir's own record. +# Changing a bot's profile directly through a Matrix client goes behind its back and will not be corrected here. +- name: Determine whether the Meowlnir bot needs creating or updating - {{ bot.username | quote }} + ansible.builtin.set_fact: + matrix_bot_meowlnir_bot_needs_update: >- + {{ + not matrix_bot_meowlnir_bot_live + or (matrix_bot_meowlnir_bot_live.displayname | default('', true)) != bot.displayname + or (matrix_bot_meowlnir_bot_live.avatar_url | default('', true)) != bot.avatar_url + }} + matrix_bot_meowlnir_bot_body: >- + {{ + { + 'displayname': bot.displayname, + 'avatar_url': bot.avatar_url, + } + }} + +- name: Ensure Meowlnir bot exists and is up to date - {{ bot.username | quote }} + when: matrix_bot_meowlnir_bot_needs_update | bool + ansible.builtin.command: + cmd: >- + {{ matrix_bot_meowlnir_bin_path }}/meowlnir-api + PUT /_meowlnir/v1/bot/{{ bot.username }} + {{ matrix_bot_meowlnir_bot_body | to_json | quote }} + register: matrix_bot_meowlnir_bot_create_result + # The task only runs when something needs changing, so a successful call is reported as a change. + # Deriving this from the status keeps a failed call from also claiming to have changed anything. + # Meowlnir answers 200 even when it could not apply the displayname or avatar (it only logs that), so this is what was asked for, not proof of what landed. A later run retries, since its stored record is unchanged. + changed_when: "matrix_bot_meowlnir_bot_create_result.stdout_lines | default([]) | last | default('') == '200'" + failed_when: false + +- name: Fail if the Meowlnir bot could not be created - {{ bot.username | quote }} + ansible.builtin.fail: + msg: >- + Creating the Meowlnir bot `{{ bot.username }}` failed. + Meowlnir said: {{ matrix_bot_meowlnir_bot_create_result.stdout | default('') | trim }} + {{ matrix_bot_meowlnir_bot_create_result.stderr | default('') | trim }} + when: >- + matrix_bot_meowlnir_bot_needs_update | bool + and ( + matrix_bot_meowlnir_bot_create_result.rc | default(1) != 0 + or (matrix_bot_meowlnir_bot_create_result.stdout_lines | default([]) | length == 0) + or (matrix_bot_meowlnir_bot_create_result.stdout_lines | last != '200') + ) + +- name: Determine which management rooms Meowlnir already has for this bot - {{ bot.username | quote }} + ansible.builtin.set_fact: + matrix_bot_meowlnir_bot_live_rooms: >- + {{ matrix_bot_meowlnir_bot_live.management_rooms | default([], true) | map(attribute='room_id') | list }} + +- name: Ensure Meowlnir management room created - {{ bot.username | quote }} + when: "bot.management_room_auto_create | bool and matrix_bot_meowlnir_bot_live_rooms | length == 0" + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/ensure_management_room_created.yml" + +- name: Ensure declared Meowlnir management rooms registered - {{ bot.username | quote }} + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/ensure_management_room_registered.yml" + with_items: "{{ bot.management_rooms }}" + loop_control: + loop_var: management_room diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_management_room_created.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_management_room_created.yml new file mode 100644 index 000000000..4d0036c55 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_management_room_created.yml @@ -0,0 +1,57 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# Only reached for bots with `management_room_auto_create` which do not have a management room yet. +# Meowlnir's own record of the bot's rooms is what makes this idempotent, so no state is kept on the Ansible side. + +# Recomputed here, because validation runs its own loop over all bots and would leave this holding the last one's value. +- name: Determine the effective initial managers for a Meowlnir bot - {{ bot.username | quote }} + ansible.builtin.set_fact: + matrix_bot_meowlnir_bot_initial_managers: "{{ bot.initial_managers | default(matrix_bot_meowlnir_initial_managers) }}" + +- name: Create a Meowlnir management room - {{ bot.username | quote }} + ansible.builtin.command: + cmd: >- + {{ matrix_bot_meowlnir_bin_path }}/meowlnir-create-management-room + {{ bot.username | quote }} + {{ matrix_bot_meowlnir_bot_initial_managers | map('quote') | join(' ') }} + register: matrix_bot_meowlnir_room_creation_result + # The script prints the new room's ID on success, so that is what tells us a room was actually created, not merely attempted. + changed_when: >- + matrix_bot_meowlnir_room_creation_result.rc == 0 + and (matrix_bot_meowlnir_room_creation_result.stdout | default('') | trim).startswith('!') + failed_when: false + +- name: Fail if the Meowlnir management room could not be created - {{ bot.username | quote }} + ansible.builtin.fail: + msg: >- + Creating a management room for the Meowlnir bot `{{ bot.username }}` failed. + {{ matrix_bot_meowlnir_room_creation_result.stdout | default('') | trim }} + {{ matrix_bot_meowlnir_room_creation_result.stderr | default('') | trim }} + when: >- + matrix_bot_meowlnir_room_creation_result.rc != 0 + or not (matrix_bot_meowlnir_room_creation_result.stdout | default('') | trim).startswith('!') + +- name: Register the created Meowlnir management room - {{ bot.username | quote }} + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/ensure_management_room_registered.yml" + vars: + management_room: + id: "{{ matrix_bot_meowlnir_room_creation_result.stdout | trim }}" + encrypted: "{{ matrix_bot_meowlnir_config_encryption_enable }}" + +- name: Report the created Meowlnir management room - {{ bot.username | quote }} + ansible.builtin.set_fact: + devture_playbook_runtime_messages_list: >- + {{ + devture_playbook_runtime_messages_list | default([]) + + + [ + "Note: created a management room (" ~ (matrix_bot_meowlnir_room_creation_result.stdout | trim) ~ + ") for the Meowlnir bot " ~ bot.username ~ " and invited " ~ + (matrix_bot_meowlnir_bot_initial_managers | join(", ")) ~ + " to it. Accept the invitation to start commanding the bot." + ] + }} diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_management_room_registered.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_management_room_registered.yml new file mode 100644 index 000000000..9b1b6773e --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/ensure_management_room_registered.yml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Build request body for Meowlnir management room - {{ management_room.id | quote }} + ansible.builtin.set_fact: + matrix_bot_meowlnir_management_room_body: >- + {{ + { + 'bot_username': bot.username, + 'encrypted': management_room.encrypted | bool, + } + }} + +- name: Ensure Meowlnir management room registered - {{ management_room.id | quote }} + ansible.builtin.command: + cmd: >- + {{ matrix_bot_meowlnir_bin_path }}/meowlnir-api + PUT /_meowlnir/v1/management_room/{{ management_room.id }} + {{ matrix_bot_meowlnir_management_room_body | to_json | quote }} + register: matrix_bot_meowlnir_management_room_result + # 201 means the room was newly registered, 200 that it already was. + changed_when: "matrix_bot_meowlnir_management_room_result.stdout_lines | default([]) | last | default('') == '201'" + failed_when: false + +- name: Fail if the Meowlnir management room could not be registered - {{ management_room.id | quote }} + ansible.builtin.fail: + msg: >- + Registering `{{ management_room.id }}` as a management room for the Meowlnir bot + `{{ bot.username }}` failed. + Meowlnir said: {{ matrix_bot_meowlnir_management_room_result.stdout | default('') | trim }} + {{ matrix_bot_meowlnir_management_room_result.stderr | default('') | trim }} + when: >- + matrix_bot_meowlnir_management_room_result.rc != 0 + or (matrix_bot_meowlnir_management_room_result.stdout_lines | default([]) | length == 0) + or (matrix_bot_meowlnir_management_room_result.stdout_lines | last not in ['200', '201']) diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/prune_bot.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/prune_bot.yml new file mode 100644 index 000000000..66fffc10f --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/prune_bot.yml @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# Only reached for bots which are no longer declared, and only after their management rooms have been de-registered — Meowlnir refuses to delete a bot which is still in use. + +- name: Remove Meowlnir bot - {{ live_bot.username | quote }} + ansible.builtin.command: + cmd: >- + {{ matrix_bot_meowlnir_bin_path }}/meowlnir-api + DELETE /_meowlnir/v1/bot/{{ live_bot.username }} + register: matrix_bot_meowlnir_bot_removal_result + changed_when: "matrix_bot_meowlnir_bot_removal_result.stdout_lines | default([]) | last | default('') == '200'" + failed_when: false + +- name: Fail if the Meowlnir bot could not be removed - {{ live_bot.username | quote }} + ansible.builtin.fail: + msg: >- + Removing the Meowlnir bot `{{ live_bot.username }}` failed. + Meowlnir said: {{ matrix_bot_meowlnir_bot_removal_result.stdout | default('') | trim }} + {{ matrix_bot_meowlnir_bot_removal_result.stderr | default('') | trim }} + when: >- + matrix_bot_meowlnir_bot_removal_result.rc != 0 + or (matrix_bot_meowlnir_bot_removal_result.stdout_lines | default([]) | length == 0) + or (matrix_bot_meowlnir_bot_removal_result.stdout_lines | last not in ['200', '404']) + +- name: Report the removed Meowlnir bot - {{ live_bot.username | quote }} + ansible.builtin.set_fact: + devture_playbook_runtime_messages_list: >- + {{ + devture_playbook_runtime_messages_list | default([]) + + + [ + "Note: the Meowlnir bot " ~ live_bot.username ~ " is no longer declared in matrix_bot_meowlnir_bots," ~ + " so Meowlnir has been told to forget it. Its Matrix user is not deactivated and remains in the rooms" ~ + " it had joined - clean that up separately if you want it gone for good." + ] + }} + when: "matrix_bot_meowlnir_bot_removal_result.stdout_lines | default([]) | last | default('') == '200'" diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/prune_bot_management_rooms.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/prune_bot_management_rooms.yml new file mode 100644 index 000000000..93400dfe7 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/prune_bot_management_rooms.yml @@ -0,0 +1,33 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Find the declaration for the Meowlnir bot - {{ live_bot.username | quote }} + ansible.builtin.set_fact: + matrix_bot_meowlnir_declared_bot: >- + {{ + (matrix_bot_meowlnir_bots | selectattr('username', 'equalto', live_bot.username) | list | first) + | default({}, true) + }} + +# Rooms created by the playbook are not declared anywhere, so bots which auto-create their management room are left alone. +# Bots which are no longer declared at all fall through to the empty declaration, meaning all of their rooms get removed — which is also what has to happen before the bot itself can be deleted. +- name: Determine which management rooms to remove - {{ live_bot.username | quote }} + ansible.builtin.set_fact: + matrix_bot_meowlnir_rooms_to_remove: >- + {{ + [] + if (matrix_bot_meowlnir_declared_bot.management_room_auto_create | default(false) | bool) + else ( + (live_bot.management_rooms | map(attribute='room_id') | list) + | difference(matrix_bot_meowlnir_declared_bot.management_rooms | default([], true) | map(attribute='id') | list) + ) + }} + +- name: Remove Meowlnir management rooms which are no longer declared - {{ live_bot.username | quote }} + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/prune_management_room.yml" + with_items: "{{ matrix_bot_meowlnir_rooms_to_remove }}" + loop_control: + loop_var: room_id_to_remove diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/prune_bots.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/prune_bots.yml new file mode 100644 index 000000000..521f58df8 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/prune_bots.yml @@ -0,0 +1,50 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# Makes the declared bot list authoritative: anything Meowlnir still knows about but which is no longer declared gets removed. +# Meowlnir's own records are re-read first, because the provisioning that just ran will have changed them. + +- name: Re-read Meowlnir's bots before pruning + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/read_meowlnir_state.yml" + +- name: Determine which Meowlnir bots are no longer declared + ansible.builtin.set_fact: + matrix_bot_meowlnir_undeclared_bots: >- + {{ + matrix_bot_meowlnir_live_bots + | rejectattr('username', 'in', matrix_bot_meowlnir_bots | map(attribute='username') | list) + | list + }} + +- name: Fail if pruning would remove every Meowlnir bot + ansible.builtin.fail: + msg: >- + No bots are declared in `matrix_bot_meowlnir_bots`, but Meowlnir still has + {{ matrix_bot_meowlnir_undeclared_bots | length }} of them + ({{ matrix_bot_meowlnir_undeclared_bots | map(attribute='username') | join(', ') }}). + Removing them would make Meowlnir forget them along with their management rooms, so the + playbook will not act on what is far more often a mistake (a commented-out block, an + unset variable) than an instruction. + If you really do want them all gone, set + `matrix_bot_meowlnir_bots_pruning_on_empty_roster_enabled: true`. + To stop the playbook managing bots at all, set + `matrix_bot_meowlnir_bots_pruning_enabled: false`. + when: >- + matrix_bot_meowlnir_bots | length == 0 + and matrix_bot_meowlnir_undeclared_bots | length > 0 + and not matrix_bot_meowlnir_bots_pruning_on_empty_roster_enabled | bool + +- name: Remove management rooms which are no longer declared + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/prune_bot_management_rooms.yml" + with_items: "{{ matrix_bot_meowlnir_live_bots }}" + loop_control: + loop_var: live_bot + +- name: Remove Meowlnir bots which are no longer declared + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/prune_bot.yml" + with_items: "{{ matrix_bot_meowlnir_undeclared_bots }}" + loop_control: + loop_var: live_bot diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/prune_management_room.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/prune_management_room.yml new file mode 100644 index 000000000..1dc9d57a1 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/prune_management_room.yml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Remove Meowlnir management room - {{ room_id_to_remove | quote }} + ansible.builtin.command: + cmd: >- + {{ matrix_bot_meowlnir_bin_path }}/meowlnir-api + DELETE /_meowlnir/v1/management_room/{{ room_id_to_remove }} + register: matrix_bot_meowlnir_room_removal_result + changed_when: "matrix_bot_meowlnir_room_removal_result.stdout_lines | default([]) | last | default('') == '200'" + failed_when: false + +- name: Fail if the Meowlnir management room could not be removed - {{ room_id_to_remove | quote }} + ansible.builtin.fail: + msg: >- + De-registering the Meowlnir management room `{{ room_id_to_remove }}` failed. + Meowlnir said: {{ matrix_bot_meowlnir_room_removal_result.stdout | default('') | trim }} + {{ matrix_bot_meowlnir_room_removal_result.stderr | default('') | trim }} + when: >- + matrix_bot_meowlnir_room_removal_result.rc != 0 + or (matrix_bot_meowlnir_room_removal_result.stdout_lines | default([]) | length == 0) + or (matrix_bot_meowlnir_room_removal_result.stdout_lines | last not in ['200', '404']) + +- name: Report the removed Meowlnir management room - {{ room_id_to_remove | quote }} + ansible.builtin.set_fact: + devture_playbook_runtime_messages_list: >- + {{ + devture_playbook_runtime_messages_list | default([]) + + + [ + "Note: the Meowlnir management room " ~ room_id_to_remove ~ " is no longer declared, so it has been de-registered." ~ + " The room itself still exists and the bot is still in it - Meowlnir simply no longer takes commands there." + ] + }} + when: "matrix_bot_meowlnir_room_removal_result.stdout_lines | default([]) | last | default('') == '200'" diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/read_meowlnir_state.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/read_meowlnir_state.yml new file mode 100644 index 000000000..e3912e046 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/read_meowlnir_state.yml @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# Meowlnir's own database is the source of truth for which bots and management rooms exist, and it can be queried, so the playbook keeps no state of its own about them. + +- name: Ask Meowlnir which bots currently exist + ansible.builtin.command: + cmd: "{{ matrix_bot_meowlnir_bin_path }}/meowlnir-api GET /_meowlnir/v1/bots" + register: matrix_bot_meowlnir_state_result + changed_when: false + failed_when: false + +- name: Fail if Meowlnir could not be asked which bots exist + ansible.builtin.fail: + msg: >- + Could not read the list of bots from Meowlnir. + Meowlnir said: {{ matrix_bot_meowlnir_state_result.stdout | default('') | trim }} + {{ matrix_bot_meowlnir_state_result.stderr | default('') | trim }} + when: >- + matrix_bot_meowlnir_state_result.rc != 0 + or (matrix_bot_meowlnir_state_result.stdout_lines | default([]) | length == 0) + or (matrix_bot_meowlnir_state_result.stdout_lines | last != '200') + +- name: Determine which bots and management rooms Meowlnir knows about + ansible.builtin.set_fact: + matrix_bot_meowlnir_live_bots: "{{ (matrix_bot_meowlnir_state_result.stdout_lines[:-1] | join('\n') | from_json).bots | default([], true) }}" diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/validate_bot.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/validate_bot.yml new file mode 100644 index 000000000..d43f6ded8 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/validate_bot.yml @@ -0,0 +1,90 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# These fields are required on every entry, so that a bot's setup can be read off the definition without knowing what the playbook would otherwise default to. +# +# The optional `initial_managers` is deliberately not among them: it only overrides an instance-wide default, and demanding it on every bot would defeat that default's purpose. +- name: Fail if a Meowlnir bot definition lacks required fields + ansible.builtin.fail: + msg: >- + A bot definition in `matrix_bot_meowlnir_bots` is missing the `{{ item }}` field. + Required on every entry: {{ matrix_bot_meowlnir_bot_required_fields | join(', ') }}. + Offending definition: {{ bot | to_json }} + when: "item not in bot" + with_items: "{{ matrix_bot_meowlnir_bot_required_fields }}" + +- name: Fail if a Meowlnir bot username is empty + ansible.builtin.fail: + msg: "A bot definition in `matrix_bot_meowlnir_bots` has an empty `username`: {{ bot | to_json }}" + when: "not bot.username" + +- name: Fail if Meowlnir bot username lacks the required prefix + ansible.builtin.fail: + msg: >- + The Meowlnir bot username `{{ bot.username }}` does not start with + `{{ matrix_bot_meowlnir_user_prefix }}`. Bot users need to fall within the user + namespace declared in Meowlnir's appservice registration file, or the homeserver + will refuse to let Meowlnir operate them. + Either rename the bot, or adjust `matrix_bot_meowlnir_user_prefix`. + when: "not bot.username.startswith(matrix_bot_meowlnir_user_prefix)" + +- name: Fail if a Meowlnir bot mixes management room auto-creation with declared rooms + ansible.builtin.fail: + msg: >- + The Meowlnir bot `{{ bot.username }}` has `management_room_auto_create` enabled, but + also declares `management_rooms`. These are mutually exclusive: either let the + playbook create a management room, or declare the rooms yourself. + when: "bot.management_room_auto_create | bool and bot.management_rooms | length > 0" + +- name: Fail if a Meowlnir bot has neither auto-created nor declared management rooms + ansible.builtin.fail: + msg: >- + The Meowlnir bot `{{ bot.username }}` declares no `management_rooms` and does not have + `management_room_auto_create` enabled, so there would be no room to command it from. + Either create a room yourself and declare it, or enable `management_room_auto_create`. + when: "not bot.management_room_auto_create | bool and bot.management_rooms | length == 0" + +- name: Fail if a Meowlnir bot declares `initial_managers` which is not a list + ansible.builtin.fail: + msg: >- + The Meowlnir bot `{{ bot.username }}` declares an `initial_managers` value which is not + a list. It needs to be a list of full Matrix user IDs (`@alice:example.com`), even when + there is only one. + Offending definition: {{ bot | to_json }} + when: "'initial_managers' in bot and (bot.initial_managers is string or bot.initial_managers is mapping or bot.initial_managers is not iterable)" + +# Omitting the key inherits the instance-wide default; declaring it empty means nobody, which is why `default()` is used here without its `boolean` argument. +- name: Determine the effective initial managers for a Meowlnir bot + ansible.builtin.set_fact: + matrix_bot_meowlnir_bot_initial_managers: "{{ bot.initial_managers | default(matrix_bot_meowlnir_initial_managers) }}" + +- name: Fail if Meowlnir management room auto-creation lacks an initial manager + ansible.builtin.fail: + msg: >- + The Meowlnir bot `{{ bot.username }}` has `management_room_auto_create` enabled, but no + initial managers are set, so nobody would be able to command the bot in the room that + gets created. + Either give the bot its own `initial_managers` list, or set + `matrix_bot_meowlnir_initial_managers` (or the `matrix_admin` variable it follows by + default), or disable `management_room_auto_create` and declare `management_rooms` + yourself. + when: "bot.management_room_auto_create | bool and matrix_bot_meowlnir_bot_initial_managers | length == 0" + +# Nothing downstream catches a bad value: the homeserver accepts invitations for users which do not exist, and on room versions supporting MSC4289 an invitee's standing in the room cannot be revoked afterwards. +# So a typo here is both silent and permanent. +- name: Fail if a Meowlnir initial manager is not a full Matrix user ID + ansible.builtin.fail: + msg: >- + `{{ item }}` is listed as an initial manager for the Meowlnir bot `{{ bot.username }}`, + but it is not a full Matrix user ID (`@alice:example.com`). + when: "not (item.startswith('@') and ':' in item)" + with_items: "{{ matrix_bot_meowlnir_bot_initial_managers }}" + +- name: Validate Meowlnir bot management rooms + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/validate_bot_management_room.yml" + with_items: "{{ bot.management_rooms }}" + loop_control: + loop_var: management_room diff --git a/roles/custom/matrix-bot-meowlnir/tasks/util/validate_bot_management_room.yml b/roles/custom/matrix-bot-meowlnir/tasks/util/validate_bot_management_room.yml new file mode 100644 index 000000000..e23f135ad --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/util/validate_bot_management_room.yml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Fail if a Meowlnir management room definition lacks required fields + ansible.builtin.fail: + msg: >- + A `management_rooms` entry for the Meowlnir bot `{{ bot.username }}` is missing the + `{{ item }}` field. All fields are required on every entry. + Offending definition: {{ management_room | to_json }} + when: "item not in management_room" + with_items: + - id + - encrypted + +- name: Fail if a Meowlnir management room ID does not look like a room ID + ansible.builtin.fail: + msg: >- + A `management_rooms` entry for the Meowlnir bot `{{ bot.username }}` has an `id` of + `{{ management_room.id }}`, which does not look like a room ID. + It needs to be a room ID (`!qporfwt:example.com`), not a room alias or a matrix.to URL. + You can find it in Element Web under the room's Settings -> Advanced. + when: "not management_room.id.startswith('!')" diff --git a/roles/custom/matrix-bot-meowlnir/tasks/validate_config.yml b/roles/custom/matrix-bot-meowlnir/tasks/validate_config.yml new file mode 100644 index 000000000..538928fc7 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/tasks/validate_config.yml @@ -0,0 +1,83 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Fail if required matrix-bot-meowlnir variables are undefined + ansible.builtin.fail: + msg: "The `{{ item.name }}` variable must be defined and have a non-null value." + with_items: + - {'name': 'matrix_bot_meowlnir_container_network', when: true} + - {'name': 'matrix_bot_meowlnir_config_homeserver_address', when: true} + - {'name': 'matrix_bot_meowlnir_config_homeserver_domain', when: true} + - {'name': 'matrix_bot_meowlnir_appservice_token', when: true} + - {'name': 'matrix_bot_meowlnir_homeserver_token', when: true} + - {'name': 'matrix_bot_meowlnir_config_meowlnir_management_secret', when: true} + - {'name': 'matrix_bot_meowlnir_config_meowlnir_data_secret', when: true} + - {'name': 'matrix_bot_meowlnir_config_antispam_secret', when: true} + - {'name': 'matrix_bot_meowlnir_config_encryption_pickle_key', when: true} + - {'name': 'matrix_bot_meowlnir_database_hostname', when: true} + - {'name': 'matrix_bot_meowlnir_database_password', when: true} + - {'name': 'matrix_bot_meowlnir_config_policy_server_signing_key', when: "{{ matrix_bot_meowlnir_policy_server_enabled }}"} + - {'name': 'matrix_bot_meowlnir_synapse_http_antispam_management_room_id', when: "{{ matrix_bot_meowlnir_synapse_http_antispam_enabled }}"} + when: "item.when | bool and (lookup('vars', item.name, default='') == '' or lookup('vars', item.name, default='') is none)" + +# Meowlnir re-runs its configuration upgrader in memory on every start, and `generate` is resolved to a fresh random value each time. +# A `generate` placeholder would therefore rotate the secret on every restart, invalidating the appservice registration or the encryption store. +- name: Fail if matrix-bot-meowlnir secrets are set to the literal "generate" + ansible.builtin.fail: + msg: >- + The `{{ item }}` variable is set to `generate`. Meowlnir would then mint a new + secret on every restart, because the playbook runs it with `--no-update` and its + configuration file is managed by Ansible. Set an explicit, stable value instead. + when: "lookup('vars', item, default='') == 'generate'" + with_items: + - matrix_bot_meowlnir_appservice_token + - matrix_bot_meowlnir_homeserver_token + - matrix_bot_meowlnir_config_meowlnir_management_secret + - matrix_bot_meowlnir_config_meowlnir_data_secret + - matrix_bot_meowlnir_config_antispam_secret + - matrix_bot_meowlnir_config_encryption_pickle_key + - matrix_bot_meowlnir_config_policy_server_signing_key + +# Bots exist only in Meowlnir's database and are created through its management API, so the whole roster and pruning path depends on that API being reachable. +# Disabling it is only coherent for an installation whose bots were created some other way, which means an empty roster and pruning turned off. +- name: Fail if the Meowlnir management API is disabled while the playbook manages bots + ansible.builtin.fail: + msg: >- + `matrix_bot_meowlnir_config_meowlnir_management_secret` is set to `disable`, which + turns Meowlnir's management API off. The playbook creates, updates and removes bots + through that API, so it cannot manage them while it is disabled. + Either give the secret a real value, or - if you manage Meowlnir's bots yourself - + leave `matrix_bot_meowlnir_bots_custom` empty and set + `matrix_bot_meowlnir_bots_pruning_enabled` to `false`. + when: >- + matrix_bot_meowlnir_config_meowlnir_management_secret == 'disable' + and (matrix_bot_meowlnir_bots | length > 0 or matrix_bot_meowlnir_bots_pruning_enabled | bool) + +- name: Fail if the bot user prefix and the localpart template disagree + ansible.builtin.fail: + msg: >- + `matrix_bot_meowlnir_config_meowlnir4all_localpart_template` must start with + `matrix_bot_meowlnir_user_prefix` ({{ matrix_bot_meowlnir_user_prefix }}), or the bots + Meowlnir creates will fall outside the user namespace declared in its appservice + registration file, and the homeserver will refuse to let it operate them. + when: "not matrix_bot_meowlnir_config_meowlnir4all_localpart_template.startswith(matrix_bot_meowlnir_user_prefix)" + +- name: Validate Meowlnir bot definitions + ansible.builtin.include_tasks: "{{ role_path }}/tasks/util/validate_bot.yml" + with_items: "{{ matrix_bot_meowlnir_bots }}" + loop_control: + loop_var: bot + +- name: Fail if Meowlnir and Draupnir both claim the synapse-http-antispam module + ansible.builtin.fail: + msg: >- + Both `matrix_bot_meowlnir_synapse_http_antispam_enabled` and + `matrix_bot_draupnir_config_web_synapseHTTPAntispam_enabled` are enabled. + The playbook wires the synapse-http-antispam module up to a single consumer, + so you need to pick one of the two. + when: + - matrix_bot_meowlnir_synapse_http_antispam_enabled | bool + - matrix_bot_draupnir_config_web_synapseHTTPAntispam_enabled | default(false) | bool diff --git a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2 b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2 new file mode 100755 index 000000000..b2af72684 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2 @@ -0,0 +1,56 @@ +#!/bin/sh +# Talks to Meowlnir's management API. +# +# The API is not published outside the container network, so requests are made from inside the container, which ships with curl. +# The management secret is read out of the live configuration file, so that it lives in exactly one place. +# +# Usage: meowlnir-api [JSON_BODY] +# Example: meowlnir-api GET /_meowlnir/v1/bots +# +# Prints the response body, followed by the HTTP status code on its own final line. + +set -eu + +CONFIG_FILE='{{ matrix_bot_meowlnir_config_path }}/config.yaml' +CONTAINER_NAME='matrix-bot-meowlnir' +API_BASE='http://localhost:{{ matrix_bot_meowlnir_config_meowlnir_port }}' +REQUEST_TIMEOUT='{{ matrix_bot_meowlnir_api_request_timeout_seconds }}' + +if [ $# -lt 2 ]; then + echo "Usage: $(basename "$0") [JSON_BODY]" >&2 + echo "Example: $(basename "$0") GET /_meowlnir/v1/bots" >&2 + exit 2 +fi + +method="$1" +api_path="$2" +body="${3:-}" + +# The configuration file is generated by Ansible, so its layout is predictable. +secret="$(awk '$1 == "management_secret:" { print $2; exit }' "$CONFIG_FILE" | sed 's/^"//; s/"$//')" + +if [ -z "$secret" ]; then + echo "Could not read management_secret from $CONFIG_FILE" >&2 + exit 1 +fi + +if [ "$secret" = 'disable' ]; then + echo "Meowlnir's management API is disabled (management_secret is set to 'disable')" >&2 + exit 1 +fi + +if [ -n "$body" ]; then + exec {{ devture_systemd_docker_base_host_command_docker }} exec "$CONTAINER_NAME" \ + curl -sS --max-time "$REQUEST_TIMEOUT" -X "$method" \ + -H "Authorization: Bearer $secret" \ + -H 'Content-Type: application/json' \ + -d "$body" \ + -w '\n%{http_code}' \ + "$API_BASE$api_path" +fi + +exec {{ devture_systemd_docker_base_host_command_docker }} exec "$CONTAINER_NAME" \ + curl -sS --max-time "$REQUEST_TIMEOUT" -X "$method" \ + -H "Authorization: Bearer $secret" \ + -w '\n%{http_code}' \ + "$API_BASE$api_path" diff --git a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2.license b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-api.j2.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-bots.j2 b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-bots.j2 new file mode 100755 index 000000000..bb2b95ab7 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-bots.j2 @@ -0,0 +1,21 @@ +#!/bin/sh +# Shows the bots Meowlnir knows about, together with their management rooms, protected rooms and watched policy lists. +# +# Usage: meowlnir-bots + +set -eu + +BIN_PATH='{{ matrix_bot_meowlnir_bin_path }}' +CONTAINER_NAME='matrix-bot-meowlnir' + +response="$("$BIN_PATH/meowlnir-api" GET /_meowlnir/v1/bots)" +status="$(printf '%s\n' "$response" | tail -n 1)" +body="$(printf '%s\n' "$response" | sed '$d')" + +if [ "$status" != '200' ]; then + echo "Meowlnir answered with HTTP $status:" >&2 + echo "$body" >&2 + exit 1 +fi + +printf '%s\n' "$body" | {{ devture_systemd_docker_base_host_command_docker }} exec -i "$CONTAINER_NAME" jq . diff --git a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-bots.j2.license b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-bots.j2.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-bots.j2.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-create-management-room.j2 b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-create-management-room.j2 new file mode 100755 index 000000000..361be2437 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-create-management-room.j2 @@ -0,0 +1,91 @@ +#!/bin/sh +# Creates a management room for a Meowlnir bot, with the given users able to command the bot there. +# +# The room is created by the bot itself, impersonated through the appservice token, so no human account's credentials are needed. +# +# The `trusted_private_chat` preset is what gives the invited users their standing, and it does the right thing on both old and new room versions: on rooms supporting MSC4289 every invitee becomes an additional creator, and on older ones each is given power level 100. +# Either way there is nothing for us to adjust afterwards. +# +# Usage: meowlnir-create-management-room ... +# +# Prints the created room's ID on success. + +set -eu + +CONFIG_FILE='{{ matrix_bot_meowlnir_config_path }}/config.yaml' +CONTAINER_NAME='matrix-bot-meowlnir' +HOMESERVER_ADDRESS='{{ matrix_bot_meowlnir_config_homeserver_address }}' +HOMESERVER_DOMAIN='{{ matrix_bot_meowlnir_config_homeserver_domain }}' +ROOM_NAME='{{ matrix_bot_meowlnir_management_room_name }}' +ROOM_TOPIC='{{ matrix_bot_meowlnir_management_room_topic | trim }}' +ENCRYPTED='{{ 'true' if matrix_bot_meowlnir_config_encryption_enable else 'false' }}' +REQUEST_TIMEOUT='{{ matrix_bot_meowlnir_api_request_timeout_seconds }}' + +if [ $# -lt 2 ]; then + echo "Usage: $(basename "$0") ..." >&2 + exit 2 +fi + +bot_localpart="$1" +shift +bot_mxid="@$bot_localpart:$HOMESERVER_DOMAIN" + +as_token="$(awk '$1 == "as_token:" { print $2; exit }' "$CONFIG_FILE" | sed 's/^"//; s/"$//')" + +if [ -z "$as_token" ]; then + echo "Could not read as_token from $CONFIG_FILE" >&2 + exit 1 +fi + +urlencode() { + printf '%s' "$1" | sed 's/%/%25/g; s/!/%21/g; s/:/%3A/g; s/@/%40/g; s/\$/%24/g; s/\//%2F/g' +} + +jq_run() { + {{ devture_systemd_docker_base_host_command_docker }} exec -i "$CONTAINER_NAME" jq "$@" +} + +if [ "$ENCRYPTED" = 'true' ]; then + initial_state='[{"type": "m.room.encryption", "state_key": "", "content": {"algorithm": "m.megolm.v1.aes-sha2"}}]' +else + initial_state='[]' +fi + +# Matrix user IDs cannot contain newlines, so splitting on them is safe here. +invitees="$(printf '%s\n' "$@" | jq_run -R -s 'split("\n") | map(select(length > 0))')" + +create_body="$(jq_run -n \ + --arg name "$ROOM_NAME" \ + --arg topic "$ROOM_TOPIC" \ + --argjson invitees "$invitees" \ + --argjson initial_state "$initial_state" \ + '{preset: "trusted_private_chat", name: $name, topic: $topic, invite: $invitees, initial_state: $initial_state}')" + +user_id_param="$(urlencode "$bot_mxid")" + +# Runs curl inside the container, because the homeserver is only reachable over the container network. +# Prints the body, with the HTTP status code on the final line. +response="$({{ devture_systemd_docker_base_host_command_docker }} exec "$CONTAINER_NAME" \ + curl -sS --max-time "$REQUEST_TIMEOUT" -X POST \ + -H "Authorization: Bearer $as_token" \ + -H 'Content-Type: application/json' \ + -d "$create_body" \ + -w '\n%{http_code}' \ + "$HOMESERVER_ADDRESS/_matrix/client/v3/createRoom?user_id=$user_id_param")" + +status="$(printf '%s\n' "$response" | tail -n 1)" + +if [ "$status" != '200' ]; then + echo "Creating the management room failed with HTTP $status:" >&2 + printf '%s\n' "$response" | sed '$d' >&2 + exit 1 +fi + +room_id="$(printf '%s\n' "$response" | sed '$d' | jq_run -r '.room_id')" + +if [ -z "$room_id" ] || [ "$room_id" = 'null' ]; then + echo 'The homeserver did not return a room ID' >&2 + exit 1 +fi + +printf '%s\n' "$room_id" diff --git a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-create-management-room.j2.license b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-create-management-room.j2.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-create-management-room.j2.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-whoami.j2 b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-whoami.j2 new file mode 100755 index 000000000..c0ac9d19e --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-whoami.j2 @@ -0,0 +1,31 @@ +#!/bin/sh +# Asks the homeserver who Meowlnir's appservice token belongs to. +# +# A `200` response proves the homeserver has Meowlnir's appservice registration loaded. +# A `401` (`M_UNKNOWN_TOKEN`) response means it is running without it — the condition that otherwise surfaces as Meowlnir endlessly logging "Failed to connect to homeserver". +# +# Usage: meowlnir-whoami +# +# Prints the response body, followed by the HTTP status code on its own final line. + +set -eu + +CONFIG_FILE='{{ matrix_bot_meowlnir_config_path }}/config.yaml' +CONTAINER_NAME='matrix-bot-meowlnir' +HOMESERVER_ADDRESS='{{ matrix_bot_meowlnir_config_homeserver_address }}' +REQUEST_TIMEOUT='{{ matrix_bot_meowlnir_api_request_timeout_seconds }}' + +# The configuration file is generated by Ansible, so its layout is predictable. +as_token="$(awk '$1 == "as_token:" { print $2; exit }' "$CONFIG_FILE" | sed 's/^"//; s/"$//')" + +if [ -z "$as_token" ]; then + echo "Could not read as_token from $CONFIG_FILE" >&2 + exit 1 +fi + +# Runs curl inside the container, because the homeserver is only reachable over the container network. +exec {{ devture_systemd_docker_base_host_command_docker }} exec "$CONTAINER_NAME" \ + curl -sS --max-time "$REQUEST_TIMEOUT" \ + -H "Authorization: Bearer $as_token" \ + -w '\n%{http_code}' \ + "$HOMESERVER_ADDRESS/_matrix/client/v3/account/whoami" diff --git a/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-whoami.j2.license b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-whoami.j2.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/bin/meowlnir-whoami.j2.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bot-meowlnir/templates/config.yaml.j2 b/roles/custom/matrix-bot-meowlnir/templates/config.yaml.j2 new file mode 100644 index 000000000..afeb73c2b --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/config.yaml.j2 @@ -0,0 +1,84 @@ +{# +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later +#} +{# + Note: this template is rendered, parsed as YAML, merged with + `matrix_bot_meowlnir_configuration_extension`, and dumped again. + Comments written here therefore do not reach the final configuration file. + + Secrets must always be rendered explicitly. Meowlnir re-runs its configuration + upgrader in memory on every start, so a literal `generate` value would produce a + brand new secret on each restart. +#} +homeserver: + address: {{ matrix_bot_meowlnir_config_homeserver_address | to_json }} + domain: {{ matrix_bot_meowlnir_config_homeserver_domain | to_json }} + +meowlnir: + id: {{ matrix_bot_meowlnir_appservice_id | to_json }} + as_token: {{ matrix_bot_meowlnir_appservice_token | to_json }} + hs_token: {{ matrix_bot_meowlnir_homeserver_token | to_json }} + + address: {{ matrix_bot_meowlnir_appservice_url | to_json }} + hostname: {{ matrix_bot_meowlnir_config_meowlnir_hostname | to_json }} + port: {{ matrix_bot_meowlnir_config_meowlnir_port | int }} + + management_secret: {{ matrix_bot_meowlnir_config_meowlnir_management_secret | to_json }} + data_secret: {{ matrix_bot_meowlnir_config_meowlnir_data_secret | to_json }} + federation_auth: {{ matrix_bot_meowlnir_config_meowlnir_federation_auth | to_json }} + dry_run: {{ matrix_bot_meowlnir_config_meowlnir_dry_run | to_json }} + untrusted: {{ matrix_bot_meowlnir_config_meowlnir_untrusted | to_json }} + + report_room: {{ matrix_bot_meowlnir_config_meowlnir_report_room | to_json if matrix_bot_meowlnir_config_meowlnir_report_room else 'null' }} + room_ban_room: {{ matrix_bot_meowlnir_config_meowlnir_room_ban_room | to_json if matrix_bot_meowlnir_config_meowlnir_room_ban_room else 'null' }} + load_all_room_hashes: {{ matrix_bot_meowlnir_config_meowlnir_load_all_room_hashes | to_json }} + + hacky_rule_filter: {{ matrix_bot_meowlnir_config_meowlnir_hacky_rule_filter | to_json }} + hacky_redact_patterns: {{ matrix_bot_meowlnir_config_meowlnir_hacky_redact_patterns | to_json }} + + admin_tokens: {{ matrix_bot_meowlnir_config_meowlnir_admin_tokens | to_json }} + +meowlnir4all: + admin_room: {{ matrix_bot_meowlnir_config_meowlnir4all_admin_room | to_json if matrix_bot_meowlnir_config_meowlnir4all_admin_room else 'null' }} + localpart_template: {{ matrix_bot_meowlnir_config_meowlnir4all_localpart_template | to_json }} + displayname: {{ matrix_bot_meowlnir_config_meowlnir4all_displayname | to_json if matrix_bot_meowlnir_config_meowlnir4all_displayname else 'null' }} + avatar_url: {{ matrix_bot_meowlnir_config_meowlnir4all_avatar_url | to_json if matrix_bot_meowlnir_config_meowlnir4all_avatar_url else 'null' }} + room_name: {{ matrix_bot_meowlnir_config_meowlnir4all_room_name | to_json }} + default_watched_lists: {{ matrix_bot_meowlnir_config_meowlnir4all_default_watched_lists | to_json }} + +antispam: + secret: {{ matrix_bot_meowlnir_config_antispam_secret | to_json }} + filter_local_invites: {{ matrix_bot_meowlnir_config_antispam_filter_local_invites | to_json }} + auto_reject_invites_token: {{ matrix_bot_meowlnir_config_antispam_auto_reject_invites_token | to_json if matrix_bot_meowlnir_config_antispam_auto_reject_invites_token else 'null' }} + notify_management_room: {{ matrix_bot_meowlnir_config_antispam_notify_management_room | to_json }} + block_invites_to: {{ matrix_bot_meowlnir_config_antispam_block_invites_to | to_json }} + +policy_server: + always_redact: {{ matrix_bot_meowlnir_config_policy_server_always_redact | to_json }} + signing_key: {{ matrix_bot_meowlnir_config_policy_server_signing_key | to_json }} + +encryption: + enable: {{ matrix_bot_meowlnir_config_encryption_enable | to_json }} + pickle_key: {{ matrix_bot_meowlnir_config_encryption_pickle_key | to_json }} + +database: + type: {{ matrix_bot_meowlnir_database_engine | to_json }} + uri: {{ matrix_bot_meowlnir_database_connection_string | to_json }} + max_open_conns: {{ matrix_bot_meowlnir_config_database_max_open_conns | int }} + max_idle_conns: {{ matrix_bot_meowlnir_config_database_max_idle_conns | int }} + max_conn_idle_time: {{ matrix_bot_meowlnir_config_database_max_conn_idle_time | to_json if matrix_bot_meowlnir_config_database_max_conn_idle_time else 'null' }} + max_conn_lifetime: {{ matrix_bot_meowlnir_config_database_max_conn_lifetime | to_json if matrix_bot_meowlnir_config_database_max_conn_lifetime else 'null' }} + +synapse_db: + type: postgres + uri: {{ matrix_bot_meowlnir_synapse_database_uri | to_json }} + max_open_conns: {{ matrix_bot_meowlnir_config_synapse_db_max_open_conns | int }} + max_idle_conns: {{ matrix_bot_meowlnir_config_synapse_db_max_idle_conns | int }} + max_conn_idle_time: {{ matrix_bot_meowlnir_config_synapse_db_max_conn_idle_time | to_json if matrix_bot_meowlnir_config_synapse_db_max_conn_idle_time else 'null' }} + max_conn_lifetime: {{ matrix_bot_meowlnir_config_synapse_db_max_conn_lifetime | to_json if matrix_bot_meowlnir_config_synapse_db_max_conn_lifetime else 'null' }} + +logging: + min_level: {{ matrix_bot_meowlnir_config_logging_min_level | to_json }} + writers: {{ matrix_bot_meowlnir_config_logging_writers | to_json }} diff --git a/roles/custom/matrix-bot-meowlnir/templates/labels.j2 b/roles/custom/matrix-bot-meowlnir/templates/labels.j2 new file mode 100644 index 000000000..958c67db5 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/labels.j2 @@ -0,0 +1,78 @@ +{# +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later +#} + +{% if matrix_bot_meowlnir_container_labels_traefik_enabled %} +traefik.enable=true + +{% if matrix_bot_meowlnir_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bot_meowlnir_container_labels_traefik_docker_network }} +{% endif %} + +traefik.http.services.matrix-bot-meowlnir.loadbalancer.server.port={{ matrix_bot_meowlnir_config_meowlnir_port }} + +{% if matrix_bot_meowlnir_config_reporting_enabled %} +############################################################ +# # +# Reports (/_matrix/client/../rooms/../report) # +# # +############################################################ + +{# Meowlnir serves these paths verbatim and applies CORS headers itself, #} +{# so no path-rewriting or CORS middleware is necessary here. #} + +traefik.http.routers.matrix-bot-meowlnir-reporting.rule={{ matrix_bot_meowlnir_container_labels_reporting_traefik_rule }} + +{% if matrix_bot_meowlnir_container_labels_reporting_traefik_priority | int > 0 %} +traefik.http.routers.matrix-bot-meowlnir-reporting.priority={{ matrix_bot_meowlnir_container_labels_reporting_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-bot-meowlnir-reporting.service=matrix-bot-meowlnir +traefik.http.routers.matrix-bot-meowlnir-reporting.entrypoints={{ matrix_bot_meowlnir_container_labels_reporting_traefik_entrypoints }} +traefik.http.routers.matrix-bot-meowlnir-reporting.tls={{ matrix_bot_meowlnir_container_labels_reporting_traefik_tls | to_json }} + +{% if matrix_bot_meowlnir_container_labels_reporting_traefik_tls %} +traefik.http.routers.matrix-bot-meowlnir-reporting.tls.certResolver={{ matrix_bot_meowlnir_container_labels_reporting_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Reports (/_matrix/client/../rooms/../report) # +# # +############################################################ +{% endif %} + +{% if matrix_bot_meowlnir_policy_server_enabled %} +############################################################ +# # +# Policy server (/_matrix/policy) # +# # +############################################################ + +{# Served on the federation endpoint, so that other servers in a room can reach it. #} + +traefik.http.routers.matrix-bot-meowlnir-policy-server.rule={{ matrix_bot_meowlnir_container_labels_policy_server_traefik_rule }} + +{% if matrix_bot_meowlnir_container_labels_policy_server_traefik_priority | int > 0 %} +traefik.http.routers.matrix-bot-meowlnir-policy-server.priority={{ matrix_bot_meowlnir_container_labels_policy_server_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-bot-meowlnir-policy-server.service=matrix-bot-meowlnir +traefik.http.routers.matrix-bot-meowlnir-policy-server.entrypoints={{ matrix_bot_meowlnir_container_labels_policy_server_traefik_entrypoints }} +traefik.http.routers.matrix-bot-meowlnir-policy-server.tls={{ matrix_bot_meowlnir_container_labels_policy_server_traefik_tls | to_json }} + +{% if matrix_bot_meowlnir_container_labels_policy_server_traefik_tls %} +traefik.http.routers.matrix-bot-meowlnir-policy-server.tls.certResolver={{ matrix_bot_meowlnir_container_labels_policy_server_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Policy server (/_matrix/policy) # +# # +############################################################ +{% endif %} +{% endif %} + +{{ matrix_bot_meowlnir_container_labels_traefik_labels_additional_labels }} diff --git a/roles/custom/matrix-registration/templates/systemd/matrix-registration.service.j2 b/roles/custom/matrix-bot-meowlnir/templates/systemd/matrix-bot-meowlnir.service.j2 similarity index 51% rename from roles/custom/matrix-registration/templates/systemd/matrix-registration.service.j2 rename to roles/custom/matrix-bot-meowlnir/templates/systemd/matrix-bot-meowlnir.service.j2 index 1a11abf10..4dc51b7e8 100644 --- a/roles/custom/matrix-registration/templates/systemd/matrix-registration.service.j2 +++ b/roles/custom/matrix-bot-meowlnir/templates/systemd/matrix-bot-meowlnir.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] -Description=matrix-registration -{% for service in matrix_registration_systemd_required_services_list %} +Description=Matrix Meowlnir moderation bot +{% for service in matrix_bot_meowlnir_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_registration_systemd_wanted_services_list %} +{% for service in matrix_bot_meowlnir_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -13,39 +13,42 @@ DefaultDependencies=no [Service] Type=simple Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-registration 2>/dev/null || true' -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-registration 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-bot-meowlnir 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-bot-meowlnir 2>/dev/null || true' ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --rm \ - --name=matrix-registration \ + --name=matrix-bot-meowlnir \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_registration_container_network }} \ - {% if matrix_registration_container_http_host_bind_port %} - -p {{ matrix_registration_container_http_host_bind_port }}:5000 \ + --read-only \ + --network={{ matrix_bot_meowlnir_container_network }} \ + {% if matrix_bot_meowlnir_container_http_host_bind_port %} + -p {{ matrix_bot_meowlnir_container_http_host_bind_port }}:{{ matrix_bot_meowlnir_config_meowlnir_port }} \ {% endif %} - --mount type=bind,src={{ matrix_registration_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_registration_data_path }},dst=/data \ - --label-file={{ matrix_registration_base_path }}/labels \ - {% for arg in matrix_registration_container_extra_arguments %} + --label-file={{ matrix_bot_meowlnir_base_path }}/labels \ + --mount type=bind,src={{ matrix_bot_meowlnir_data_path }},dst=/data \ + --mount type=bind,src={{ matrix_bot_meowlnir_config_path }},dst=/data/config,ro \ + {% for arg in matrix_bot_meowlnir_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_registration_container_image }} \ - serve + {{ matrix_bot_meowlnir_container_image }} \ + /usr/bin/meowlnir --config=/data/config/config.yaml --no-update -{% for network in matrix_registration_container_additional_networks %} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-registration +{% if matrix_bot_meowlnir_container_network != 'host' %} +{% for network in matrix_bot_meowlnir_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-meowlnir {% endfor %} +{% endif %} -ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-registration +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-meowlnir -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-registration 2>/dev/null || true' -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-registration 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-bot-meowlnir 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-bot-meowlnir 2>/dev/null || true' Restart=always RestartSec=30 -SyslogIdentifier=matrix-registration +SyslogIdentifier=matrix-bot-meowlnir [Install] WantedBy=multi-user.target diff --git a/roles/custom/matrix-bot-meowlnir/templates/systemd/matrix-bot-meowlnir.service.j2.license b/roles/custom/matrix-bot-meowlnir/templates/systemd/matrix-bot-meowlnir.service.j2.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/templates/systemd/matrix-bot-meowlnir.service.j2.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bot-meowlnir/vars/main.yml b/roles/custom/matrix-bot-meowlnir/vars/main.yml new file mode 100644 index 000000000..1e68e57f7 --- /dev/null +++ b/roles/custom/matrix-bot-meowlnir/vars/main.yml @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# The fields every entry in `matrix_bot_meowlnir_bots` must carry. +# +# Lives here, not in `defaults/main.yml`, because it describes the role's own expectations and is not something to override. +# `initial_managers` is deliberately absent — it is optional and falls back to `matrix_bot_meowlnir_initial_managers`. +matrix_bot_meowlnir_bot_required_fields: + - username + - displayname + - avatar_url + - management_room_auto_create + - management_rooms diff --git a/roles/custom/matrix-bot-mjolnir/defaults/main.yml b/roles/custom/matrix-bot-mjolnir/defaults/main.yml index 64e100454..badd5e907 100644 --- a/roles/custom/matrix-bot-mjolnir/defaults/main.yml +++ b/roles/custom/matrix-bot-mjolnir/defaults/main.yml @@ -26,7 +26,6 @@ matrix_bot_mjolnir_container_image: "{{ matrix_bot_mjolnir_container_image_regis matrix_bot_mjolnir_container_image_registry_prefix: "{{ 'localhost/' if matrix_bot_mjolnir_container_image_self_build else matrix_bot_mjolnir_container_image_registry_prefix_upstream }}" matrix_bot_mjolnir_container_image_registry_prefix_upstream: "{{ matrix_bot_mjolnir_container_image_registry_prefix_upstream_default }}" matrix_bot_mjolnir_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_bot_mjolnir_container_image_force_pull: "{{ matrix_bot_mjolnir_container_image.endswith(':latest') }}" matrix_bot_mjolnir_base_path: "{{ matrix_base_data_path }}/mjolnir" matrix_bot_mjolnir_config_path: "{{ matrix_bot_mjolnir_base_path }}/config" diff --git a/roles/custom/matrix-bot-mjolnir/tasks/setup_install.yml b/roles/custom/matrix-bot-mjolnir/tasks/setup_install.yml index 5ccf00a7d..bae12a370 100644 --- a/roles/custom/matrix-bot-mjolnir/tasks/setup_install.yml +++ b/roles/custom/matrix-bot-mjolnir/tasks/setup_install.yml @@ -28,17 +28,25 @@ when: "item.when | bool" - name: Ensure mjolnir Docker image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_bot_mjolnir_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_bot_mjolnir_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_mjolnir_container_image_force_pull }}" + pull: always when: "not matrix_bot_mjolnir_container_image_self_build | bool" register: matrix_bot_mjolnir_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_bot_mjolnir_container_image_pull_result is not failed +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure mjolnir repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bot_mjolnir_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bot_mjolnir_container_image_self_build | bool" + - name: Ensure mjolnir repository is present on self-build ansible.builtin.git: repo: "{{ matrix_bot_mjolnir_container_image_self_build_repo }}" @@ -51,15 +59,14 @@ when: "matrix_bot_mjolnir_container_image_self_build | bool" - name: Ensure mjolnir Docker image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_bot_mjolnir_container_image }}" - source: build - force_source: "{{ matrix_bot_mjolnir_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_bot_mjolnir_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_bot_mjolnir_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bot_mjolnir_git_pull_results.changed | bool else 'never' }}" when: "matrix_bot_mjolnir_container_image_self_build | bool" + register: matrix_bot_mjolnir_container_image_build_result - name: Ensure matrix-bot-mjolnir config installed ansible.builtin.copy: @@ -71,6 +78,7 @@ register: matrix_bot_mjolnir_config_result - name: Ensure matrix-bot-mjolnir container network is created + when: matrix_bot_mjolnir_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_bot_mjolnir_container_network }}" @@ -92,6 +100,7 @@ or matrix_bot_mjolnir_config_result.changed | default(false) or matrix_bot_mjolnir_systemd_service_result.changed | default(false) or matrix_bot_mjolnir_container_image_pull_result.changed | default(false) + or matrix_bot_mjolnir_container_image_build_result.changed | default(false) }} - name: Ensure matrix-bot-mjolnir.service restarted, if necessary diff --git a/roles/custom/matrix-bot-mjolnir/tasks/validate_config.yml b/roles/custom/matrix-bot-mjolnir/tasks/validate_config.yml index 66f582a18..53f6b1850 100644 --- a/roles/custom/matrix-bot-mjolnir/tasks/validate_config.yml +++ b/roles/custom/matrix-bot-mjolnir/tasks/validate_config.yml @@ -17,6 +17,7 @@ - {'old': 'matrix_bot_mjolnir_container_image_name_prefix', 'new': 'matrix_bot_mjolnir_container_image_registry_prefix'} - {'old': 'matrix_bot_mjolnir_docker_image', 'new': 'matrix_bot_mjolnir_container_image'} - {'old': 'matrix_bot_mjolnir_docker_image_force_pull', 'new': 'matrix_bot_mjolnir_container_image_force_pull'} + - {'old': 'matrix_bot_mjolnir_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - {'old': 'matrix_bot_mjolnir_docker_image_registry_prefix', 'new': 'matrix_bot_mjolnir_container_image_registry_prefix'} - {'old': 'matrix_bot_mjolnir_docker_image_registry_prefix_upstream', 'new': 'matrix_bot_mjolnir_container_image_registry_prefix_upstream'} - {'old': 'matrix_bot_mjolnir_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bot_mjolnir_container_image_registry_prefix_upstream_default'} diff --git a/roles/custom/matrix-bot-mjolnir/templates/systemd/matrix-bot-mjolnir.service.j2 b/roles/custom/matrix-bot-mjolnir/templates/systemd/matrix-bot-mjolnir.service.j2 index 03a49407e..840264c7e 100644 --- a/roles/custom/matrix-bot-mjolnir/templates/systemd/matrix-bot-mjolnir.service.j2 +++ b/roles/custom/matrix-bot-mjolnir/templates/systemd/matrix-bot-mjolnir.service.j2 @@ -32,9 +32,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {{ matrix_bot_mjolnir_container_image }} \ bot --mjolnir-config /data/config/production.yaml +{% if matrix_bot_mjolnir_container_network != 'host' %} {% for network in matrix_bot_mjolnir_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-mjolnir {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-mjolnir diff --git a/roles/custom/matrix-bridge-appservice-discord/defaults/main.yml b/roles/custom/matrix-bridge-appservice-discord/defaults/main.yml index e751371c6..440a7f409 100644 --- a/roles/custom/matrix-bridge-appservice-discord/defaults/main.yml +++ b/roles/custom/matrix-bridge-appservice-discord/defaults/main.yml @@ -15,84 +15,82 @@ # matrix-appservice-discord is a Matrix <-> Discord bridge # Project source code URL: https://github.com/matrix-org/matrix-appservice-discord -matrix_appservice_discord_enabled: false -matrix_appservice_discord_container_image_self_build: false +matrix_bridge_appservice_discord_enabled: false # renovate: datasource=docker depName=ghcr.io/matrix-org/matrix-appservice-discord -matrix_appservice_discord_version: v4.0.0 -matrix_appservice_discord_container_image: "{{ matrix_appservice_discord_container_image_registry_prefix }}matrix-org/matrix-appservice-discord:{{ matrix_appservice_discord_version }}" -matrix_appservice_discord_container_image_registry_prefix: "{{ 'localhost/' if matrix_appservice_discord_container_image_self_build else matrix_appservice_discord_container_image_registry_prefix_upstream }}" -matrix_appservice_discord_container_image_registry_prefix_upstream: "{{ matrix_appservice_discord_container_image_registry_prefix_upstream_default }}" -matrix_appservice_discord_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_appservice_discord_container_image_force_pull: "{{ matrix_appservice_discord_container_image.endswith(':latest') }}" +matrix_bridge_appservice_discord_version: v4.0.0 +matrix_bridge_appservice_discord_container_image: "{{ matrix_bridge_appservice_discord_container_image_registry_prefix }}matrix-org/matrix-appservice-discord:{{ matrix_bridge_appservice_discord_version }}" +matrix_bridge_appservice_discord_container_image_registry_prefix: "{{ matrix_bridge_appservice_discord_container_image_registry_prefix_upstream }}" +matrix_bridge_appservice_discord_container_image_registry_prefix_upstream: "{{ matrix_bridge_appservice_discord_container_image_registry_prefix_upstream_default }}" +matrix_bridge_appservice_discord_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_appservice_discord_base_path: "{{ matrix_base_data_path }}/appservice-discord" -matrix_appservice_discord_config_path: "{{ matrix_base_data_path }}/appservice-discord/config" -matrix_appservice_discord_data_path: "{{ matrix_base_data_path }}/appservice-discord/data" +matrix_bridge_appservice_discord_base_path: "{{ matrix_base_data_path }}/appservice-discord" +matrix_bridge_appservice_discord_config_path: "{{ matrix_base_data_path }}/appservice-discord/config" +matrix_bridge_appservice_discord_data_path: "{{ matrix_base_data_path }}/appservice-discord/data" # Get your own keys at https://discordapp.com/developers/applications/me/create -matrix_appservice_discord_client_id: '' -matrix_appservice_discord_bot_token: '' +matrix_bridge_appservice_discord_client_id: '' +matrix_bridge_appservice_discord_bot_token: '' -matrix_appservice_discord_appservice_token: '' -matrix_appservice_discord_homeserver_token: '' +matrix_bridge_appservice_discord_appservice_token: '' +matrix_bridge_appservice_discord_homeserver_token: '' -matrix_appservice_discord_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_appservice_discord_homeserver_domain: "{{ matrix_domain }}" # Controls whether the matrix-appservice-discord container exposes its HTTP port (tcp/9005 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:9005"), or empty string to not expose. -matrix_appservice_discord_container_http_host_bind_port: '' +matrix_bridge_appservice_discord_container_http_host_bind_port: '' -matrix_appservice_discord_container_network: "" +matrix_bridge_appservice_discord_container_network: "" -matrix_appservice_discord_container_additional_networks: "{{ matrix_appservice_discord_container_additional_networks_auto + matrix_appservice_discord_container_additional_networks_custom }}" -matrix_appservice_discord_container_additional_networks_auto: [] -matrix_appservice_discord_container_additional_networks_custom: [] +matrix_bridge_appservice_discord_container_additional_networks: "{{ matrix_bridge_appservice_discord_container_additional_networks_auto + matrix_bridge_appservice_discord_container_additional_networks_custom }}" +matrix_bridge_appservice_discord_container_additional_networks_auto: [] +matrix_bridge_appservice_discord_container_additional_networks_custom: [] # A list of extra arguments to pass to the container -matrix_appservice_discord_container_extra_arguments: [] +matrix_bridge_appservice_discord_container_extra_arguments: [] # List of systemd services that matrix-appservice-discord.service depends on. -matrix_appservice_discord_systemd_required_services_list: "{{ matrix_appservice_discord_systemd_required_services_list_default + matrix_appservice_discord_systemd_required_services_list_auto + matrix_appservice_discord_systemd_required_services_list_custom }}" -matrix_appservice_discord_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_appservice_discord_systemd_required_services_list_auto: [] -matrix_appservice_discord_systemd_required_services_list_custom: [] +matrix_bridge_appservice_discord_systemd_required_services_list: "{{ matrix_bridge_appservice_discord_systemd_required_services_list_default + matrix_bridge_appservice_discord_systemd_required_services_list_auto + matrix_bridge_appservice_discord_systemd_required_services_list_custom }}" +matrix_bridge_appservice_discord_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_appservice_discord_systemd_required_services_list_auto: [] +matrix_bridge_appservice_discord_systemd_required_services_list_custom: [] # List of systemd services that matrix-appservice-discord.service wants -matrix_appservice_discord_systemd_wanted_services_list: [] +matrix_bridge_appservice_discord_systemd_wanted_services_list: [] -matrix_appservice_discord_appservice_url: 'http://matrix-appservice-discord:9005' +matrix_bridge_appservice_discord_appservice_url: 'http://matrix-appservice-discord:9005' -matrix_appservice_discord_bridge_domain: "{{ matrix_domain }}" +matrix_bridge_appservice_discord_bridge_domain: "{{ matrix_domain }}" # As of right now, the homeserver URL must be a public URL. See below. -matrix_appservice_discord_bridge_homeserverUrl: "{{ matrix_homeserver_url }}" # noqa var-naming -matrix_appservice_discord_bridge_disablePresence: false # noqa var-naming -matrix_appservice_discord_bridge_enableSelfServiceBridging: false # noqa var-naming -matrix_appservice_discord_bridge_disablePortalBridging: false # noqa var-naming +matrix_bridge_appservice_discord_bridge_homeserverUrl: "{{ matrix_homeserver_url }}" # noqa var-naming +matrix_bridge_appservice_discord_bridge_disablePresence: false # noqa var-naming +matrix_bridge_appservice_discord_bridge_enableSelfServiceBridging: false # noqa var-naming +matrix_bridge_appservice_discord_bridge_disablePortalBridging: false # noqa var-naming # Database-related configuration fields. # # To use SQLite, stick to these defaults. # # To use Postgres: -# - change the engine (`matrix_appservice_discord_database_engine: 'postgres'`) -# - adjust your database credentials via the `matrix_appservice_discord_database_*` variables -matrix_appservice_discord_database_engine: 'sqlite' +# - change the engine (`matrix_bridge_appservice_discord_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_appservice_discord_database_*` variables +matrix_bridge_appservice_discord_database_engine: 'sqlite' -matrix_appservice_discord_sqlite_database_path_local: "{{ matrix_appservice_discord_data_path }}/discord.db" -matrix_appservice_discord_sqlite_database_path_in_container: "/data/discord.db" +matrix_bridge_appservice_discord_sqlite_database_path_local: "{{ matrix_bridge_appservice_discord_data_path }}/discord.db" +matrix_bridge_appservice_discord_sqlite_database_path_in_container: "/data/discord.db" -matrix_appservice_discord_database_username: 'matrix_appservice_discord' -matrix_appservice_discord_database_password: 'some-password' -matrix_appservice_discord_database_hostname: '' -matrix_appservice_discord_database_port: 5432 -matrix_appservice_discord_database_name: 'matrix_appservice_discord' +matrix_bridge_appservice_discord_database_username: 'matrix_appservice_discord' +matrix_bridge_appservice_discord_database_password: 'some-password' +matrix_bridge_appservice_discord_database_hostname: '' +matrix_bridge_appservice_discord_database_port: 5432 +matrix_bridge_appservice_discord_database_name: 'matrix_appservice_discord' # These 2 variables are what actually ends up in the bridge configuration. # It's best if you don't change them directly, but rather redefine the sub-variables that constitute them. -matrix_appservice_discord_database_filename: "{{ matrix_appservice_discord_sqlite_database_path_in_container }}" -matrix_appservice_discord_database_connString: 'postgresql://{{ matrix_appservice_discord_database_username }}:{{ matrix_appservice_discord_database_password }}@{{ matrix_appservice_discord_database_hostname }}:{{ matrix_appservice_discord_database_port }}/{{ matrix_appservice_discord_database_name }}' # noqa var-naming +matrix_bridge_appservice_discord_database_filename: "{{ matrix_bridge_appservice_discord_sqlite_database_path_in_container }}" +matrix_bridge_appservice_discord_database_connString: 'postgresql://{{ matrix_bridge_appservice_discord_database_username }}:{{ matrix_bridge_appservice_discord_database_password }}@{{ matrix_bridge_appservice_discord_database_hostname }}:{{ matrix_bridge_appservice_discord_database_port }}/{{ matrix_bridge_appservice_discord_database_name }}' # noqa var-naming # Tells whether the bot should make use of "Privileged Gateway Intents". @@ -101,44 +99,44 @@ matrix_appservice_discord_database_connString: 'postgresql://{{ matrix_appservic # by triggering all Intent checkboxes on a page like this: `https://discord.com/developers/applications/694448564151123988/bot` # # Learn more: https://gist.github.com/advaith1/e69bcc1cdd6d0087322734451f15aa2f -matrix_appservice_discord_auth_usePrivilegedIntents: false # noqa var-naming +matrix_bridge_appservice_discord_auth_usePrivilegedIntents: false # noqa var-naming -matrix_appservice_discord_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_appservice_discord_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_appservice_discord_configuration_extension_yaml: | +matrix_bridge_appservice_discord_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_appservice_discord_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_appservice_discord_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_appservice_discord_configuration_yaml`. + # completely redefining `matrix_bridge_appservice_discord_configuration_yaml`. -matrix_appservice_discord_configuration_extension: "{{ matrix_appservice_discord_configuration_extension_yaml | from_yaml if matrix_appservice_discord_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_appservice_discord_configuration_extension: "{{ matrix_bridge_appservice_discord_configuration_extension_yaml | from_yaml if matrix_bridge_appservice_discord_configuration_extension_yaml | from_yaml is mapping else {} }}" -matrix_appservice_discord_configuration: "{{ matrix_appservice_discord_configuration_yaml | from_yaml | combine(matrix_appservice_discord_configuration_extension, recursive=True) }}" +matrix_bridge_appservice_discord_configuration: "{{ matrix_bridge_appservice_discord_configuration_yaml | from_yaml | combine(matrix_bridge_appservice_discord_configuration_extension, recursive=True) }}" -matrix_appservice_discord_registration_yaml: | +matrix_bridge_appservice_discord_registration_yaml: | #jinja2: lstrip_blocks: True id: appservice-discord - as_token: "{{ matrix_appservice_discord_appservice_token }}" - hs_token: "{{ matrix_appservice_discord_homeserver_token }}" + as_token: "{{ matrix_bridge_appservice_discord_appservice_token }}" + hs_token: "{{ matrix_bridge_appservice_discord_homeserver_token }}" namespaces: users: - exclusive: true - regex: '@_discord_.*:{{ matrix_appservice_discord_homeserver_domain | regex_escape }}' + regex: '@_discord_.*:{{ matrix_bridge_appservice_discord_homeserver_domain | regex_escape }}' aliases: - exclusive: true - regex: '#_discord_.*:{{ matrix_appservice_discord_homeserver_domain | regex_escape }}' - url: {{ matrix_appservice_discord_appservice_url }} + regex: '#_discord_.*:{{ matrix_bridge_appservice_discord_homeserver_domain | regex_escape }}' + url: {{ matrix_bridge_appservice_discord_appservice_url }} sender_localpart: _discord_bot rate_limited: false protocols: - discord -matrix_appservice_discord_registration: "{{ matrix_appservice_discord_registration_yaml | from_yaml }}" +matrix_bridge_appservice_discord_registration: "{{ matrix_bridge_appservice_discord_registration_yaml | from_yaml }}" -# matrix_appservice_discord_restart_necessary controls whether the service +# matrix_bridge_appservice_discord_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -146,4 +144,4 @@ matrix_appservice_discord_registration: "{{ matrix_appservice_discord_registrati # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_appservice_discord_restart_necessary: false +matrix_bridge_appservice_discord_restart_necessary: false diff --git a/roles/custom/matrix-bridge-appservice-discord/tasks/main.yml b/roles/custom/matrix-bridge-appservice-discord/tasks/main.yml index 617a70849..8a2992b64 100644 --- a/roles/custom/matrix-bridge-appservice-discord/tasks/main.yml +++ b/roles/custom/matrix-bridge-appservice-discord/tasks/main.yml @@ -12,15 +12,15 @@ - install-all - install-appservice-discord block: - - when: matrix_appservice_discord_enabled | bool + - when: matrix_bridge_appservice_discord_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_appservice_discord_enabled | bool + - when: matrix_bridge_appservice_discord_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-appservice-discord block: - - when: not matrix_appservice_discord_enabled | bool + - when: not matrix_bridge_appservice_discord_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-appservice-discord/tasks/setup_install.yml b/roles/custom/matrix-bridge-appservice-discord/tasks/setup_install.yml index 6c122ecf5..810d3bd1b 100644 --- a/roles/custom/matrix-bridge-appservice-discord/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-appservice-discord/tasks/setup_install.yml @@ -14,42 +14,40 @@ --- - ansible.builtin.set_fact: - matrix_appservice_discord_migration_requires_restart: false + matrix_bridge_appservice_discord_migration_requires_restart: false -- when: "matrix_appservice_discord_database_engine == 'postgres'" +- when: "matrix_bridge_appservice_discord_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_appservice_discord_sqlite_database_path_local }}" - register: matrix_appservice_discord_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_appservice_discord_sqlite_database_path_local }}" + register: matrix_bridge_appservice_discord_sqlite_database_path_local_stat_result - - when: "matrix_appservice_discord_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_appservice_discord_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_appservice_discord_sqlite_database_path_local }}" - dst: "{{ matrix_appservice_discord_database_connString }}" + src: "{{ matrix_bridge_appservice_discord_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_appservice_discord_database_connString }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_appservice_discord_database_engine' + engine_variable_name: 'matrix_bridge_appservice_discord_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-appservice-discord.service'] - ansible.builtin.set_fact: - matrix_appservice_discord_migration_requires_restart: true + matrix_bridge_appservice_discord_migration_requires_restart: true - name: Ensure Appservice Discord image is pulled - community.docker.docker_image: - name: "{{ matrix_appservice_discord_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_appservice_discord_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_appservice_discord_container_image_force_pull }}" - register: matrix_appservice_discord_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_appservice_discord_container_image }}" + pull: always + register: matrix_bridge_appservice_discord_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_appservice_discord_container_image_pull_result is not failed + until: matrix_bridge_appservice_discord_container_image_pull_result is not failed - name: Ensure AppService Discord paths exist ansible.builtin.file: @@ -59,14 +57,14 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - "{{ matrix_appservice_discord_base_path }}" - - "{{ matrix_appservice_discord_config_path }}" - - "{{ matrix_appservice_discord_data_path }}" + - "{{ matrix_bridge_appservice_discord_base_path }}" + - "{{ matrix_bridge_appservice_discord_config_path }}" + - "{{ matrix_bridge_appservice_discord_data_path }}" - name: Check if an old database file already exists ansible.builtin.stat: - path: "{{ matrix_appservice_discord_base_path }}/discord.db" - register: matrix_appservice_discord_stat_db + path: "{{ matrix_bridge_appservice_discord_base_path }}/discord.db" + register: matrix_bridge_appservice_discord_stat_db - name: (Data relocation) Ensure matrix-appservice-discord.service is stopped ansible.builtin.service: @@ -75,54 +73,55 @@ enabled: false daemon_reload: true failed_when: false - when: "matrix_appservice_discord_stat_db.stat.exists" + when: "matrix_bridge_appservice_discord_stat_db.stat.exists" - name: (Data relocation) Move AppService Discord discord.db file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_appservice_discord_base_path }}/{{ item }} {{ matrix_appservice_discord_data_path }}/{{ item }}" - creates: "{{ matrix_appservice_discord_data_path }}/{{ item }}" - removes: "{{ matrix_appservice_discord_base_path }}/{{ item }}" + cmd: "mv {{ matrix_bridge_appservice_discord_base_path }}/{{ item }} {{ matrix_bridge_appservice_discord_data_path }}/{{ item }}" + creates: "{{ matrix_bridge_appservice_discord_data_path }}/{{ item }}" + removes: "{{ matrix_bridge_appservice_discord_base_path }}/{{ item }}" with_items: - discord.db - user-store.db - room-store.db - when: "matrix_appservice_discord_stat_db.stat.exists" + when: "matrix_bridge_appservice_discord_stat_db.stat.exists" - name: Ensure AppService Discord config.yaml installed ansible.builtin.copy: - content: "{{ matrix_appservice_discord_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_appservice_discord_config_path }}/config.yaml" + content: "{{ matrix_bridge_appservice_discord_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_appservice_discord_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_appservice_discord_config_result + register: matrix_bridge_appservice_discord_config_result - name: Ensure AppService Discord registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_appservice_discord_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_appservice_discord_config_path }}/registration.yaml" + content: "{{ matrix_bridge_appservice_discord_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_appservice_discord_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_appservice_discord_registration_result + register: matrix_bridge_appservice_discord_registration_result -# If `matrix_appservice_discord_client_id` hasn't changed, the same invite link would be generated. +# If `matrix_bridge_appservice_discord_client_id` hasn't changed, the same invite link would be generated. # We intentionally suppress Ansible changes. - name: Generate AppService Discord invite link ansible.builtin.shell: >- {{ devture_systemd_docker_base_host_command_docker }} run --rm --name matrix-appservice-discord-link-gen --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL - --mount type=bind,src={{ matrix_appservice_discord_config_path }},dst=/cfg + --mount type=bind,src={{ matrix_bridge_appservice_discord_config_path }},dst=/cfg -w /cfg - {{ matrix_appservice_discord_container_image }} + {{ matrix_bridge_appservice_discord_container_image }} /bin/sh -c "node /build/tools/addbot.js > /cfg/invite_link" changed_when: false - name: Ensure matrix-appservice-discord container network is created + when: matrix_bridge_appservice_discord_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_appservice_discord_container_network }}" + name: "{{ matrix_bridge_appservice_discord_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -131,17 +130,17 @@ src: "{{ role_path }}/templates/systemd/matrix-appservice-discord.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-discord.service" mode: '0644' - register: matrix_appservice_discord_systemd_service_result + register: matrix_bridge_appservice_discord_systemd_service_result - name: Determine whether matrix-appservice-discord needs a restart ansible.builtin.set_fact: - matrix_appservice_discord_restart_necessary: >- + matrix_bridge_appservice_discord_restart_necessary: >- {{ - matrix_appservice_discord_migration_requires_restart | default(false) - or matrix_appservice_discord_config_result.changed | default(false) - or matrix_appservice_discord_registration_result.changed | default(false) - or matrix_appservice_discord_systemd_service_result.changed | default(false) - or matrix_appservice_discord_container_image_pull_result.changed | default(false) + matrix_bridge_appservice_discord_migration_requires_restart | default(false) + or matrix_bridge_appservice_discord_config_result.changed | default(false) + or matrix_bridge_appservice_discord_registration_result.changed | default(false) + or matrix_bridge_appservice_discord_systemd_service_result.changed | default(false) + or matrix_bridge_appservice_discord_container_image_pull_result.changed | default(false) }} - name: Ensure matrix-appservice-discord.service restarted, if necessary @@ -149,4 +148,4 @@ name: "matrix-appservice-discord.service" state: restarted daemon_reload: true - when: "matrix_appservice_discord_migration_requires_restart | bool" + when: "matrix_bridge_appservice_discord_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-appservice-discord/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-appservice-discord/tasks/setup_uninstall.yml index fb164945c..68473e80a 100644 --- a/roles/custom/matrix-bridge-appservice-discord/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-appservice-discord/tasks/setup_uninstall.yml @@ -9,9 +9,9 @@ - name: Check existence of matrix-appservice-discord service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-discord.service" - register: matrix_appservice_discord_service_stat + register: matrix_bridge_appservice_discord_service_stat -- when: matrix_appservice_discord_service_stat.stat.exists | bool +- when: matrix_bridge_appservice_discord_service_stat.stat.exists | bool block: - name: Ensure matrix-appservice-discord is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-appservice-discord/tasks/validate_config.yml b/roles/custom/matrix-bridge-appservice-discord/tasks/validate_config.yml index d70963e26..3d3bd4876 100644 --- a/roles/custom/matrix-bridge-appservice-discord/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-appservice-discord/tasks/validate_config.yml @@ -12,13 +12,15 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_appservice_discord_container_expose_client_server_api_port', 'new': ''} - - {'old': 'matrix_appservice_discord_container_image_name_prefix', 'new': 'matrix_appservice_discord_container_image_registry_prefix'} - - {'old': 'matrix_appservice_discord_docker_image', 'new': 'matrix_appservice_discord_container_image'} - - {'old': 'matrix_appservice_discord_docker_image_force_pull', 'new': 'matrix_appservice_discord_container_image_force_pull'} - - {'old': 'matrix_appservice_discord_docker_image_registry_prefix', 'new': 'matrix_appservice_discord_container_image_registry_prefix'} - - {'old': 'matrix_appservice_discord_docker_image_registry_prefix_upstream', 'new': 'matrix_appservice_discord_container_image_registry_prefix_upstream'} - - {'old': 'matrix_appservice_discord_docker_image_registry_prefix_upstream_default', 'new': 'matrix_appservice_discord_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_appservice_discord_container_expose_client_server_api_port', 'new': ''} + - {'old': 'matrix_bridge_appservice_discord_container_image_name_prefix', 'new': 'matrix_bridge_appservice_discord_container_image_registry_prefix'} + - {'old': 'matrix_bridge_appservice_discord_docker_image', 'new': 'matrix_bridge_appservice_discord_container_image'} + - {'old': 'matrix_bridge_appservice_discord_docker_image_force_pull', 'new': 'matrix_bridge_appservice_discord_container_image_force_pull'} + - {'old': 'matrix_bridge_appservice_discord_docker_image_registry_prefix', 'new': 'matrix_bridge_appservice_discord_container_image_registry_prefix'} + - {'old': 'matrix_bridge_appservice_discord_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_appservice_discord_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_appservice_discord_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_appservice_discord_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_appservice_discord_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_appservice_discord_container_image_self_build', 'new': ' (self-building was never actually implemented for this role, so enabling it only led to image pull failures; the prebuilt image is amd64-only, so on other architectures consider the mautrix-discord bridge instead)'} - name: Fail if required appservice-discord settings not defined ansible.builtin.fail: @@ -26,15 +28,15 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_appservice_discord_client_id', when: true} - - {'name': 'matrix_appservice_discord_bot_token', when: true} - - {'name': 'matrix_appservice_discord_appservice_token', when: true} - - {'name': 'matrix_appservice_discord_homeserver_token', when: true} - - {'name': 'matrix_appservice_discord_homeserver_domain', when: true} - - {'name': 'matrix_appservice_discord_container_network', when: true} - - {'name': 'matrix_appservice_discord_database_hostname', when: "{{ matrix_appservice_discord_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_appservice_discord_client_id', when: true} + - {'name': 'matrix_bridge_appservice_discord_bot_token', when: true} + - {'name': 'matrix_bridge_appservice_discord_appservice_token', when: true} + - {'name': 'matrix_bridge_appservice_discord_homeserver_token', when: true} + - {'name': 'matrix_bridge_appservice_discord_homeserver_domain', when: true} + - {'name': 'matrix_bridge_appservice_discord_container_network', when: true} + - {'name': 'matrix_bridge_appservice_discord_database_hostname', when: "{{ matrix_bridge_appservice_discord_database_engine == 'postgres' }}"} - name: Require a valid database engine ansible.builtin.fail: - msg: "`matrix_appservice_discord_database_engine` needs to be either 'sqlite' or 'postgres'" - when: "matrix_appservice_discord_database_engine not in ['sqlite', 'postgres']" + msg: "`matrix_bridge_appservice_discord_database_engine` needs to be either 'sqlite' or 'postgres'" + when: "matrix_bridge_appservice_discord_database_engine not in ['sqlite', 'postgres']" diff --git a/roles/custom/matrix-bridge-appservice-discord/templates/config.yaml.j2 b/roles/custom/matrix-bridge-appservice-discord/templates/config.yaml.j2 index 63c45d020..138039cfd 100644 --- a/roles/custom/matrix-bridge-appservice-discord/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-appservice-discord/templates/config.yaml.j2 @@ -1,10 +1,10 @@ #jinja2: lstrip_blocks: True bridge: # Domain part of the bridge, e.g. matrix.org - domain: {{ matrix_appservice_discord_bridge_domain|to_json }} + domain: {{ matrix_bridge_appservice_discord_bridge_domain|to_json }} # This should be your publicly facing URL because Discord may use it to # fetch media from the media store. - homeserverUrl: {{ matrix_appservice_discord_bridge_homeserverUrl|to_json }} + homeserverUrl: {{ matrix_bridge_appservice_discord_bridge_homeserverUrl|to_json }} # Interval at which to process users in the 'presence queue'. If you have # 5 users, one user will be processed every 500 milliseconds according to the # value below. This has a minimum value of 250. @@ -13,17 +13,17 @@ bridge: presenceInterval: 500 # Disable setting presence for 'ghost users' which means Discord users on Matrix # will not be shown as away or online. - disablePresence: {{ matrix_appservice_discord_bridge_disablePresence|to_json }} + disablePresence: {{ matrix_bridge_appservice_discord_bridge_disablePresence|to_json }} # Disable sending typing notifications when somebody on Discord types. disableTypingNotifications: false # Disable deleting messages on Discord if a message is redacted on Matrix. disableDeletionForwarding: false # Disable portal bridging, where Matrix users can search for unbridged Discord # rooms on their Matrix server. - disablePortalBridging: {{ matrix_appservice_discord_bridge_disablePortalBridging|to_json }} + disablePortalBridging: {{ matrix_bridge_appservice_discord_bridge_disablePortalBridging|to_json }} # Enable users to bridge rooms using !discord commands. See # https://t2bot.io/discord for instructions. - enableSelfServiceBridging: {{ matrix_appservice_discord_bridge_enableSelfServiceBridging|to_json }} + enableSelfServiceBridging: {{ matrix_bridge_appservice_discord_bridge_enableSelfServiceBridging|to_json }} # Disable sending of read receipts for Matrix events which have been # successfully bridged to Discord. disableReadReceipts: false @@ -41,11 +41,11 @@ bridge: invalidTokenMessage: 'Your Discord bot token seems to be invalid, and the bridge cannot function. Please update it in your bridge settings and restart the bridge' # Authentication configuration for the discord bot. auth: - clientID: {{ matrix_appservice_discord_client_id | string|to_json }} - botToken: {{ matrix_appservice_discord_bot_token|to_json }} + clientID: {{ matrix_bridge_appservice_discord_client_id | string|to_json }} + botToken: {{ matrix_bridge_appservice_discord_bot_token|to_json }} # You must enable "Privileged Gateway Intents" in your bot settings on discord.com (e.g. https://discord.com/developers/applications/12345/bot) # for this to work - usePrivilegedIntents: {{ matrix_appservice_discord_auth_usePrivilegedIntents|to_json }} + usePrivilegedIntents: {{ matrix_bridge_appservice_discord_auth_usePrivilegedIntents|to_json }} logging: # What level should the logger output to the console at. console: "warn" # Valid values: silent, error, warn, http, info, verbose, silly @@ -67,10 +67,10 @@ database: # If you are migrating, see https://github.com/matrix-org/matrix-appservice-discord/blob/master/docs/howto.md#migrate-to-postgres-from-sqlite # WARNING: You will almost certainly be fine with sqlite unless your bridge # is in heavy demand and you suffer from IO slowness. - {% if matrix_appservice_discord_database_engine == 'sqlite' %} - filename: {{ matrix_appservice_discord_database_filename|to_json }} + {% if matrix_bridge_appservice_discord_database_engine == 'sqlite' %} + filename: {{ matrix_bridge_appservice_discord_database_filename|to_json }} {% else %} - connString: {{ matrix_appservice_discord_database_connString|to_json }} + connString: {{ matrix_bridge_appservice_discord_database_connString|to_json }} {% endif %} room: # Set the default visibility of alias rooms, defaults to "public". diff --git a/roles/custom/matrix-bridge-appservice-discord/templates/systemd/matrix-appservice-discord.service.j2 b/roles/custom/matrix-bridge-appservice-discord/templates/systemd/matrix-appservice-discord.service.j2 index 238e72cb3..0d7beae30 100644 --- a/roles/custom/matrix-bridge-appservice-discord/templates/systemd/matrix-appservice-discord.service.j2 +++ b/roles/custom/matrix-bridge-appservice-discord/templates/systemd/matrix-appservice-discord.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Appservice Discord bridge -{% for service in matrix_appservice_discord_systemd_required_services_list %} +{% for service in matrix_bridge_appservice_discord_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_appservice_discord_systemd_wanted_services_list %} +{% for service in matrix_bridge_appservice_discord_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,21 +22,23 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_appservice_discord_container_network }} \ - {% if matrix_appservice_discord_container_http_host_bind_port %} - -p {{ matrix_appservice_discord_container_http_host_bind_port }}:9005 \ + --network={{ matrix_bridge_appservice_discord_container_network }} \ + {% if matrix_bridge_appservice_discord_container_http_host_bind_port %} + -p {{ matrix_bridge_appservice_discord_container_http_host_bind_port }}:9005 \ {% endif %} - --mount type=bind,src={{ matrix_appservice_discord_config_path }},dst=/cfg \ - --mount type=bind,src={{ matrix_appservice_discord_data_path }},dst=/data \ - {% for arg in matrix_appservice_discord_container_extra_arguments %} + --mount type=bind,src={{ matrix_bridge_appservice_discord_config_path }},dst=/cfg \ + --mount type=bind,src={{ matrix_bridge_appservice_discord_data_path }},dst=/data \ + {% for arg in matrix_bridge_appservice_discord_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_appservice_discord_container_image }} \ + {{ matrix_bridge_appservice_discord_container_image }} \ node /build/src/discordas.js -p 9005 -c /cfg/config.yaml -f /cfg/registration.yaml -{% for network in matrix_appservice_discord_container_additional_networks %} +{% if matrix_bridge_appservice_discord_container_network != 'host' %} +{% for network in matrix_bridge_appservice_discord_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-appservice-discord {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-appservice-discord diff --git a/roles/custom/matrix-bridge-appservice-irc/defaults/main.yml b/roles/custom/matrix-bridge-appservice-irc/defaults/main.yml index ac1f03261..692edd6dd 100644 --- a/roles/custom/matrix-bridge-appservice-irc/defaults/main.yml +++ b/roles/custom/matrix-bridge-appservice-irc/defaults/main.yml @@ -23,71 +23,70 @@ # Matrix Appservice IRC is a Matrix <-> IRC bridge # Project source code URL: https://github.com/matrix-org/matrix-appservice-irc -matrix_appservice_irc_enabled: true +matrix_bridge_appservice_irc_enabled: true -matrix_appservice_irc_container_image_self_build: false -matrix_appservice_irc_container_repo: "https://github.com/matrix-org/matrix-appservice-irc.git" -matrix_appservice_irc_container_repo_version: "{{ 'master' if matrix_appservice_irc_version == 'latest' else matrix_appservice_irc_version }}" -matrix_appservice_irc_container_src_files_path: "{{ matrix_base_data_path }}/appservice-irc/docker-src" +matrix_bridge_appservice_irc_container_image_self_build: false +matrix_bridge_appservice_irc_container_repo: "https://github.com/matrix-org/matrix-appservice-irc.git" +matrix_bridge_appservice_irc_container_repo_version: "{{ 'master' if matrix_bridge_appservice_irc_version == 'latest' else matrix_bridge_appservice_irc_version }}" +matrix_bridge_appservice_irc_container_src_files_path: "{{ matrix_base_data_path }}/appservice-irc/docker-src" -# matrix_appservice_irc_version used to contain the full Docker image tag (e.g. `release-X.X.X`). +# matrix_bridge_appservice_irc_version used to contain the full Docker image tag (e.g. `release-X.X.X`). # It's a bare version number now. We try to somewhat retain compatibility below. # renovate: datasource=docker depName=docker.io/matrixdotorg/matrix-appservice-irc -matrix_appservice_irc_version: 4.0.0 -matrix_appservice_irc_container_image: "{{ matrix_appservice_irc_container_image_registry_prefix }}matrixdotorg/matrix-appservice-irc:{{ matrix_appservice_irc_container_image_tag }}" -matrix_appservice_irc_container_image_registry_prefix: "{{ 'localhost/' if matrix_appservice_irc_container_image_self_build else matrix_appservice_irc_container_image_registry_prefix_upstream }}" -matrix_appservice_irc_container_image_registry_prefix_upstream: "{{ matrix_appservice_irc_container_image_registry_prefix_upstream_default }}" -matrix_appservice_irc_container_image_registry_prefix_upstream_default: docker.io/ -matrix_appservice_irc_container_image_tag: "{{ 'latest' if matrix_appservice_irc_version == 'latest' else ('release-' + matrix_appservice_irc_version) }}" -matrix_appservice_irc_container_image_force_pull: "{{ matrix_appservice_irc_container_image.endswith(':latest') }}" +matrix_bridge_appservice_irc_version: 4.0.0 +matrix_bridge_appservice_irc_container_image: "{{ matrix_bridge_appservice_irc_container_image_registry_prefix }}matrixdotorg/matrix-appservice-irc:{{ matrix_bridge_appservice_irc_container_image_tag }}" +matrix_bridge_appservice_irc_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_appservice_irc_container_image_self_build else matrix_bridge_appservice_irc_container_image_registry_prefix_upstream }}" +matrix_bridge_appservice_irc_container_image_registry_prefix_upstream: "{{ matrix_bridge_appservice_irc_container_image_registry_prefix_upstream_default }}" +matrix_bridge_appservice_irc_container_image_registry_prefix_upstream_default: docker.io/ +matrix_bridge_appservice_irc_container_image_tag: "{{ 'latest' if matrix_bridge_appservice_irc_version == 'latest' else ('release-' + matrix_bridge_appservice_irc_version) }}" -matrix_appservice_irc_base_path: "{{ matrix_base_data_path }}/appservice-irc" -matrix_appservice_irc_config_path: "{{ matrix_appservice_irc_base_path }}/config" -matrix_appservice_irc_data_path: "{{ matrix_appservice_irc_base_path }}/data" +matrix_bridge_appservice_irc_base_path: "{{ matrix_base_data_path }}/appservice-irc" +matrix_bridge_appservice_irc_config_path: "{{ matrix_bridge_appservice_irc_base_path }}/config" +matrix_bridge_appservice_irc_data_path: "{{ matrix_bridge_appservice_irc_base_path }}/data" -matrix_appservice_irc_homeserver_url: "" -matrix_appservice_irc_homeserver_domain: '{{ matrix_domain }}' +matrix_bridge_appservice_irc_homeserver_url: "" +matrix_bridge_appservice_irc_homeserver_domain: '{{ matrix_domain }}' # ircService.mediaProxy configuration for serving publicly accessible URLs to authenticated Matrix media -matrix_appservice_irc_ircService_mediaProxy_bindPort: 11111 # noqa var-naming -matrix_appservice_irc_ircService_mediaProxy_publicUrl_scheme: https # noqa var-naming -matrix_appservice_irc_ircService_mediaProxy_publicUrl_hostname: '{{ matrix_server_fqn_matrix }}' # noqa var-naming -matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix: '/irc/' # noqa var-naming -matrix_appservice_irc_ircService_mediaProxy_publicUrl: "{{ matrix_appservice_irc_ircService_mediaProxy_publicUrl_scheme }}://{{ matrix_appservice_irc_ircService_mediaProxy_publicUrl_hostname }}{{ matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix }}" # noqa var-naming - -matrix_appservice_irc_homeserver_enablePresence: true # noqa var-naming -matrix_appservice_irc_appservice_address: 'http://matrix-appservice-irc:9999' - -matrix_appservice_irc_database_engine: nedb -matrix_appservice_irc_database_username: matrix_appservice_irc -matrix_appservice_irc_database_password: 'some-password' -matrix_appservice_irc_database_hostname: '' -matrix_appservice_irc_database_port: 5432 -matrix_appservice_irc_database_name: matrix_appservice_irc -matrix_appservice_irc_database_sslmode: disable +matrix_bridge_appservice_irc_ircService_mediaProxy_bindPort: 11111 # noqa var-naming +matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_scheme: https # noqa var-naming +matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_hostname: '{{ matrix_server_fqn_matrix }}' # noqa var-naming +matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix: '/irc/' # noqa var-naming +matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl: "{{ matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_scheme }}://{{ matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_hostname }}{{ matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix }}" # noqa var-naming + +matrix_bridge_appservice_irc_homeserver_enablePresence: true # noqa var-naming +matrix_bridge_appservice_irc_appservice_address: 'http://matrix-appservice-irc:9999' + +matrix_bridge_appservice_irc_database_engine: nedb +matrix_bridge_appservice_irc_database_username: matrix_appservice_irc +matrix_bridge_appservice_irc_database_password: 'some-password' +matrix_bridge_appservice_irc_database_hostname: '' +matrix_bridge_appservice_irc_database_port: 5432 +matrix_bridge_appservice_irc_database_name: matrix_appservice_irc +matrix_bridge_appservice_irc_database_sslmode: disable # The name of the container network to use when importing a NeDB database into Postgres. # For Postgres not working in a container, this can be left empty. -matrix_appservice_irc_database_container_network: '' +matrix_bridge_appservice_irc_database_container_network: '' # This is just the Postgres connection string, if Postgres is used. -# Naming clashes with `matrix_appservice_irc_database_connectionString` somewhat. -matrix_appservice_irc_database_connection_string: 'postgresql://{{ matrix_appservice_irc_database_username }}:{{ matrix_appservice_irc_database_password }}@{{ matrix_appservice_irc_database_hostname }}:{{ matrix_appservice_irc_database_port }}/{{ matrix_appservice_irc_database_name }}?sslmode={{ matrix_appservice_irc_database_sslmode }}' +# Naming clashes with `matrix_bridge_appservice_irc_database_connectionString` somewhat. +matrix_bridge_appservice_irc_database_connection_string: 'postgresql://{{ matrix_bridge_appservice_irc_database_username }}:{{ matrix_bridge_appservice_irc_database_password }}@{{ matrix_bridge_appservice_irc_database_hostname }}:{{ matrix_bridge_appservice_irc_database_port }}/{{ matrix_bridge_appservice_irc_database_name }}?sslmode={{ matrix_bridge_appservice_irc_database_sslmode }}' # This is what actually goes into `database.connectionString` for the bridge. -matrix_appservice_irc_database_connectionString: |- # noqa var-naming +matrix_bridge_appservice_irc_database_connectionString: |- # noqa var-naming {{ { 'nedb': 'nedb:///data', - 'postgres': matrix_appservice_irc_database_connection_string, - }[matrix_appservice_irc_database_engine] + 'postgres': matrix_bridge_appservice_irc_database_connection_string, + }[matrix_bridge_appservice_irc_database_engine] }} -matrix_appservice_irc_ircService_servers: [] # noqa var-naming +matrix_bridge_appservice_irc_ircService_servers: [] # noqa var-naming -# Example of `matrix_appservice_irc_ircService_servers` with one server (and all its options): +# Example of `matrix_bridge_appservice_irc_ircService_servers` with one server (and all its options): # -# matrix_appservice_irc_ircService_servers: +# matrix_bridge_appservice_irc_ircService_servers: # # The address of the server to connect to. # irc.example.com: # # A human-readable short name. This is used to label IRC status rooms @@ -472,68 +471,68 @@ matrix_appservice_irc_ircService_servers: [] # noqa var-naming # Controls whether the matrix-appservice-irc container exposes its HTTP port (tcp/9999 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:9999"), or empty string to not expose. -matrix_appservice_irc_container_http_host_bind_port: '' +matrix_bridge_appservice_irc_container_http_host_bind_port: '' # Controls whether the matrix-appservice-irc container exposes its media proxy HTTP port. # # Takes an ":" or "" value (e.g. "127.0.0.1:11111"), or empty string to not expose. -matrix_appservice_irc_container_media_proxy_host_bind_port: '' +matrix_bridge_appservice_irc_container_media_proxy_host_bind_port: '' -matrix_appservice_irc_container_network: "" +matrix_bridge_appservice_irc_container_network: "" -matrix_appservice_irc_container_additional_networks: "{{ matrix_appservice_irc_container_additional_networks_auto + matrix_appservice_irc_container_additional_networks_custom }}" -matrix_appservice_irc_container_additional_networks_auto: [] -matrix_appservice_irc_container_additional_networks_custom: [] +matrix_bridge_appservice_irc_container_additional_networks: "{{ matrix_bridge_appservice_irc_container_additional_networks_auto + matrix_bridge_appservice_irc_container_additional_networks_custom }}" +matrix_bridge_appservice_irc_container_additional_networks_auto: [] +matrix_bridge_appservice_irc_container_additional_networks_custom: [] # A list of extra arguments to pass to the container -matrix_appservice_irc_container_extra_arguments: [] +matrix_bridge_appservice_irc_container_extra_arguments: [] -# matrix_appservice_irc_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. -# To inject your own other container labels, see `matrix_appservice_irc_container_labels_additional_labels`. -matrix_appservice_irc_container_labels_traefik_enabled: true -matrix_appservice_irc_container_labels_traefik_docker_network: "{{ matrix_appservice_irc_container_network }}" -matrix_appservice_irc_container_labels_traefik_entrypoints: web-secure -matrix_appservice_irc_container_labels_traefik_tls_certResolver: default # noqa var-naming +# matrix_bridge_appservice_irc_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# To inject your own other container labels, see `matrix_bridge_appservice_irc_container_labels_additional_labels`. +matrix_bridge_appservice_irc_container_labels_traefik_enabled: true +matrix_bridge_appservice_irc_container_labels_traefik_docker_network: "{{ matrix_bridge_appservice_irc_container_network }}" +matrix_bridge_appservice_irc_container_labels_traefik_entrypoints: web-secure +matrix_bridge_appservice_irc_container_labels_traefik_tls_certResolver: default # noqa var-naming # Controls whether Traefik labels for the media proxy will be applied -matrix_appservice_irc_container_labels_media_proxy_enabled: true +matrix_bridge_appservice_irc_container_labels_media_proxy_enabled: true # Derived from publicUrl_pathPrefix, stripping any trailing slash (unless it's just "/") -matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix: "{{ '/' if matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix == '/' else matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix.rstrip('/') }}" -matrix_appservice_irc_container_labels_media_proxy_traefik_rule: "Host(`{{ matrix_appservice_irc_ircService_mediaProxy_publicUrl_hostname }}`) && PathPrefix(`{{ matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix }}`)" -matrix_appservice_irc_container_labels_media_proxy_traefik_priority: 2000 -matrix_appservice_irc_container_labels_media_proxy_traefik_entrypoints: "{{ matrix_appservice_irc_container_labels_traefik_entrypoints }}" -matrix_appservice_irc_container_labels_media_proxy_traefik_tls: "{{ matrix_appservice_irc_container_labels_media_proxy_traefik_entrypoints != 'web' }}" -matrix_appservice_irc_container_labels_media_proxy_traefik_tls_certResolver: "{{ matrix_appservice_irc_container_labels_traefik_tls_certResolver }}" # noqa var-naming +matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix: "{{ '/' if matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix == '/' else matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix.rstrip('/') }}" +matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_rule: "Host(`{{ matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_hostname }}`) && PathPrefix(`{{ matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix }}`)" +matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_priority: 2000 +matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_entrypoints: "{{ matrix_bridge_appservice_irc_container_labels_traefik_entrypoints }}" +matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_tls: "{{ matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_entrypoints != 'web' }}" +matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_tls_certResolver: "{{ matrix_bridge_appservice_irc_container_labels_traefik_tls_certResolver }}" # noqa var-naming # matrix-appservice-irc container additional labels -matrix_appservice_irc_container_labels_additional_labels: '' +matrix_bridge_appservice_irc_container_labels_additional_labels: '' # List of systemd services that matrix-appservice-irc.service depends on. -matrix_appservice_irc_systemd_required_services_list: "{{ matrix_appservice_irc_systemd_required_services_list_default + matrix_appservice_irc_systemd_required_services_list_auto + matrix_appservice_irc_systemd_required_services_list_custom }}" -matrix_appservice_irc_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_appservice_irc_systemd_required_services_list_auto: [] -matrix_appservice_irc_systemd_required_services_list_custom: [] +matrix_bridge_appservice_irc_systemd_required_services_list: "{{ matrix_bridge_appservice_irc_systemd_required_services_list_default + matrix_bridge_appservice_irc_systemd_required_services_list_auto + matrix_bridge_appservice_irc_systemd_required_services_list_custom }}" +matrix_bridge_appservice_irc_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_appservice_irc_systemd_required_services_list_auto: [] +matrix_bridge_appservice_irc_systemd_required_services_list_custom: [] # List of systemd services that matrix-appservice-irc.service wants -matrix_appservice_irc_systemd_wanted_services_list: [] +matrix_bridge_appservice_irc_systemd_wanted_services_list: [] -matrix_appservice_irc_appservice_token: '' -matrix_appservice_irc_homeserver_token: '' +matrix_bridge_appservice_irc_appservice_token: '' +matrix_bridge_appservice_irc_homeserver_token: '' -matrix_appservice_irc_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_appservice_irc_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_appservice_irc_configuration_extension_yaml: | +matrix_bridge_appservice_irc_configuration_extension_yaml: | # Your custom YAML configuration for Appservice IRC servers goes here. - # This configuration extends the default starting configuration (`matrix_appservice_irc_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_appservice_irc_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_appservice_irc_configuration_yaml`. + # completely redefining `matrix_bridge_appservice_irc_configuration_yaml`. -matrix_appservice_irc_configuration_extension: "{{ matrix_appservice_irc_configuration_extension_yaml | from_yaml if matrix_appservice_irc_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_appservice_irc_configuration_extension: "{{ matrix_bridge_appservice_irc_configuration_extension_yaml | from_yaml if matrix_bridge_appservice_irc_configuration_extension_yaml | from_yaml is mapping else {} }}" -matrix_appservice_irc_configuration: "{{ matrix_appservice_irc_configuration_yaml | from_yaml | combine(matrix_appservice_irc_configuration_extension, recursive=True) }}" +matrix_bridge_appservice_irc_configuration: "{{ matrix_bridge_appservice_irc_configuration_yaml | from_yaml | combine(matrix_bridge_appservice_irc_configuration_extension, recursive=True) }}" # The original registration.yaml file generated by AppService IRC is merged with this config override, # to produce the final registration.yaml file ultimately used by both the bridge and the homeserver. @@ -543,14 +542,14 @@ matrix_appservice_irc_configuration: "{{ matrix_appservice_irc_configuration_yam # - always having the same AS/HS token and appservice ID in the registration.yaml file # # Learn more about this in `setup_install.yml` -matrix_appservice_irc_registration_override_yaml: | +matrix_bridge_appservice_irc_registration_override_yaml: | id: appservice-irc - as_token: "{{ matrix_appservice_irc_appservice_token }}" - hs_token: "{{ matrix_appservice_irc_homeserver_token }}" + as_token: "{{ matrix_bridge_appservice_irc_appservice_token }}" + hs_token: "{{ matrix_bridge_appservice_irc_homeserver_token }}" -matrix_appservice_irc_registration_override: "{{ matrix_appservice_irc_registration_override_yaml | from_yaml }}" +matrix_bridge_appservice_irc_registration_override: "{{ matrix_bridge_appservice_irc_registration_override_yaml | from_yaml }}" -# matrix_appservice_irc_restart_necessary controls whether the service +# matrix_bridge_appservice_irc_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -558,4 +557,4 @@ matrix_appservice_irc_registration_override: "{{ matrix_appservice_irc_registrat # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_appservice_irc_restart_necessary: false +matrix_bridge_appservice_irc_restart_necessary: false diff --git a/roles/custom/matrix-bridge-appservice-irc/tasks/main.yml b/roles/custom/matrix-bridge-appservice-irc/tasks/main.yml index ba6332519..baf2ad730 100644 --- a/roles/custom/matrix-bridge-appservice-irc/tasks/main.yml +++ b/roles/custom/matrix-bridge-appservice-irc/tasks/main.yml @@ -12,15 +12,15 @@ - install-all - install-appservice-irc block: - - when: matrix_appservice_irc_enabled | bool + - when: matrix_bridge_appservice_irc_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_appservice_irc_enabled | bool + - when: matrix_bridge_appservice_irc_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-appservice-irc block: - - when: not matrix_appservice_irc_enabled | bool + - when: not matrix_bridge_appservice_irc_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-appservice-irc/tasks/migrate_nedb_to_postgres.yml b/roles/custom/matrix-bridge-appservice-irc/tasks/migrate_nedb_to_postgres.yml index 930e484b2..6b58e34d9 100644 --- a/roles/custom/matrix-bridge-appservice-irc/tasks/migrate_nedb_to_postgres.yml +++ b/roles/custom/matrix-bridge-appservice-irc/tasks/migrate_nedb_to_postgres.yml @@ -38,13 +38,13 @@ - name: Check existence of matrix-appservice-irc service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-irc.service" - register: matrix_appservice_irc_service_stat + register: matrix_bridge_appservice_irc_service_stat - name: Ensure matrix-appservice-irc is stopped ansible.builtin.service: name: matrix-appservice-irc state: stopped - when: "matrix_appservice_irc_service_stat.stat.exists" + when: "matrix_bridge_appservice_irc_service_stat.stat.exists" - name: Import appservice-irc NeDB database into Postgres ansible.builtin.command: @@ -53,25 +53,25 @@ --rm --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL - {% if matrix_appservice_irc_database_container_network %} - --network={{ matrix_appservice_irc_database_container_network }} + {% if matrix_bridge_appservice_irc_database_container_network %} + --network={{ matrix_bridge_appservice_irc_database_container_network }} {% endif %} - --mount type=bind,src={{ matrix_appservice_irc_data_path }},dst=/data + --mount type=bind,src={{ matrix_bridge_appservice_irc_data_path }},dst=/data --entrypoint=/bin/sh - {{ matrix_appservice_irc_container_image }} + {{ matrix_bridge_appservice_irc_container_image }} -c - '/usr/local/bin/node /app/lib/scripts/migrate-db-to-pgres.js --dbdir /data --privateKey /data/passkey.pem --connectionString {{ matrix_appservice_irc_database_connection_string }}' - register: matrix_appservice_irc_import_nedb_to_postgres_result - changed_when: matrix_appservice_irc_import_nedb_to_postgres_result.rc == 0 + '/usr/local/bin/node /app/lib/scripts/migrate-db-to-pgres.js --dbdir /data --privateKey /data/passkey.pem --connectionString {{ matrix_bridge_appservice_irc_database_connection_string }}' + register: matrix_bridge_appservice_irc_import_nedb_to_postgres_result + changed_when: matrix_bridge_appservice_irc_import_nedb_to_postgres_result.rc == 0 - name: Archive NeDB database files ansible.builtin.command: - cmd: "mv {{ matrix_appservice_irc_data_path }}/{{ item }} {{ matrix_appservice_irc_data_path }}/{{ item }}.backup" + cmd: "mv {{ matrix_bridge_appservice_irc_data_path }}/{{ item }} {{ matrix_bridge_appservice_irc_data_path }}/{{ item }}.backup" with_items: - rooms.db - users.db - register: matrix_appservice_irc_import_nedb_to_postgres_move_result - changed_when: matrix_appservice_irc_import_nedb_to_postgres_move_result.rc == 0 + register: matrix_bridge_appservice_irc_import_nedb_to_postgres_move_result + changed_when: matrix_bridge_appservice_irc_import_nedb_to_postgres_move_result.rc == 0 - name: Inject result ansible.builtin.set_fact: @@ -80,6 +80,6 @@ devture_playbook_runtime_messages_list | default([]) + [ - "Note: Your appservice-irc database files have been imported into Postgres. The original database files have been moved from `" + matrix_appservice_irc_data_path + "/*.db` to `" + matrix_appservice_irc_data_path + "/*.db.backup`. When you've confirmed that the import went well and everything works, you should be able to safely delete these files." + "Note: Your appservice-irc database files have been imported into Postgres. The original database files have been moved from `" + matrix_bridge_appservice_irc_data_path + "/*.db` to `" + matrix_bridge_appservice_irc_data_path + "/*.db.backup`. When you've confirmed that the import went well and everything works, you should be able to safely delete these files." ] }} diff --git a/roles/custom/matrix-bridge-appservice-irc/tasks/setup_install.yml b/roles/custom/matrix-bridge-appservice-irc/tasks/setup_install.yml index ff47314f6..f267ff5b5 100644 --- a/roles/custom/matrix-bridge-appservice-irc/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-appservice-irc/tasks/setup_install.yml @@ -26,18 +26,18 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_appservice_irc_base_path }}", when: true} - - {path: "{{ matrix_appservice_irc_config_path }}", when: true} - - {path: "{{ matrix_appservice_irc_data_path }}", when: true} - - {path: "{{ matrix_appservice_irc_container_src_files_path }}", when: "{{ matrix_appservice_irc_container_image_self_build }}"} + - {path: "{{ matrix_bridge_appservice_irc_base_path }}", when: true} + - {path: "{{ matrix_bridge_appservice_irc_config_path }}", when: true} + - {path: "{{ matrix_bridge_appservice_irc_data_path }}", when: true} + - {path: "{{ matrix_bridge_appservice_irc_container_src_files_path }}", when: "{{ matrix_bridge_appservice_irc_container_image_self_build }}"} when: item.when | bool - name: Check if an old passkey file already exists ansible.builtin.stat: - path: "{{ matrix_appservice_irc_base_path }}/passkey.pem" - register: matrix_appservice_irc_stat_passkey + path: "{{ matrix_bridge_appservice_irc_base_path }}/passkey.pem" + register: matrix_bridge_appservice_irc_stat_passkey -- when: "matrix_appservice_irc_stat_passkey.stat.exists" +- when: "matrix_bridge_appservice_irc_stat_passkey.stat.exists" block: - name: (Data relocation) Ensure matrix-appservice-irc.service is stopped ansible.builtin.service: @@ -48,108 +48,114 @@ - name: (Data relocation) Move AppService IRC passkey.pem file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_appservice_irc_base_path }}/passkey.pem {{ matrix_appservice_irc_data_path }}/passkey.pem" - register: matrix_appservice_irc_move_passkey_result - changed_when: matrix_appservice_irc_move_passkey_result.rc == 0 + cmd: "mv {{ matrix_bridge_appservice_irc_base_path }}/passkey.pem {{ matrix_bridge_appservice_irc_data_path }}/passkey.pem" + register: matrix_bridge_appservice_irc_move_passkey_result + changed_when: matrix_bridge_appservice_irc_move_passkey_result.rc == 0 - name: (Data relocation) Move AppService IRC database files to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_appservice_irc_base_path }}/{{ item }} {{ matrix_appservice_irc_data_path }}/{{ item }}" - register: matrix_appservice_irc_move_dbs_result - changed_when: matrix_appservice_irc_move_dbs_result.rc == 0 + cmd: "mv {{ matrix_bridge_appservice_irc_base_path }}/{{ item }} {{ matrix_bridge_appservice_irc_data_path }}/{{ item }}" + register: matrix_bridge_appservice_irc_move_dbs_result + changed_when: matrix_bridge_appservice_irc_move_dbs_result.rc == 0 with_items: - rooms.db - users.db failed_when: false - ansible.builtin.set_fact: - matrix_appservice_irc_migration_requires_restart: false + matrix_bridge_appservice_irc_migration_requires_restart: false -- when: "matrix_appservice_irc_database_engine == 'postgres'" +- when: "matrix_bridge_appservice_irc_database_engine == 'postgres'" block: - name: Check if a nedb database already exists ansible.builtin.stat: - path: "{{ matrix_appservice_irc_data_path }}/users.db" - register: matrix_appservice_irc_nedb_database_path_local_stat_result + path: "{{ matrix_bridge_appservice_irc_data_path }}/users.db" + register: matrix_bridge_appservice_irc_nedb_database_path_local_stat_result - - when: "matrix_appservice_irc_nedb_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_appservice_irc_nedb_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_tasks: "{{ role_path }}/tasks/migrate_nedb_to_postgres.yml" - ansible.builtin.set_fact: - matrix_appservice_irc_migration_requires_restart: true + matrix_bridge_appservice_irc_migration_requires_restart: true - name: Ensure Appservice IRC image is pulled - community.docker.docker_image: - name: "{{ matrix_appservice_irc_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_appservice_irc_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_appservice_irc_container_image_force_pull }}" - when: "matrix_appservice_irc_enabled | bool and not matrix_appservice_irc_container_image_self_build | bool" - register: matrix_appservice_irc_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_appservice_irc_container_image }}" + pull: always + when: "matrix_bridge_appservice_irc_enabled | bool and not matrix_bridge_appservice_irc_container_image_self_build | bool" + register: matrix_bridge_appservice_irc_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_appservice_irc_container_image_pull_result is not failed + until: matrix_bridge_appservice_irc_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure matrix-appservice-irc repository ownership is correct when self-building + ansible.builtin.file: + path: "{{ matrix_bridge_appservice_irc_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_appservice_irc_enabled | bool and matrix_bridge_appservice_irc_container_image_self_build | bool" - name: Ensure matrix-appservice-irc repository is present when self-building ansible.builtin.git: - repo: "{{ matrix_appservice_irc_container_repo }}" - version: "{{ matrix_appservice_irc_container_repo_version }}" - dest: "{{ matrix_appservice_irc_container_src_files_path }}" + repo: "{{ matrix_bridge_appservice_irc_container_repo }}" + version: "{{ matrix_bridge_appservice_irc_container_repo_version }}" + dest: "{{ matrix_bridge_appservice_irc_container_src_files_path }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_appservice_irc_git_pull_results - when: "matrix_appservice_irc_enabled | bool and matrix_appservice_irc_container_image_self_build | bool" + register: matrix_bridge_appservice_irc_git_pull_results + when: "matrix_bridge_appservice_irc_enabled | bool and matrix_bridge_appservice_irc_container_image_self_build | bool" - name: Ensure matrix-appservice-irc Docker image is built - community.docker.docker_image: - name: "{{ matrix_appservice_irc_container_image }}" - source: build - force_source: "{{ matrix_appservice_irc_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_appservice_irc_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_appservice_irc_container_src_files_path }}" - pull: true - when: "matrix_appservice_irc_enabled | bool and matrix_appservice_irc_container_image_self_build | bool and matrix_appservice_irc_git_pull_results.changed" + community.docker.docker_image_build: + name: "{{ matrix_bridge_appservice_irc_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_appservice_irc_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_appservice_irc_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_appservice_irc_enabled | bool and matrix_bridge_appservice_irc_container_image_self_build | bool and matrix_bridge_appservice_irc_git_pull_results.changed" + register: matrix_bridge_appservice_irc_container_image_build_result - name: Ensure Matrix Appservice IRC config installed ansible.builtin.copy: - content: "{{ matrix_appservice_irc_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_appservice_irc_config_path }}/config.yaml" + content: "{{ matrix_bridge_appservice_irc_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_appservice_irc_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_appservice_irc_config_result + register: matrix_bridge_appservice_irc_config_result - name: Ensure Matrix Appservice IRC labels file installed ansible.builtin.template: src: "{{ role_path }}/templates/labels.j2" - dest: "{{ matrix_appservice_irc_base_path }}/labels" + dest: "{{ matrix_bridge_appservice_irc_base_path }}/labels" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_appservice_irc_labels_result + register: matrix_bridge_appservice_irc_labels_result - name: Generate Appservice IRC passkey if it doesn't exist ansible.builtin.shell: - cmd: "{{ matrix_host_command_openssl }} genpkey -out {{ matrix_appservice_irc_data_path }}/passkey.pem -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:2048" - creates: "{{ matrix_appservice_irc_data_path }}/passkey.pem" + cmd: "{{ matrix_host_command_openssl }} genpkey -out {{ matrix_bridge_appservice_irc_data_path }}/passkey.pem -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:2048" + creates: "{{ matrix_bridge_appservice_irc_data_path }}/passkey.pem" become: true become_user: "{{ matrix_user_name }}" - name: Check if an authenticated media signing key exists ansible.builtin.stat: - path: "{{ matrix_appservice_irc_data_path }}/auth-media.jwk" - register: matrix_appservice_irc_stat_auth_media_key + path: "{{ matrix_bridge_appservice_irc_data_path }}/auth-media.jwk" + register: matrix_bridge_appservice_irc_stat_auth_media_key -- when: not matrix_appservice_irc_stat_auth_media_key.stat.exists +- when: not matrix_bridge_appservice_irc_stat_auth_media_key.stat.exists block: - name: Generate IRC appservice signing key for authenticated media community.docker.docker_container: name: "create-auth-media-jwk-key" - image: "{{ matrix_appservice_irc_container_image }}" + image: "{{ matrix_bridge_appservice_irc_container_image }}" cleanup: true network_mode: none entrypoint: "/usr/local/bin/node" @@ -164,12 +170,12 @@ } main().then(() => process.exit(0)).catch(err => { throw err });" detach: false - register: matrix_appservice_irc_jwk_result + register: matrix_bridge_appservice_irc_jwk_result - name: Write auth media signing key to file ansible.builtin.copy: - content: "{{ matrix_appservice_irc_jwk_result.container.Output }}" - dest: "{{ matrix_appservice_irc_data_path }}/auth-media.jwk" + content: "{{ matrix_bridge_appservice_irc_jwk_result.container.Output }}" + dest: "{{ matrix_bridge_appservice_irc_data_path }}/auth-media.jwk" mode: "0644" owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" @@ -178,7 +184,7 @@ # Fix it. - name: (Migration) Ensure Appservice IRC passkey permissions are okay ansible.builtin.file: - path: "{{ matrix_appservice_irc_data_path }}/passkey.pem" + path: "{{ matrix_bridge_appservice_irc_data_path }}/passkey.pem" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" @@ -207,10 +213,10 @@ {{ devture_systemd_docker_base_host_command_docker }} run --rm --name matrix-appservice-irc-gen --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL - --mount type=bind,src={{ matrix_appservice_irc_config_path }},dst=/config - --mount type=bind,src={{ matrix_appservice_irc_data_path }},dst=/data + --mount type=bind,src={{ matrix_bridge_appservice_irc_config_path }},dst=/config + --mount type=bind,src={{ matrix_bridge_appservice_irc_data_path }},dst=/data --entrypoint=/bin/bash - {{ matrix_appservice_irc_container_image }} + {{ matrix_bridge_appservice_irc_container_image }} -c 'node app.js -r @@ -222,36 +228,37 @@ - name: Read Appservice IRC registration-template.yaml ansible.builtin.slurp: - src: "{{ matrix_appservice_irc_config_path }}/registration-template.yaml" - register: matrix_appservice_irc_registration_template_slurp + src: "{{ matrix_bridge_appservice_irc_config_path }}/registration-template.yaml" + register: matrix_bridge_appservice_irc_registration_template_slurp - name: Remove unnecessary Appservice IRC registration-template.yaml ansible.builtin.file: - path: "{{ matrix_appservice_irc_config_path }}/registration-template.yaml" + path: "{{ matrix_bridge_appservice_irc_config_path }}/registration-template.yaml" state: absent changed_when: false - name: Parse registration-template.yaml ansible.builtin.set_fact: - matrix_appservice_irc_registration_template: "{{ matrix_appservice_irc_registration_template_slurp['content'] | b64decode | from_yaml }}" + matrix_bridge_appservice_irc_registration_template: "{{ matrix_bridge_appservice_irc_registration_template_slurp['content'] | b64decode | from_yaml }}" - name: Combine registration-template.yaml and own registration override config ansible.builtin.set_fact: - matrix_appservice_irc_registration: "{{ matrix_appservice_irc_registration_template | combine(matrix_appservice_irc_registration_override, recursive=True) }}" + matrix_bridge_appservice_irc_registration: "{{ matrix_bridge_appservice_irc_registration_template | combine(matrix_bridge_appservice_irc_registration_override, recursive=True) }}" - name: Ensure Appservice IRC registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_appservice_irc_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_appservice_irc_config_path }}/registration.yaml" + content: "{{ matrix_bridge_appservice_irc_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_appservice_irc_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_appservice_irc_registration_result + register: matrix_bridge_appservice_irc_registration_result - name: Ensure matrix-appservice-irc container network is created + when: matrix_bridge_appservice_irc_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_appservice_irc_container_network }}" + name: "{{ matrix_bridge_appservice_irc_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -260,18 +267,19 @@ src: "{{ role_path }}/templates/systemd/matrix-appservice-irc.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-irc.service" mode: '0644' - register: matrix_appservice_irc_systemd_service_result + register: matrix_bridge_appservice_irc_systemd_service_result - name: Determine whether matrix-appservice-irc needs a restart ansible.builtin.set_fact: - matrix_appservice_irc_restart_necessary: >- + matrix_bridge_appservice_irc_restart_necessary: >- {{ - matrix_appservice_irc_migration_requires_restart | default(false) - or matrix_appservice_irc_config_result.changed | default(false) - or matrix_appservice_irc_labels_result.changed | default(false) - or matrix_appservice_irc_registration_result.changed | default(false) - or matrix_appservice_irc_systemd_service_result.changed | default(false) - or matrix_appservice_irc_container_image_pull_result.changed | default(false) + matrix_bridge_appservice_irc_migration_requires_restart | default(false) + or matrix_bridge_appservice_irc_config_result.changed | default(false) + or matrix_bridge_appservice_irc_labels_result.changed | default(false) + or matrix_bridge_appservice_irc_registration_result.changed | default(false) + or matrix_bridge_appservice_irc_systemd_service_result.changed | default(false) + or matrix_bridge_appservice_irc_container_image_pull_result.changed | default(false) + or matrix_bridge_appservice_irc_container_image_build_result.changed | default(false) }} - name: Ensure matrix-appservice-irc.service restarted, if necessary @@ -279,4 +287,4 @@ name: "matrix-appservice-irc.service" state: restarted daemon_reload: true - when: "matrix_appservice_irc_migration_requires_restart | bool" + when: "matrix_bridge_appservice_irc_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-appservice-irc/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-appservice-irc/tasks/setup_uninstall.yml index 371c42503..cd367e653 100644 --- a/roles/custom/matrix-bridge-appservice-irc/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-appservice-irc/tasks/setup_uninstall.yml @@ -9,9 +9,9 @@ - name: Check existence of matrix-appservice-irc service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-irc.service" - register: matrix_appservice_irc_service_stat + register: matrix_bridge_appservice_irc_service_stat -- when: matrix_appservice_irc_service_stat.stat.exists | bool +- when: matrix_bridge_appservice_irc_service_stat.stat.exists | bool block: - name: Ensure matrix-appservice-irc is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-appservice-irc/tasks/validate_config.yml b/roles/custom/matrix-bridge-appservice-irc/tasks/validate_config.yml index ee527f277..7cbc5542c 100644 --- a/roles/custom/matrix-bridge-appservice-irc/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-appservice-irc/tasks/validate_config.yml @@ -13,19 +13,20 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_appservice_irc_container_expose_client_server_api_port', 'new': ''} - - {'old': 'matrix_appservice_irc_container_self_build', 'new': 'matrix_appservice_irc_container_image_self_build'} - - {'old': 'matrix_appservice_irc_docker_image_name_prefix', 'new': 'matrix_appservice_irc_container_image_registry_prefix'} - - {'old': 'matrix_appservice_irc_homeserver_media_url', 'new': ''} - - {'old': 'matrix_appservice_irc_docker_image', 'new': 'matrix_appservice_irc_container_image'} - - {'old': 'matrix_appservice_irc_docker_image_force_pull', 'new': 'matrix_appservice_irc_container_image_force_pull'} - - {'old': 'matrix_appservice_irc_docker_image_registry_prefix', 'new': 'matrix_appservice_irc_container_image_registry_prefix'} - - {'old': 'matrix_appservice_irc_docker_image_registry_prefix_upstream', 'new': 'matrix_appservice_irc_container_image_registry_prefix_upstream'} - - {'old': 'matrix_appservice_irc_docker_image_registry_prefix_upstream_default', 'new': 'matrix_appservice_irc_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_appservice_irc_docker_image_tag', 'new': 'matrix_appservice_irc_container_image_tag'} - - {'old': 'matrix_appservice_irc_docker_repo', 'new': 'matrix_appservice_irc_container_repo'} - - {'old': 'matrix_appservice_irc_docker_repo_version', 'new': 'matrix_appservice_irc_container_repo_version'} - - {'old': 'matrix_appservice_irc_docker_src_files_path', 'new': 'matrix_appservice_irc_container_src_files_path'} + - {'old': 'matrix_bridge_appservice_irc_container_expose_client_server_api_port', 'new': ''} + - {'old': 'matrix_bridge_appservice_irc_container_self_build', 'new': 'matrix_bridge_appservice_irc_container_image_self_build'} + - {'old': 'matrix_bridge_appservice_irc_docker_image_name_prefix', 'new': 'matrix_bridge_appservice_irc_container_image_registry_prefix'} + - {'old': 'matrix_bridge_appservice_irc_homeserver_media_url', 'new': ''} + - {'old': 'matrix_bridge_appservice_irc_docker_image', 'new': 'matrix_bridge_appservice_irc_container_image'} + - {'old': 'matrix_bridge_appservice_irc_docker_image_force_pull', 'new': 'matrix_bridge_appservice_irc_container_image_force_pull'} + - {'old': 'matrix_bridge_appservice_irc_docker_image_registry_prefix', 'new': 'matrix_bridge_appservice_irc_container_image_registry_prefix'} + - {'old': 'matrix_bridge_appservice_irc_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_appservice_irc_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_appservice_irc_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_appservice_irc_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_appservice_irc_docker_image_tag', 'new': 'matrix_bridge_appservice_irc_container_image_tag'} + - {'old': 'matrix_bridge_appservice_irc_docker_repo', 'new': 'matrix_bridge_appservice_irc_container_repo'} + - {'old': 'matrix_bridge_appservice_irc_docker_repo_version', 'new': 'matrix_bridge_appservice_irc_container_repo_version'} + - {'old': 'matrix_bridge_appservice_irc_docker_src_files_path', 'new': 'matrix_bridge_appservice_irc_container_src_files_path'} + - {'old': 'matrix_bridge_appservice_irc_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required appservice-irc settings not defined ansible.builtin.fail: @@ -33,16 +34,16 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_appservice_irc_appservice_token', when: true} - - {'name': 'matrix_appservice_irc_homeserver_url', when: true} - - {'name': 'matrix_appservice_irc_homeserver_token', when: true} - - {'name': 'matrix_appservice_irc_database_hostname', when: "{{ matrix_appservice_irc_database_engine == 'postgres' }}"} - - {'name': 'matrix_appservice_irc_container_network', when: true} + - {'name': 'matrix_bridge_appservice_irc_appservice_token', when: true} + - {'name': 'matrix_bridge_appservice_irc_homeserver_url', when: true} + - {'name': 'matrix_bridge_appservice_irc_homeserver_token', when: true} + - {'name': 'matrix_bridge_appservice_irc_database_hostname', when: "{{ matrix_bridge_appservice_irc_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_appservice_irc_container_network', when: true} -# Our base configuration (`matrix_appservice_irc_configuration_yaml`) is not enough to +# Our base configuration (`matrix_bridge_appservice_irc_configuration_yaml`) is not enough to # let the playbook run without errors. # -# Unless the final configuration (`matrix_appservice_irc_configuration`) contains an `ircService` definition, +# Unless the final configuration (`matrix_bridge_appservice_irc_configuration`) contains an `ircService` definition, # we'd fail generating the registration.yaml file with a non-helpful error. # # This is a safety check to ensure we fail earlier and in a nicer way. @@ -51,30 +52,30 @@ ansible.builtin.fail: msg: >- Your Appservice IRC configuration is incomplete (lacking an `ircService.servers` configuration). - You need to define one or more servers by either using `matrix_appservice_irc_ircService_servers` - or by extending the base configuration with additional configuration in `matrix_appservice_irc_configuration_extension_yaml`. - Overriding the whole bridge's configuration (`matrix_appservice_irc_configuration`) is yet another possibility. - when: "matrix_appservice_irc_configuration.ircService.servers | length == 0" + You need to define one or more servers by either using `matrix_bridge_appservice_irc_ircService_servers` + or by extending the base configuration with additional configuration in `matrix_bridge_appservice_irc_configuration_extension_yaml`. + Overriding the whole bridge's configuration (`matrix_bridge_appservice_irc_configuration`) is yet another possibility. + when: "matrix_bridge_appservice_irc_configuration.ircService.servers | length == 0" -- name: Fail if matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix does not start with a slash +- name: Fail if matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix does not start with a slash ansible.builtin.fail: msg: >- - matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix (`{{ matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix }}`) must start with a slash (e.g. `/` or `/irc/`). - when: "matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix[0] != '/'" + matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix (`{{ matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix }}`) must start with a slash (e.g. `/` or `/irc/`). + when: "matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix[0] != '/'" -- name: Fail if matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix does not end with a slash +- name: Fail if matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix does not end with a slash ansible.builtin.fail: msg: >- - matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix (`{{ matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix }}`) must end with a slash (e.g. `/` or `/irc/`). - when: "matrix_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix[-1] != '/'" + matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix (`{{ matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix }}`) must end with a slash (e.g. `/` or `/irc/`). + when: "matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl_pathPrefix[-1] != '/'" -- when: matrix_appservice_irc_container_labels_traefik_enabled | bool +- when: matrix_bridge_appservice_irc_container_labels_traefik_enabled | bool block: # We ensure it doesn't end with a slash, because we handle both (slash and no-slash). # Knowing that the path_prefix does not end with a slash ensures we know how to set these routes up # without having to do "does it end with a slash" checks elsewhere. - - name: Fail if matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix ends with a slash + - name: Fail if matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix ends with a slash ansible.builtin.fail: msg: >- - matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix (`{{ matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix }}`) must either be `/` or not end with a slash (e.g. `/irc`). - when: "matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix != '/' and matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix[-1] == '/'" + matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix (`{{ matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix }}`) must either be `/` or not end with a slash (e.g. `/irc`). + when: "matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix != '/' and matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix[-1] == '/'" diff --git a/roles/custom/matrix-bridge-appservice-irc/templates/config.yaml.j2 b/roles/custom/matrix-bridge-appservice-irc/templates/config.yaml.j2 index 363ac9a1b..8c215191b 100644 --- a/roles/custom/matrix-bridge-appservice-irc/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-appservice-irc/templates/config.yaml.j2 @@ -7,7 +7,7 @@ # Unless otherwise specified, these keys CANNOT be hot-reloaded. homeserver: # The URL to the home server for client-server API calls - url: "{{ matrix_appservice_irc_homeserver_url }}" + url: "{{ matrix_bridge_appservice_irc_homeserver_url }}" # Drop Matrix messages which are older than this number of seconds, according to # the event's origin_server_ts. @@ -24,12 +24,12 @@ homeserver: # The 'domain' part for user IDs on this home server. Usually (but not always) # is the "domain name" part of the HS URL. - domain: "{{ matrix_appservice_irc_homeserver_domain }}" + domain: "{{ matrix_bridge_appservice_irc_homeserver_domain }}" # Should presence be enabled for Matrix clients on this bridge. If disabled on the # homeserver then it should also be disabled here to avoid excess traffic. # Default: true - enablePresence: {{ matrix_appservice_irc_homeserver_enablePresence|to_json }} + enablePresence: {{ matrix_bridge_appservice_irc_homeserver_enablePresence|to_json }} # Which port should the appservice bind to. Can be overridden by the one provided in the # command line! Optional. @@ -62,7 +62,7 @@ ircService: # All server keys can be hot-reloaded, however existing IRC connections # will not have changes applied to them. - servers: {{ matrix_appservice_irc_ircService_servers|to_json }} + servers: {{ matrix_bridge_appservice_irc_ircService_servers|to_json }} # present relevant UI to the user. MSC2346 bridgeInfoState: @@ -141,9 +141,9 @@ ircService: # How long should the generated URLs be valid for ttlSeconds: 604800 # The port for the media proxy to listen on - bindPort: {{ matrix_appservice_irc_ircService_mediaProxy_bindPort | to_json }} + bindPort: {{ matrix_bridge_appservice_irc_ircService_mediaProxy_bindPort | to_json }} # The publicly accessible URL to the media proxy - publicUrl: {{ matrix_appservice_irc_ircService_mediaProxy_publicUrl | to_json }} + publicUrl: {{ matrix_bridge_appservice_irc_ircService_mediaProxy_publicUrl | to_json }} # Options here are generally only applicable to large-scale bridges and may have # consequences greater than other options in this configuration file. @@ -162,8 +162,8 @@ advanced: # This key CANNOT be hot-reloaded. database: # database engine (must be 'postgres' or 'nedb'). Default: nedb - engine: {{ matrix_appservice_irc_database_engine|to_json }} + engine: {{ matrix_bridge_appservice_irc_database_engine|to_json }} # Either a PostgreSQL connection string, or a path to the NeDB storage directory. # For postgres, it must start with postgres:// # For NeDB, it must start with nedb://. The path is relative to the project directory. - connectionString: {{ matrix_appservice_irc_database_connectionString | to_json }} + connectionString: {{ matrix_bridge_appservice_irc_database_connectionString | to_json }} diff --git a/roles/custom/matrix-bridge-appservice-irc/templates/labels.j2 b/roles/custom/matrix-bridge-appservice-irc/templates/labels.j2 index fbffbdae9..98bd6c5e6 100644 --- a/roles/custom/matrix-bridge-appservice-irc/templates/labels.j2 +++ b/roles/custom/matrix-bridge-appservice-irc/templates/labels.j2 @@ -6,14 +6,14 @@ SPDX-FileCopyrightText: 2026 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_appservice_irc_container_labels_traefik_enabled and matrix_appservice_irc_container_labels_media_proxy_enabled %} +{% if matrix_bridge_appservice_irc_container_labels_traefik_enabled and matrix_bridge_appservice_irc_container_labels_media_proxy_enabled %} traefik.enable=true -{% if matrix_appservice_irc_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_appservice_irc_container_labels_traefik_docker_network }} +{% if matrix_bridge_appservice_irc_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_appservice_irc_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.matrix-appservice-irc-media-proxy.loadbalancer.server.port={{ matrix_appservice_irc_ircService_mediaProxy_bindPort }} +traefik.http.services.matrix-appservice-irc-media-proxy.loadbalancer.server.port={{ matrix_bridge_appservice_irc_ircService_mediaProxy_bindPort }} ############################################################ # # @@ -23,34 +23,34 @@ traefik.http.services.matrix-appservice-irc-media-proxy.loadbalancer.server.port {% set middlewares = [] %} -traefik.http.routers.matrix-appservice-irc-media-proxy.rule={{ matrix_appservice_irc_container_labels_media_proxy_traefik_rule }} +traefik.http.routers.matrix-appservice-irc-media-proxy.rule={{ matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_rule }} -{% if matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix != '/' %} -traefik.http.middlewares.matrix-appservice-irc-media-proxy-slashless-redirect.redirectregex.regex=({{ matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix | quote }})$ +{% if matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix != '/' %} +traefik.http.middlewares.matrix-appservice-irc-media-proxy-slashless-redirect.redirectregex.regex=({{ matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix | quote }})$ traefik.http.middlewares.matrix-appservice-irc-media-proxy-slashless-redirect.redirectregex.replacement=${1}/ {% set middlewares = middlewares + ['matrix-appservice-irc-media-proxy-slashless-redirect'] %} {% endif %} -{% if matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix != '/' %} -traefik.http.middlewares.matrix-appservice-irc-media-proxy-strip-prefix.stripprefix.prefixes={{ matrix_appservice_irc_container_labels_media_proxy_traefik_path_prefix }} +{% if matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix != '/' %} +traefik.http.middlewares.matrix-appservice-irc-media-proxy-strip-prefix.stripprefix.prefixes={{ matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_path_prefix }} {% set middlewares = middlewares + ['matrix-appservice-irc-media-proxy-strip-prefix'] %} {% endif %} -{% if matrix_appservice_irc_container_labels_media_proxy_traefik_priority | int > 0 %} -traefik.http.routers.matrix-appservice-irc-media-proxy.priority={{ matrix_appservice_irc_container_labels_media_proxy_traefik_priority }} +{% if matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_priority | int > 0 %} +traefik.http.routers.matrix-appservice-irc-media-proxy.priority={{ matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_priority }} {% endif %} traefik.http.routers.matrix-appservice-irc-media-proxy.service=matrix-appservice-irc-media-proxy -traefik.http.routers.matrix-appservice-irc-media-proxy.entrypoints={{ matrix_appservice_irc_container_labels_media_proxy_traefik_entrypoints }} +traefik.http.routers.matrix-appservice-irc-media-proxy.entrypoints={{ matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_entrypoints }} {% if middlewares | length > 0 %} traefik.http.routers.matrix-appservice-irc-media-proxy.middlewares={{ middlewares | join(',') }} {% endif %} -traefik.http.routers.matrix-appservice-irc-media-proxy.tls={{ matrix_appservice_irc_container_labels_media_proxy_traefik_tls | to_json }} -{% if matrix_appservice_irc_container_labels_media_proxy_traefik_tls %} -traefik.http.routers.matrix-appservice-irc-media-proxy.tls.certResolver={{ matrix_appservice_irc_container_labels_media_proxy_traefik_tls_certResolver }} +traefik.http.routers.matrix-appservice-irc-media-proxy.tls={{ matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_tls | to_json }} +{% if matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_tls %} +traefik.http.routers.matrix-appservice-irc-media-proxy.tls.certResolver={{ matrix_bridge_appservice_irc_container_labels_media_proxy_traefik_tls_certResolver }} {% endif %} ############################################################ @@ -60,4 +60,4 @@ traefik.http.routers.matrix-appservice-irc-media-proxy.tls.certResolver={{ matri ############################################################ {% endif %} -{{ matrix_appservice_irc_container_labels_additional_labels }} +{{ matrix_bridge_appservice_irc_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-appservice-irc/templates/systemd/matrix-appservice-irc.service.j2 b/roles/custom/matrix-bridge-appservice-irc/templates/systemd/matrix-appservice-irc.service.j2 index 24a5d156b..881d7940f 100644 --- a/roles/custom/matrix-bridge-appservice-irc/templates/systemd/matrix-appservice-irc.service.j2 +++ b/roles/custom/matrix-bridge-appservice-irc/templates/systemd/matrix-appservice-irc.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Appservice IRC bridge -{% for service in matrix_appservice_irc_systemd_required_services_list %} +{% for service in matrix_bridge_appservice_irc_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_appservice_irc_systemd_wanted_services_list %} +{% for service in matrix_bridge_appservice_irc_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,26 +22,28 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_appservice_irc_container_network }} \ - {% if matrix_appservice_irc_container_http_host_bind_port %} - -p {{ matrix_appservice_irc_container_http_host_bind_port }}:9999 \ + --network={{ matrix_bridge_appservice_irc_container_network }} \ + {% if matrix_bridge_appservice_irc_container_http_host_bind_port %} + -p {{ matrix_bridge_appservice_irc_container_http_host_bind_port }}:9999 \ {% endif %} - {% if matrix_appservice_irc_container_media_proxy_host_bind_port %} - -p {{ matrix_appservice_irc_container_media_proxy_host_bind_port }}:{{ matrix_appservice_irc_ircService_mediaProxy_bindPort }} \ + {% if matrix_bridge_appservice_irc_container_media_proxy_host_bind_port %} + -p {{ matrix_bridge_appservice_irc_container_media_proxy_host_bind_port }}:{{ matrix_bridge_appservice_irc_ircService_mediaProxy_bindPort }} \ {% endif %} - --mount type=bind,src={{ matrix_appservice_irc_config_path }},dst=/config \ - --mount type=bind,src={{ matrix_appservice_irc_data_path }},dst=/data \ - --label-file={{ matrix_appservice_irc_base_path }}/labels \ - {% for arg in matrix_appservice_irc_container_extra_arguments %} + --mount type=bind,src={{ matrix_bridge_appservice_irc_config_path }},dst=/config \ + --mount type=bind,src={{ matrix_bridge_appservice_irc_data_path }},dst=/data \ + --label-file={{ matrix_bridge_appservice_irc_base_path }}/labels \ + {% for arg in matrix_bridge_appservice_irc_container_extra_arguments %} {{ arg }} \ {% endfor %} --entrypoint=/bin/bash \ - {{ matrix_appservice_irc_container_image }} \ + {{ matrix_bridge_appservice_irc_container_image }} \ -c 'node app.js -c /config/config.yaml -f /config/registration.yaml -p 9999' -{% for network in matrix_appservice_irc_container_additional_networks %} +{% if matrix_bridge_appservice_irc_container_network != 'host' %} +{% for network in matrix_bridge_appservice_irc_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-appservice-irc {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-appservice-irc diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/defaults/main.yml b/roles/custom/matrix-bridge-appservice-kakaotalk/defaults/main.yml deleted file mode 100644 index d680a7424..000000000 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/defaults/main.yml +++ /dev/null @@ -1,237 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2025 Slavi Pantaleev -# SPDX-FileCopyrightText: 2023 Nikita Chernyi -# SPDX-FileCopyrightText: 2024 MDAD project contributors -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- -# matrix-appservice-kakaotalk is a Matrix <-> Kakaotalk bridge -# Project source code URL: https://src.miscworks.net/fair/matrix-appservice-kakaotalk/ - -matrix_appservice_kakaotalk_enabled: true - -# No images are published for neither of the container images (appservice or node), so we're self-building everything. -matrix_appservice_kakaotalk_container_image_self_build: true -# matrix_appservice_kakaotalk_container_image_self_build_repo: "https://src.miscworks.net/fair/matrix-appservice-kakaotalk.git" -# -# hnarjis' fork is used instead of upstream (fair's), because upstream is currently broken. -# The following error happens when chatting up the bot without this fix: -# [2022-07-25 09:04:53,784] [ERROR@mau.as] Exception in Matrix event handler -# Traceback (most recent call last): -# File "/usr/lib/python3.9/site-packages/mautrix/appservice/as_handler.py", line 239, in try_handle -# await handler_func(event) -# File "/usr/lib/python3.9/site-packages/mautrix/bridge/matrix.py", line 820, in int_handle_event -# await self.int_handle_invite(evt) -# File "/usr/lib/python3.9/site-packages/mautrix/bridge/matrix.py", line 441, in int_handle_invite -# inviter = await self.bridge.get_user(evt.sender) -# File "/usr/lib/python3.9/site-packages/matrix_appservice_kakaotalk/__main__.py", line 112, in get_user -# return await User.get_by_mxid(user_id, create=create) -# File "/usr/lib/python3.9/site-packages/mautrix/util/async_getter_lock.py", line 60, in wrapper -# return await fn(cls, *args, **kwargs) -# File "/usr/lib/python3.9/site-packages/matrix_appservice_kakaotalk/user.py", line 227, in get_by_mxid -# user = cls(mxid) -# TypeError: __init__() missing 2 required positional arguments: 'force_login' and 'was_connected' -matrix_appservice_kakaotalk_container_image_self_build_repo: "https://src.miscworks.net/hnarjis/matrix-appservice-kakaotalk.git" -matrix_appservice_kakaotalk_container_image_self_build_repo_version: "{{ 'master' if matrix_appservice_kakaotalk_version == 'latest' else matrix_appservice_kakaotalk_version }}" - -matrix_appservice_kakaotalk_node_version: "{{ matrix_appservice_kakaotalk_version }}" -matrix_appservice_kakaotalk_node_container_image: "{{ matrix_appservice_kakaotalk_node_container_image_registry_prefix }}fair/matrix-appservice-kakaotalk-node:{{ matrix_appservice_kakaotalk_node_version }}" -matrix_appservice_kakaotalk_node_container_image_registry_prefix: "{{ 'localhost/' if matrix_appservice_kakaotalk_container_image_self_build else matrix_appservice_kakaotalk_node_container_image_registry_prefix_upstream }}" -matrix_appservice_kakaotalk_node_container_image_registry_prefix_upstream: "{{ matrix_appservice_kakaotalk_node_container_image_registry_prefix_upstream_default }}" -matrix_appservice_kakaotalk_node_container_image_registry_prefix_upstream_default: "" -matrix_appservice_kakaotalk_node_container_image_force_pull: "{{ matrix_appservice_kakaotalk_node_container_image.endswith(':latest') }}" - -matrix_appservice_kakaotalk_version: 86c038fd2ffee5e0aebf65136f085cce7e38b54e -matrix_appservice_kakaotalk_container_image: "{{ matrix_appservice_kakaotalk_container_image_registry_prefix }}fair/matrix-appservice-kakaotalk:{{ matrix_appservice_kakaotalk_version }}" -matrix_appservice_kakaotalk_container_image_registry_prefix: "{{ 'localhost/' if matrix_appservice_kakaotalk_container_image_self_build else matrix_appservice_kakaotalk_container_image_registry_prefix_upstream }}" -matrix_appservice_kakaotalk_container_image_registry_prefix_upstream: "{{ matrix_appservice_kakaotalk_container_image_registry_prefix_upstream_default }}" -matrix_appservice_kakaotalk_container_image_registry_prefix_upstream_default: "" -matrix_appservice_kakaotalk_container_image_force_pull: "{{ matrix_appservice_kakaotalk_container_image.endswith(':latest') }}" - -matrix_appservice_kakaotalk_base_path: "{{ matrix_base_data_path }}/appservice-kakaotalk" -matrix_appservice_kakaotalk_config_path: "{{ matrix_appservice_kakaotalk_base_path }}/config" -matrix_appservice_kakaotalk_data_path: "{{ matrix_appservice_kakaotalk_base_path }}/data" -matrix_appservice_kakaotalk_container_src_files_path: "{{ matrix_appservice_kakaotalk_base_path }}/docker-src" - -matrix_appservice_kakaotalk_command_prefix: "!kt" - -matrix_appservice_kakaotalk_homeserver_address: "" -matrix_appservice_kakaotalk_homeserver_domain: '{{ matrix_domain }}' -# Whether asynchronous uploads via MSC2246 should be enabled for media. -# Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_appservice_kakaotalk_homeserver_async_media: false -matrix_appservice_kakaotalk_appservice_address: 'http://matrix-appservice-kakaotalk:11115' - - -# A list of extra arguments to pass to the appservice-kakaotalk container -matrix_appservice_kakaotalk_container_extra_arguments: [] - -# List of systemd services that matrix-appservice-kakaotalk.service depends on. -matrix_appservice_kakaotalk_systemd_required_services_list: "{{ matrix_appservice_kakaotalk_systemd_required_services_list_default + matrix_appservice_kakaotalk_systemd_required_services_list_auto + matrix_appservice_kakaotalk_systemd_required_services_list_custom }}" -matrix_appservice_kakaotalk_systemd_required_services_list_default: |- - {{ - ([devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else []) - + - ['matrix-appservice-kakaotalk-node.service'] - }} -matrix_appservice_kakaotalk_systemd_required_services_list_auto: [] -matrix_appservice_kakaotalk_systemd_required_services_list_custom: [] - -# List of systemd services that matrix-appservice-kakaotalk.service wants -matrix_appservice_kakaotalk_systemd_wanted_services_list: [] - -matrix_appservice_kakaotalk_container_network: "" - -matrix_appservice_kakaotalk_container_additional_networks: "{{ matrix_appservice_kakaotalk_container_additional_networks_auto + matrix_appservice_kakaotalk_container_additional_networks_custom }}" -matrix_appservice_kakaotalk_container_additional_networks_auto: [] -matrix_appservice_kakaotalk_container_additional_networks_custom: [] - -# A list of extra arguments to pass to the appservice-kakaotalk-node container -matrix_appservice_kakaotalk_node_container_extra_arguments: [] - -# List of systemd services that matrix-appservice-kakaotalk-node.service depends on. -matrix_appservice_kakaotalk_node_systemd_required_services_list: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" - -# List of systemd services that matrix-appservice-kakaotalk-node.service wants -matrix_appservice_kakaotalk_node_systemd_wanted_services_list: [] - -matrix_appservice_kakaotalk_appservice_token: '' -matrix_appservice_kakaotalk_homeserver_token: '' - -# Whether or not created rooms should have federation enabled. -# If false, created portal rooms will never be federated. -matrix_appservice_kakaotalk_federate_rooms: true - -# Database-related configuration fields. -# -# To use SQLite: -# - change the engine (`matrix_appservice_kakaotalk_database_engine: 'sqlite'`) -# To use Postgres: -# - adjust your database credentials via the `matrix_appservice_kakaotalk_database_*` variables -matrix_appservice_kakaotalk_database_engine: 'postgres' - -matrix_appservice_kakaotalk_sqlite_database_path_local: "{{ matrix_appservice_kakaotalk_data_path }}/appservice-kakaotalk.db" -matrix_appservice_kakaotalk_sqlite_database_path_in_container: "/data/appservice-kakaotalk.db" - -matrix_appservice_kakaotalk_database_username: 'matrix_appservice_kakaotalk' -matrix_appservice_kakaotalk_database_password: 'some-password' -matrix_appservice_kakaotalk_database_hostname: '' -matrix_appservice_kakaotalk_database_port: 5432 -matrix_appservice_kakaotalk_database_name: 'matrix_appservice_kakaotalk' - -matrix_appservice_kakaotalk_database_connection_string: 'postgres://{{ matrix_appservice_kakaotalk_database_username }}:{{ matrix_appservice_kakaotalk_database_password }}@{{ matrix_appservice_kakaotalk_database_hostname }}:{{ matrix_appservice_kakaotalk_database_port }}/{{ matrix_appservice_kakaotalk_database_name }}' - -matrix_appservice_kakaotalk_appservice_database: "{{ - { - 'sqlite': ('sqlite:///' + matrix_appservice_kakaotalk_sqlite_database_path_in_container), - 'postgres': matrix_appservice_kakaotalk_database_connection_string, - }[matrix_appservice_kakaotalk_database_engine] -}}" - - -# Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). -# Also see: matrix_appservice_kakaotalk_bridge_login_shared_secret_map -matrix_appservice_kakaotalk_login_shared_secret: '' - -matrix_appservice_kakaotalk_bridge_login_shared_secret_map: "{{ {matrix_appservice_kakaotalk_homeserver_domain: matrix_appservice_kakaotalk_login_shared_secret} if matrix_appservice_kakaotalk_login_shared_secret else {} }}" - -matrix_appservice_kakaotalk_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" - -matrix_appservice_kakaotalk_bridge_permissions: | - {{ - {matrix_appservice_kakaotalk_homeserver_domain: 'user'} - | combine({matrix_admin: 'admin'} if matrix_admin else {}) - }} - -matrix_appservice_kakaotalk_appservice_bot_username: kakaotalkbot -matrix_appservice_kakaotalk_user_prefix: 'kakaotalk_' - -# End-to-bridge encryption configuration -matrix_appservice_kakaotalk_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_appservice_kakaotalk_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" - -# Specifies the default log level for all bridge loggers. -matrix_appservice_kakaotalk_logging_level: WARNING - - -# Default configuration template which covers the generic use case. -# You can customize it by controlling the various variables inside it. -# -# For a more advanced customization, you can extend the default (see `matrix_appservice_kakaotalk_configuration_extension_yaml`) -# or completely replace this variable with your own template. -matrix_appservice_kakaotalk_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" - -matrix_appservice_kakaotalk_configuration_extension_yaml: | - # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_appservice_kakaotalk_configuration_yaml`). - # - # You can override individual variables from the default configuration, or introduce new ones. - # - # If you need something more special, you can take full control by - # completely redefining `matrix_appservice_kakaotalk_configuration_yaml`. - -matrix_appservice_kakaotalk_configuration_extension: "{{ matrix_appservice_kakaotalk_configuration_extension_yaml | from_yaml if matrix_appservice_kakaotalk_configuration_extension_yaml | from_yaml is mapping else {} }}" - -# Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_appservice_kakaotalk_configuration_yaml`. -matrix_appservice_kakaotalk_configuration: "{{ matrix_appservice_kakaotalk_configuration_yaml | from_yaml | combine(matrix_appservice_kakaotalk_configuration_extension, recursive=True) }}" - - -# Default configuration template which covers the generic use case. -# You can customize it by controlling the various variables inside it. -# -# For a more advanced customization, you can extend the default (see `matrix_appservice_kakaotalk_node_configuration_extension_yaml`) -# or completely replace this variable with your own template. -# -# The side-effect of this lookup is that Ansible would even parse the JSON for us, returning a dict. -# This is unlike what it does when looking up YAML template files (no automatic parsing there). -matrix_appservice_kakaotalk_node_configuration_default: "{{ lookup('template', 'templates/node-config.json.j2', convert_data=False) | from_json }}" - -# Your custom JSON configuration for appservice-kakaotalk-node should go to `matrix_appservice_kakaotalk_node_configuration_extension_json`. -# This configuration extends the default starting configuration (`matrix_appservice_kakaotalk_node_configuration_default`). -# -# You can override individual variables from the default configuration, or introduce new ones. -# -# If you need something more special, you can take full control by -# completely redefining `matrix_appservice_kakaotalk_node_configuration_default`. -# -# Example configuration extension follows: -# -# matrix_appservice_kakaotalk_node_configuration_extension_json: | -# { -# "register_timeout": 5000 -# } -matrix_appservice_kakaotalk_node_configuration_extension_json: '{}' - -matrix_appservice_kakaotalk_node_configuration_extension: "{{ matrix_appservice_kakaotalk_node_configuration_extension_json | from_json if matrix_appservice_kakaotalk_node_configuration_extension_json | from_json is mapping else {} }}" - -# Holds the final appservice-kakaotalk-node configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_appservice_kakaotalk_node_configuration_default`. -matrix_appservice_kakaotalk_node_configuration: "{{ matrix_appservice_kakaotalk_node_configuration_default | combine(matrix_appservice_kakaotalk_node_configuration_extension, recursive=True) }}" - - -matrix_appservice_kakaotalk_registration_yaml: | - id: appservice-kakaotalk - as_token: {{ matrix_appservice_kakaotalk_appservice_token | to_json }} - hs_token: {{ matrix_appservice_kakaotalk_homeserver_token | to_json }} - namespaces: - users: - - exclusive: true - regex: '^@{{ matrix_appservice_kakaotalk_user_prefix | regex_escape }}.*:{{ matrix_appservice_kakaotalk_homeserver_domain | regex_escape }}$' - - exclusive: true - regex: '^@{{ matrix_appservice_kakaotalk_appservice_bot_username | regex_escape }}:{{ matrix_appservice_kakaotalk_homeserver_domain | regex_escape }}$' - url: {{ matrix_appservice_kakaotalk_appservice_address | to_json }} - sender_localpart: _appservice_kakaotalk - rate_limited: false - -matrix_appservice_kakaotalk_registration: "{{ matrix_appservice_kakaotalk_registration_yaml | from_yaml }}" - -# matrix_appservice_kakaotalk_restart_necessary controls whether the service -# will be restarted (when true) or merely started (when false) by the -# systemd service manager role (when conditional restart is enabled). -# -# This value is automatically computed during installation based on whether -# any configuration files, the systemd service file, or the container image changed. -# The default of `false` means "no restart needed" — appropriate when the role's -# installation tasks haven't run (e.g., due to --tags skipping them). -matrix_appservice_kakaotalk_restart_necessary: false diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/setup_install.yml b/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/setup_install.yml deleted file mode 100644 index ad9e85963..000000000 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/setup_install.yml +++ /dev/null @@ -1,141 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 Sebastian Gumprich -# SPDX-FileCopyrightText: 2024 David Mehren -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Ensure matrix-appservice-kakaotalk image is pulled - community.docker.docker_image: - name: "{{ matrix_appservice_kakaotalk_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_appservice_kakaotalk_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_appservice_kakaotalk_container_image_force_pull }}" - when: not matrix_appservice_kakaotalk_container_image_self_build - register: matrix_appservice_kakaotalk_container_image_pull_result - retries: "{{ devture_playbook_help_container_retries_count }}" - delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_appservice_kakaotalk_container_image_pull_result is not failed - -- name: Ensure matrix-appservice-kakaotalk-node image is pulled - community.docker.docker_image: - name: "{{ matrix_appservice_kakaotalk_node_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_appservice_kakaotalk_node_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_appservice_kakaotalk_node_container_image_force_pull }}" - when: not matrix_appservice_kakaotalk_container_image_self_build - register: matrix_appservice_kakaotalk_node_container_image_pull_result - retries: "{{ devture_playbook_help_container_retries_count }}" - delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_appservice_kakaotalk_node_container_image_pull_result is not failed - -- name: Ensure matrix-appservice-kakaotalk paths exist - ansible.builtin.file: - path: "{{ item.path }}" - state: directory - mode: '0750' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - with_items: - - {path: "{{ matrix_appservice_kakaotalk_base_path }}", when: true} - - {path: "{{ matrix_appservice_kakaotalk_config_path }}", when: true} - - {path: "{{ matrix_appservice_kakaotalk_data_path }}", when: true} - - {path: "{{ matrix_appservice_kakaotalk_container_src_files_path }}", when: "{{ matrix_appservice_kakaotalk_container_image_self_build }}"} - when: item.when | bool - -- name: Ensure matrix-appservice-kakaotalk repository is present on self-build - ansible.builtin.git: - repo: "{{ matrix_appservice_kakaotalk_container_image_self_build_repo }}" - dest: "{{ matrix_appservice_kakaotalk_container_src_files_path }}" - version: "{{ matrix_appservice_kakaotalk_container_image_self_build_repo_version }}" - force: "yes" - become: true - become_user: "{{ matrix_user_name }}" - register: matrix_appservice_kakaotalk_git_pull_results - when: "matrix_appservice_kakaotalk_container_image_self_build | bool" - -- name: Ensure matrix-appservice-kakaotalk-node Docker image is built - community.docker.docker_image: - name: "{{ matrix_appservice_kakaotalk_node_container_image }}" - source: build - force_source: "{{ matrix_appservice_kakaotalk_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_appservice_kakaotalk_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_appservice_kakaotalk_container_src_files_path }}/node" - pull: true - when: "matrix_appservice_kakaotalk_container_image_self_build | bool" - -- name: Ensure matrix-appservice-kakaotalk Docker image is built - community.docker.docker_image: - name: "{{ matrix_appservice_kakaotalk_container_image }}" - source: build - force_source: "{{ matrix_appservice_kakaotalk_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_appservice_kakaotalk_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_appservice_kakaotalk_container_src_files_path }}" - pull: true - when: "matrix_appservice_kakaotalk_container_image_self_build | bool" - -- name: Ensure matrix-appservice-kakaotalk-node config.json installed - ansible.builtin.copy: - content: "{{ matrix_appservice_kakaotalk_node_configuration | to_nice_json }}" - dest: "{{ matrix_appservice_kakaotalk_config_path }}/node-config.json" - mode: '0644' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - register: matrix_appservice_kakaotalk_node_config_result - -- name: Ensure matrix-appservice-kakaotalk config.yaml installed - ansible.builtin.copy: - content: "{{ matrix_appservice_kakaotalk_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_appservice_kakaotalk_config_path }}/config.yaml" - mode: '0644' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - register: matrix_appservice_kakaotalk_config_result - -- name: Ensure matrix-appservice-kakaotalk registration.yaml installed - ansible.builtin.copy: - content: "{{ matrix_appservice_kakaotalk_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_appservice_kakaotalk_config_path }}/registration.yaml" - mode: '0644' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - register: matrix_appservice_kakaotalk_registration_result - -- name: Ensure matrix-appservice-kakaotalk container network is created - community.general.docker_network: - enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_appservice_kakaotalk_container_network }}" - driver: bridge - driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - -- name: Ensure matrix-appservice-kakaotalk-node.service installed - ansible.builtin.template: - src: "{{ role_path }}/templates/systemd/matrix-appservice-kakaotalk-node.service.j2" - dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-kakaotalk-node.service" - mode: '0644' - register: matrix_appservice_kakaotalk_node_systemd_service_result - -- name: Ensure matrix-appservice-kakaotalk.service installed - ansible.builtin.template: - src: "{{ role_path }}/templates/systemd/matrix-appservice-kakaotalk.service.j2" - dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-kakaotalk.service" - mode: '0644' - register: matrix_appservice_kakaotalk_systemd_service_result - -- name: Determine whether matrix-appservice-kakaotalk needs a restart - ansible.builtin.set_fact: - matrix_appservice_kakaotalk_restart_necessary: >- - {{ - matrix_appservice_kakaotalk_node_config_result.changed | default(false) - or matrix_appservice_kakaotalk_config_result.changed | default(false) - or matrix_appservice_kakaotalk_registration_result.changed | default(false) - or matrix_appservice_kakaotalk_node_systemd_service_result.changed | default(false) - or matrix_appservice_kakaotalk_systemd_service_result.changed | default(false) - or matrix_appservice_kakaotalk_container_image_pull_result.changed | default(false) - or matrix_appservice_kakaotalk_node_container_image_pull_result.changed | default(false) - }} diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/setup_uninstall.yml deleted file mode 100644 index f92960991..000000000 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/setup_uninstall.yml +++ /dev/null @@ -1,40 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Slavi Pantaleev -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Check existence of matrix-appservice-kakaotalk service - ansible.builtin.stat: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-kakaotalk.service" - register: matrix_appservice_kakaotalk_service_stat - -- name: Ensure matrix-appservice-kakaotalk is stopped - ansible.builtin.service: - name: matrix-appservice-kakaotalk - state: stopped - enabled: false - daemon_reload: true - when: matrix_appservice_kakaotalk_service_stat.stat.exists | bool - -- name: Check existence of matrix-appservice-kakaotalk-node service - ansible.builtin.stat: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-kakaotalk-node.service" - register: matrix_appservice_kakaotalk_node_service_stat - -- name: Ensure matrix-appservice-kakaotalk-node is stopped - ansible.builtin.service: - name: matrix-appservice-kakaotalk-node - state: stopped - enabled: false - daemon_reload: true - when: matrix_appservice_kakaotalk_node_service_stat.stat.exists | bool - -- name: Ensure matrix-appservice-kakaotalk.service files don't exist - ansible.builtin.file: - path: "{{ item }}" - state: absent - with_items: - - "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-kakaotalk-node.service" - - "{{ devture_systemd_docker_base_systemd_path }}/matrix-appservice-kakaotalk.service" - when: matrix_appservice_kakaotalk_service_stat.stat.exists | bool or matrix_appservice_kakaotalk_node_service_stat.stat.exists | bool diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/validate_config.yml b/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/validate_config.yml deleted file mode 100644 index 4b895bee6..000000000 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/validate_config.yml +++ /dev/null @@ -1,39 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2025 Slavi Pantaleev -# SPDX-FileCopyrightText: 2025 Suguru Hirahara -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: (Deprecation) Catch and report renamed appservice-kakaotalk variables - ansible.builtin.fail: - msg: >- - Your configuration contains a variable, which now has a different name. - Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). - when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" - with_items: - - {'old': 'matrix_appservice_kakaotalk_node_docker_image_name_prefix', 'new': 'matrix_appservice_kakaotalk_node_container_image_registry_prefix'} - - {'old': 'matrix_appservice_kakaotalk_docker_image_name_prefix', 'new': 'matrix_appservice_kakaotalk_container_image_registry_prefix'} - - {'old': 'matrix_appservice_kakaotalk_docker_image', 'new': 'matrix_appservice_kakaotalk_container_image'} - - {'old': 'matrix_appservice_kakaotalk_docker_image_force_pull', 'new': 'matrix_appservice_kakaotalk_container_image_force_pull'} - - {'old': 'matrix_appservice_kakaotalk_docker_image_registry_prefix', 'new': 'matrix_appservice_kakaotalk_container_image_registry_prefix'} - - {'old': 'matrix_appservice_kakaotalk_docker_image_registry_prefix_upstream', 'new': 'matrix_appservice_kakaotalk_container_image_registry_prefix_upstream'} - - {'old': 'matrix_appservice_kakaotalk_docker_image_registry_prefix_upstream_default', 'new': 'matrix_appservice_kakaotalk_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_appservice_kakaotalk_docker_src_files_path', 'new': 'matrix_appservice_kakaotalk_container_src_files_path'} - - {'old': 'matrix_appservice_kakaotalk_node_docker_image', 'new': 'matrix_appservice_kakaotalk_node_container_image'} - - {'old': 'matrix_appservice_kakaotalk_node_docker_image_force_pull', 'new': 'matrix_appservice_kakaotalk_node_container_image_force_pull'} - - {'old': 'matrix_appservice_kakaotalk_node_docker_image_registry_prefix', 'new': 'matrix_appservice_kakaotalk_node_container_image_registry_prefix'} - - {'old': 'matrix_appservice_kakaotalk_node_docker_image_registry_prefix_upstream', 'new': 'matrix_appservice_kakaotalk_node_container_image_registry_prefix_upstream'} - - {'old': 'matrix_appservice_kakaotalk_node_docker_image_registry_prefix_upstream_default', 'new': 'matrix_appservice_kakaotalk_node_container_image_registry_prefix_upstream_default'} - -- name: Fail if required appservice-kakaotalk settings not defined - ansible.builtin.fail: - msg: >- - You need to define a required configuration setting (`{{ item.name }}`). - when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" - with_items: - - {'name': 'matrix_appservice_kakaotalk_appservice_token', when: true} - - {'name': 'matrix_appservice_kakaotalk_homeserver_address', when: true} - - {'name': 'matrix_appservice_kakaotalk_homeserver_token', when: true} - - {'name': 'matrix_appservice_kakaotalk_database_hostname', when: "{{ matrix_appservice_kakaotalk_database_engine == 'postgres' }}"} - - {'name': 'matrix_appservice_kakaotalk_container_network', when: true} diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/config.yaml.j2 b/roles/custom/matrix-bridge-appservice-kakaotalk/templates/config.yaml.j2 deleted file mode 100644 index 0f76a976b..000000000 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/config.yaml.j2 +++ /dev/null @@ -1,276 +0,0 @@ -# Homeserver details -homeserver: - # The address that this appservice can use to connect to the homeserver. - address: {{ matrix_appservice_kakaotalk_homeserver_address | to_json }} - # The domain of the homeserver (for MXIDs, etc). - domain: {{ matrix_appservice_kakaotalk_homeserver_domain | to_json }} - # Whether or not to verify the SSL certificate of the homeserver. - # Only applies if address starts with https:// - verify_ssl: true - # Whether or not the homeserver supports asmux-specific endpoints, - # such as /_matrix/client/unstable/net.maunium.asmux/dms for atomically - # updating m.direct. - asmux: false - # Number of retries for all HTTP requests if the homeserver isn't reachable. - http_retry_count: 4 - # The URL to push real-time bridge status to. - # If set, the bridge will make POST requests to this URL whenever a user's MQTT connection state changes. - # The bridge will use the appservice as_token to authorize requests. - status_endpoint: null - # Endpoint for reporting per-message status. - message_send_checkpoint_endpoint: null - # Whether asynchronous uploads via MSC2246 should be enabled for media. - # Requires a media repo that supports MSC2246. - async_media: {{ matrix_appservice_kakaotalk_homeserver_async_media | to_json }} - -# Application service host/registration related details -# Changing these values requires regeneration of the registration. -appservice: - # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_appservice_kakaotalk_appservice_address | to_json }} - - # The hostname and port where this appservice should listen. - hostname: 0.0.0.0 - port: 11115 - # The maximum body size of appservice API requests (from the homeserver) in mebibytes - # Usually 1 is enough, but on high-traffic bridges you might need to increase this to avoid 413s - max_body_size: 1 - - # The full URI to the database. SQLite and Postgres are supported. - # Format examples: - # SQLite: sqlite:///filename.db - # Postgres: postgres://username:password@hostname/dbname - database: {{ matrix_appservice_kakaotalk_appservice_database | to_json }} - # Additional arguments for asyncpg.create_pool() or sqlite3.connect() - # https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.pool.create_pool - # https://docs.python.org/3/library/sqlite3.html#sqlite3.connect - # For sqlite, min_size is used as the connection thread pool size and max_size is ignored. - database_opts: - min_size: 5 - max_size: 10 - - # The unique ID of this appservice. - id: appservice-kakaotalk - # Username of the appservice bot. - bot_username: {{ matrix_appservice_kakaotalk_appservice_bot_username | to_json }} - # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty - # to leave display name/avatar as-is. - bot_displayname: KakaoTalk bridge bot - bot_avatar: - - # Whether or not to receive ephemeral events via appservice transactions. - # Requires MSC2409 support (i.e. Synapse 1.22+). - # You should disable bridge -> sync_with_custom_puppets when this is enabled. - ephemeral_events: false - - # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_appservice_kakaotalk_appservice_token | to_json }} - hs_token: {{ matrix_appservice_kakaotalk_homeserver_token | to_json }} - -# Prometheus telemetry config. Requires prometheus-client to be installed. -metrics: - enabled: false - listen_port: 8000 - -# Manhole config. -manhole: - # Whether or not opening the manhole is allowed. - enabled: false - # The path for the unix socket. - path: /var/tmp/matrix-appservice-kakaotalk.manhole - # The list of UIDs who can be added to the whitelist. - # If empty, any UIDs can be specified in the open-manhole command. - whitelist: - - 0 - -# Config for things that are directly sent to KakaoTalk. -kakaotalk: - device_name: "KakaoTalk Bridge" - -# Bridge config -bridge: - # Localpart template of MXIDs for KakaoTalk users. - # {userid} is replaced with the user ID of the KakaoTalk user. - username_template: "{{ matrix_appservice_kakaotalk_user_prefix }}{userid}" - # Displayname template for KakaoTalk users. - # {displayname} is replaced with the display name of the KakaoTalk user. - displayname_template: "{displayname} (KT)" - - # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_appservice_kakaotalk_command_prefix | to_json }} - - # Number of chats to sync (and create portals for) on startup/login. - # Set to 0 to disable automatic syncing, or -1 to sync as much as possible. - initial_chat_sync: 20 - # Whether or not the KakaoTalk users of logged in Matrix users should be - # invited to private chats when the user sends a message from another client. - invite_own_puppet_to_pm: false - # Whether or not to use /sync to get presence, read receipts and typing notifications - # when double puppeting is enabled - sync_with_custom_puppets: true - # Whether or not to update the m.direct account data event when double puppeting is enabled. - # Note that updating the m.direct event is not atomic (except with mautrix-asmux) - # and is therefore prone to race conditions. - sync_direct_chat_list: false - # Servers to always allow double puppeting from - double_puppet_server_map: {} - # Allow using double puppeting from any server with a valid client .well-known file. - double_puppet_allow_discovery: false - # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth - # - # If set, custom puppets will be enabled automatically for local users - # instead of users having to find an access token and run `login-matrix` - # manually. - # If using this for other servers than the bridge's server, - # you must also set the URL in the double_puppet_server_map. - login_shared_secret_map: {{ matrix_appservice_kakaotalk_bridge_login_shared_secret_map | to_json }} - # Whether or not to update avatars when syncing all contacts at startup. - update_avatar_initial_sync: true - # End-to-bridge encryption support options. These require matrix-nio to be installed with pip - # and login_shared_secret to be configured in order to get a device for the bridge bot. - # - # Additionally, https://github.com/matrix-org/synapse/pull/5758 is required if using a normal - # application service. - encryption: - # Allow encryption, work in group chat rooms with e2ee enabled - allow: {{ matrix_appservice_kakaotalk_bridge_encryption_allow | to_json }} - # Default to encryption, force-enable encryption in all portals the bridge creates - # This will cause the bridge bot to be in private chats for the encryption to work properly. - default: {{ matrix_appservice_kakaotalk_bridge_encryption_default| to_json }} - # Options for automatic key sharing. - key_sharing: - # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. - # You must use a client that supports requesting keys from other users to use this feature. - allow: false - # Require the requesting device to have a valid cross-signing signature? - # This doesn't require that the bridge has verified the device, only that the user has verified it. - # Not yet implemented. - require_cross_signing: false - # Require devices to be verified by the bridge? - # Verification by the bridge is not yet implemented. - require_verification: true - # Whether or not the bridge should send a read receipt from the bridge bot when a message has - # been sent to KakaoTalk. - delivery_receipts: false - # Whether to allow inviting arbitrary mxids to portal rooms - allow_invites: false - # Whether or not created rooms should have federation enabled. - # If false, created portal rooms will never be federated. - federate_rooms: {{ matrix_appservice_kakaotalk_federate_rooms | to_json }} - # Settings for backfilling messages from KakaoTalk. - backfill: - # Whether or not the KakaoTalk users of logged in Matrix users should be - # invited to private chats when backfilling history from KakaoTalk. This is - # usually needed to prevent rate limits and to allow timestamp massaging. - invite_own_puppet: true - # Maximum number of messages to backfill initially. - # Set to 0 to disable backfilling when creating portal, or -1 to backfill as much as possible. - initial_limit: 0 - # Maximum number of messages to backfill if messages were missed while - # the bridge was disconnected. - # Set to 0 to disable backfilling missed messages, or -1 to backfill as much as possible. - missed_limit: 1000 - # If using double puppeting, should notifications be disabled - # while the initial backfill is in progress? - disable_notifications: false - # The number of seconds that a disconnection can last without triggering an automatic re-sync - # and missed message backfilling when reconnecting. - # Set to 0 to always re-sync, or -1 to never re-sync automatically. - resync_max_disconnected_time: 5 - # Should users remain logged in after being disconnected from chatroom updates? - # This is a convenience feature, but might make the bridge look more suspicious to KakaoTalk. - remain_logged_in_on_disconnect: true - # May the bridge restore user logins with session tokens instead of requiring a password? - # This is a convenience feature, but might make the bridge look more suspicious to KakaoTalk. - # Note that password-based login will be tried first for users who have saved their password. - allow_token_relogin: true - # Should the bridge connect users to chatroom updates after a token-based login? - # This will disconnect any KakaoTalk PC/bridge sessions that were started since the last connection. - # This is a convenience feature, but might make the bridge look more suspicious to KakaoTalk. - reconnect_on_token_relogin: true - # Should the bridge do a resync for connected users on startup? - sync_on_startup: true - # Whether or not temporary disconnections should send notices to the notice room. - # If this is false, disconnections will never send messages and connections will only send - # messages if it was disconnected for more than resync_max_disconnected_time seconds. - temporary_disconnect_notices: true - # Disable bridge notices entirely - disable_bridge_notices: false - # Set this to true to tell the bridge to re-send m.bridge events to all rooms on the next run. - # This field will automatically be changed back to false after it, - # except if the config file is not writable. - resend_bridge_info: false - # Whether or not mute status and tags should only be bridged when the portal room is created. - tag_only_on_create: true - # If set to true, downloading media from the CDN will use a plain aiohttp client without the usual headers or - # other configuration. This may be useful if you don't want to use the default proxy for large files. - sandbox_media_download: false - - # Permissions for using the bridge. - # Permitted values: - # relay - Allowed to be relayed through the bridge, no access to commands. - # user - Use the bridge with puppeting. - # admin - Use and administrate the bridge. - # Permitted keys: - # * - All Matrix users - # domain - All users on that homeserver - # mxid - Specific user - permissions: {{ matrix_appservice_kakaotalk_bridge_permissions | to_json }} - - relay: - # Whether relay mode should be allowed. If allowed, `!kt set-relay` can be used to turn any - # authenticated user into a relaybot for that chat. - enabled: {{ matrix_appservice_kakaotalk_bridge_relay_enabled }} - # The formats to use when sending messages to KakaoTalk via a relay user. - # - # Available variables: - # $sender_displayname - The display name of the sender (e.g. Example User) - # $sender_username - The username (Matrix ID localpart) of the sender (e.g. alice) - # $sender_mxid - The Matrix ID of the sender (e.g. @alice:example.com) - # $message - The message content - message_formats: - m.text: '$sender_displayname: $message' - m.notice: '$sender_displayname: $message' - m.emote: '* $sender_displayname $message' - m.file: 'File from $sender_displayname: $message' - m.image: 'Image from $sender_displayname: $message' - m.audio: 'Audio from $sender_displayname: $message' - m.video: 'Video from $sender_displayname: $message' - m.location: '$sender_displayname sent a location' - -rpc: - connection: - # Either unix or tcp - type: tcp - # Only for type: unix - # path: /rpc/rpc.sock - # Only for type: tcp - host: matrix-appservice-kakaotalk-node - port: 8000 - -# Python logging configuration. -# -# See section 16.7.2 of the Python documentation for more info: -# https://docs.python.org/3.6/library/logging.config.html#configuration-dictionary-schema -logging: - version: 1 - formatters: - colored: - (): matrix_appservice_kakaotalk.util.ColorFormatter - format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s" - normal: - format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s" - handlers: - console: - class: logging.StreamHandler - formatter: colored - loggers: - mau: - level: {{ matrix_appservice_kakaotalk_logging_level | to_json }} - paho: - level: {{ matrix_appservice_kakaotalk_logging_level | to_json }} - aiohttp: - level: {{ matrix_appservice_kakaotalk_logging_level | to_json }} - root: - level: {{ matrix_appservice_kakaotalk_logging_level | to_json }} - handlers: [console] diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/config.yaml.j2.license b/roles/custom/matrix-bridge-appservice-kakaotalk/templates/config.yaml.j2.license deleted file mode 100644 index 8b6d0c244..000000000 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/config.yaml.j2.license +++ /dev/null @@ -1,6 +0,0 @@ -SPDX-FileCopyrightText: 2022 MDAD project contributors -SPDX-FileCopyrightText: 2022 Slavi Pantaleev -SPDX-FileCopyrightText: 2023 Nikita Chernyi -SPDX-FileCopyrightText: 2024 Suguru Hirahara - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/node-config.json.j2 b/roles/custom/matrix-bridge-appservice-kakaotalk/templates/node-config.json.j2 deleted file mode 100644 index 827091382..000000000 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/node-config.json.j2 +++ /dev/null @@ -1,13 +0,0 @@ -{ - "listen": { - "type": "tcp", - "host": "0.0.0.0", - "port": 8000, - "force": false - }, - "register_timeout": 3000, - "logging_keys": { - "request": ["mxid"], - "response": ["status"] - } -} diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/node-config.json.j2.license b/roles/custom/matrix-bridge-appservice-kakaotalk/templates/node-config.json.j2.license deleted file mode 100644 index 7b1e56adc..000000000 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/node-config.json.j2.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2022 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk-node.service.j2.license b/roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk-node.service.j2.license deleted file mode 100644 index b2bdc9cb4..000000000 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk-node.service.j2.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2022 - 2025 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk.service.j2.license b/roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk.service.j2.license deleted file mode 100644 index 7b1e56adc..000000000 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk.service.j2.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2022 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-beeper-line/defaults/main.yml b/roles/custom/matrix-bridge-beeper-line/defaults/main.yml new file mode 100644 index 000000000..7d07a77a8 --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/defaults/main.yml @@ -0,0 +1,234 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# beeper-line is a Matrix <-> LINE bridge +# Project source code URL: https://github.com/beeper/line + +matrix_bridge_beeper_line_enabled: true + +matrix_bridge_beeper_line_container_image_self_build: false +matrix_bridge_beeper_line_container_image_self_build_repo: "https://github.com/beeper/line.git" +matrix_bridge_beeper_line_container_image_self_build_branch: "{{ 'main' if matrix_bridge_beeper_line_version == 'latest' else matrix_bridge_beeper_line_version }}" + +# Unlike other components, this one is pinned to a commit hash and not to a version number. +# beeper-line's release tags are not maintained: the latest one (1.2.0) dates back to 2026-05-17 and lags behind the `main` branch by more than a hundred bugfix commits. +# This is because upstream releases by deploying the `main` branch from CI, not by tagging. +# Pinning to a tag would mean shipping a bridge which misses months' worth of fixes, so we pin to a commit from `main` instead. +# A side effect is that Renovate cannot track updates for this component, so its version needs to be bumped manually. +matrix_bridge_beeper_line_version: 412eda7f028f0ee946d6fe584c64c7e97f27c7a7 + +# Upstream does not publish container images publicly (its CI only pushes to Beeper's private registry), so this is a community-maintained image built from the upstream source. +# It is only available for the amd64 architecture, which is why the playbook falls back to self-building on other architectures. +# To use another prebuilt image, override this variable directly. +matrix_bridge_beeper_line_container_image: "{{ matrix_bridge_beeper_line_container_image_registry_prefix }}crispyduck/beeper-line:{{ matrix_bridge_beeper_line_version }}" +matrix_bridge_beeper_line_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_beeper_line_container_image_self_build else matrix_bridge_beeper_line_container_image_registry_prefix_upstream }}" +matrix_bridge_beeper_line_container_image_registry_prefix_upstream: "{{ matrix_bridge_beeper_line_container_image_registry_prefix_upstream_default }}" +matrix_bridge_beeper_line_container_image_registry_prefix_upstream_default: "docker.io/" + +matrix_bridge_beeper_line_base_path: "{{ matrix_base_data_path }}/beeper-line" +matrix_bridge_beeper_line_config_path: "{{ matrix_bridge_beeper_line_base_path }}/config" +matrix_bridge_beeper_line_data_path: "{{ matrix_bridge_beeper_line_base_path }}/data" +matrix_bridge_beeper_line_container_src_files_path: "{{ matrix_bridge_beeper_line_base_path }}/docker-src" + +matrix_bridge_beeper_line_homeserver_address: "" +# Whether asynchronous uploads via MSC2246 should be enabled for media. +# Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). +matrix_bridge_beeper_line_homeserver_async_media: false +matrix_bridge_beeper_line_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_beeper_line_appservice_address: "http://matrix-beeper-line:29322" + +# Scheme of the bridge's public address (see `matrix_bridge_beeper_line_bridge_public_address`). +matrix_bridge_beeper_line_scheme: https + +# The public base URL at which this bridge's HTTP API is reachable from outside (when exposed). +# Used for the provisioning API's external-server (OpenID) flow. +matrix_bridge_beeper_line_bridge_public_address: "{{ (matrix_bridge_beeper_line_scheme + '://' + matrix_bridge_beeper_line_exposure_hostname + matrix_bridge_beeper_line_exposure_path_prefix) if matrix_bridge_beeper_line_exposure_enabled else '' }}" + +matrix_bridge_beeper_line_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_beeper_line_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" + +matrix_bridge_beeper_line_backfill_enabled: false +matrix_bridge_beeper_line_backfill_max_initial_messages: 50 +matrix_bridge_beeper_line_backfill_max_catchup_messages: 500 +matrix_bridge_beeper_line_backfill_unread_hours_threshold: 720 + +matrix_bridge_beeper_line_command_prefix: "!line" + +matrix_bridge_beeper_line_container_network: "" + +matrix_bridge_beeper_line_container_additional_networks: "{{ matrix_bridge_beeper_line_container_additional_networks_auto + matrix_bridge_beeper_line_container_additional_networks_custom }}" +matrix_bridge_beeper_line_container_additional_networks_auto: [] +matrix_bridge_beeper_line_container_additional_networks_custom: [] + +# matrix_bridge_beeper_line_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# See `../templates/labels.j2` for details. +# +# To inject your own other container labels, see `matrix_bridge_beeper_line_container_labels_additional_labels`. +matrix_bridge_beeper_line_container_labels_traefik_enabled: true +matrix_bridge_beeper_line_container_labels_traefik_docker_network: "{{ matrix_bridge_beeper_line_container_network }}" +matrix_bridge_beeper_line_container_labels_traefik_entrypoints: web-secure +matrix_bridge_beeper_line_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose beeper-line's HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_beeper_line_container_labels_exposure_enabled: "{{ matrix_bridge_beeper_line_exposure_enabled }}" +matrix_bridge_beeper_line_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_beeper_line_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_beeper_line_exposure_path_prefix }}`)" +matrix_bridge_beeper_line_container_labels_exposure_traefik_priority: 0 +matrix_bridge_beeper_line_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_beeper_line_container_labels_traefik_entrypoints }}" +matrix_bridge_beeper_line_container_labels_exposure_traefik_tls: "{{ matrix_bridge_beeper_line_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_beeper_line_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_beeper_line_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_beeper_line_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# See `../templates/labels.j2` for details. +# +# Example: +# matrix_bridge_beeper_line_container_labels_additional_labels: | +# my.label=1 +# another.label="here" +matrix_bridge_beeper_line_container_labels_additional_labels: '' + +# A list of extra arguments to pass to the container +matrix_bridge_beeper_line_container_extra_arguments: [] + +# List of systemd services that matrix-beeper-line.service depends on. +matrix_bridge_beeper_line_systemd_required_services_list: "{{ matrix_bridge_beeper_line_systemd_required_services_list_default + matrix_bridge_beeper_line_systemd_required_services_list_auto + matrix_bridge_beeper_line_systemd_required_services_list_custom }}" +matrix_bridge_beeper_line_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_beeper_line_systemd_required_services_list_auto: [] +matrix_bridge_beeper_line_systemd_required_services_list_custom: [] + +# List of systemd services that matrix-beeper-line.service wants +matrix_bridge_beeper_line_systemd_wanted_services_list: [] + +matrix_bridge_beeper_line_appservice_token: '' +matrix_bridge_beeper_line_homeserver_token: '' + +matrix_bridge_beeper_line_appservice_bot_username: linebot +matrix_bridge_beeper_line_appservice_bot_displayname: LINE bridge bot +matrix_bridge_beeper_line_appservice_bot_avatar: '' + +# Minimum severity of journal log messages. +# Valid values: fatal, error, warn, info, debug, trace +matrix_bridge_beeper_line_logging_level: 'warn' + +# Whether or not created rooms should have federation enabled. +# If false, created portal rooms will never be federated. +matrix_bridge_beeper_line_federate_rooms: true + +# Controls whether beeper-line's HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_beeper_line_exposure_enabled: false +matrix_bridge_beeper_line_exposure_hostname: '' +matrix_bridge_beeper_line_exposure_path_prefix: '' + +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_bridge_beeper_line_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_beeper_line_database_*` variables +matrix_bridge_beeper_line_database_engine: 'sqlite' + +matrix_bridge_beeper_line_sqlite_database_path_local: "{{ matrix_bridge_beeper_line_data_path }}/matrix-line.db" +matrix_bridge_beeper_line_sqlite_database_path_in_container: "file:/data/matrix-line.db?_txlock=immediate" + +matrix_bridge_beeper_line_database_username: 'matrix_beeper_line' +matrix_bridge_beeper_line_database_password: 'some-password' +matrix_bridge_beeper_line_database_hostname: '' +matrix_bridge_beeper_line_database_port: 5432 +matrix_bridge_beeper_line_database_name: 'matrix_beeper_line' +matrix_bridge_beeper_line_database_sslmode: disable + +matrix_bridge_beeper_line_database_connection_string: 'postgresql://{{ matrix_bridge_beeper_line_database_username }}:{{ matrix_bridge_beeper_line_database_password }}@{{ matrix_bridge_beeper_line_database_hostname }}:{{ matrix_bridge_beeper_line_database_port }}/{{ matrix_bridge_beeper_line_database_name }}?sslmode={{ matrix_bridge_beeper_line_database_sslmode }}' + +matrix_bridge_beeper_line_appservice_database_type: "{{ { + 'sqlite': 'sqlite3-fk-wal', + 'postgres': 'postgres', +}[matrix_bridge_beeper_line_database_engine] }}" + +matrix_bridge_beeper_line_appservice_database_uri: "{{ { + 'sqlite': matrix_bridge_beeper_line_sqlite_database_path_in_container, + 'postgres': matrix_bridge_beeper_line_database_connection_string, +}[matrix_bridge_beeper_line_database_engine] }}" + +matrix_bridge_beeper_line_double_puppet_secrets: "{{ matrix_bridge_beeper_line_double_puppet_secrets_auto | combine(matrix_bridge_beeper_line_double_puppet_secrets_custom) }}" +matrix_bridge_beeper_line_double_puppet_secrets_auto: {} +matrix_bridge_beeper_line_double_puppet_secrets_custom: {} + +# Enable End-to-bridge encryption +matrix_bridge_beeper_line_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_beeper_line_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_beeper_line_bridge_encryption_require: false +matrix_bridge_beeper_line_bridge_encryption_appservice: false +matrix_bridge_beeper_line_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_beeper_line_bridge_encryption_allow }}" +matrix_bridge_beeper_line_bridge_encryption_pickle_key: mautrix.bridge.e2ee + +# Prefix of the localparts generated for LINE ghost users. +# The bridge username template, appservice registration namespace, and Ketesa managed-user +# allowlist are all derived from this value. +matrix_bridge_beeper_line_appservice_username_prefix: line_ + +# Shared secret for authentication of provisioning API requests. +# If set to "disable", the provisioning API will be disabled. +matrix_bridge_beeper_line_provisioning_shared_secret: disable + +matrix_bridge_beeper_line_bridge_personal_filtering_spaces: true + +matrix_bridge_beeper_line_bridge_permissions: | + {{ + {'*': 'relay', matrix_bridge_beeper_line_homeserver_domain: 'user'} + | combine({matrix_admin: 'admin'} if matrix_admin else {}) + }} + +# Default beeper-line configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_bridge_beeper_line_configuration_extension_yaml`) +# or completely replace this variable with your own template. +matrix_bridge_beeper_line_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" + +matrix_bridge_beeper_line_configuration_extension_yaml: | + # Your custom YAML configuration goes here. + # This configuration extends the default starting configuration (`matrix_bridge_beeper_line_configuration_yaml`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by + # completely redefining `matrix_bridge_beeper_line_configuration_yaml`. + +matrix_bridge_beeper_line_configuration_extension: "{{ matrix_bridge_beeper_line_configuration_extension_yaml | from_yaml if matrix_bridge_beeper_line_configuration_extension_yaml | from_yaml is mapping else {} }}" + +# Holds the final configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_beeper_line_configuration_yaml`. +matrix_bridge_beeper_line_configuration: "{{ matrix_bridge_beeper_line_configuration_yaml | from_yaml | combine(matrix_bridge_beeper_line_configuration_extension, recursive=True) }}" + +matrix_bridge_beeper_line_registration_yaml: | + id: line + url: {{ matrix_bridge_beeper_line_appservice_address }} + as_token: "{{ matrix_bridge_beeper_line_appservice_token }}" + hs_token: "{{ matrix_bridge_beeper_line_homeserver_token }}" + sender_localpart: _bot_{{ matrix_bridge_beeper_line_appservice_bot_username }} + rate_limited: false + namespaces: + users: + - regex: '^@{{ matrix_bridge_beeper_line_appservice_username_prefix | regex_escape }}.+:{{ matrix_bridge_beeper_line_homeserver_domain | regex_escape }}$' + exclusive: true + - exclusive: true + regex: '^@{{ matrix_bridge_beeper_line_appservice_bot_username | regex_escape }}:{{ matrix_bridge_beeper_line_homeserver_domain | regex_escape }}$' + de.sorunome.msc2409.push_ephemeral: true + receive_ephemeral: true + io.element.msc4190: {{ matrix_bridge_beeper_line_msc4190_enabled | to_json }} + +matrix_bridge_beeper_line_registration: "{{ matrix_bridge_beeper_line_registration_yaml | from_yaml }}" + +# matrix_bridge_beeper_line_restart_necessary controls whether the service +# will be restarted (when true) or merely started (when false) by the +# systemd service manager role (when conditional restart is enabled). +# +# This value is automatically computed during installation based on whether +# any configuration files, the systemd service file, or the container image changed. +# The default of `false` means "no restart needed", appropriate when the role's +# installation tasks haven't run (e.g., due to --tags skipping them). +matrix_bridge_beeper_line_restart_necessary: false diff --git a/roles/custom/matrix-bridge-beeper-line/molecule/default/converge.yml b/roles/custom/matrix-bridge-beeper-line/molecule/default/converge.yml new file mode 100644 index 000000000..9443bd41d --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for beeper-line Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for beeper-line Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure beeper-line is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the beeper-line systemd service is started + ansible.builtin.systemd_service: + name: matrix-beeper-line.service + state: started diff --git a/roles/custom/matrix-bridge-beeper-line/molecule/default/molecule.yml b/roles/custom/matrix-bridge-beeper-line/molecule/default/molecule.yml new file mode 100644 index 000000000..4d2e7eb0f --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/molecule/default/molecule.yml @@ -0,0 +1,103 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: beeper-line-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_beeper_line_container_network: beeper-line-molecule + + # The scenario deliberately stops at the third-party boundary: an idle, logged-out + # bridge proves the playbook contract without needing a LINE account or credentials. + matrix_bridge_beeper_line_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_beeper_line_homeserver_domain: molecule.local + + # The playbook selects Postgres in normal deployments. Non-default credentials make + # schema creation evidence that the role composed and delivered this connection URI. + matrix_bridge_beeper_line_database_engine: postgres + matrix_bridge_beeper_line_database_hostname: matrix-postgres-molecule + matrix_bridge_beeper_line_database_name: molecule_beeper_line + matrix_bridge_beeper_line_database_username: molecule_beeper_line + matrix_bridge_beeper_line_database_password: molecule_pg_password_8f72d1 + + matrix_bridge_beeper_line_appservice_token: molecule_line_as_token_4e81a9 + matrix_bridge_beeper_line_homeserver_token: molecule_line_hs_token_7c25f0 + matrix_bridge_beeper_line_appservice_bot_username: molecule-linebot + matrix_bridge_beeper_line_appservice_bot_displayname: Molecule LINE Bot + matrix_bridge_beeper_line_appservice_bot_avatar: mxc://molecule.local/lineAvatarFixture + # The dot proves every consumer escapes the shared non-default prefix as a regex. + matrix_bridge_beeper_line_appservice_username_prefix: molecule.line_ + # Each value differs from the role default so parsed checks distinguish role output + # from component defaults. + matrix_bridge_beeper_line_command_prefix: "!molecule-line" + matrix_bridge_beeper_line_bridge_personal_filtering_spaces: false + matrix_bridge_beeper_line_federate_rooms: false + matrix_bridge_beeper_line_backfill_enabled: true + matrix_bridge_beeper_line_backfill_max_initial_messages: 27 + matrix_bridge_beeper_line_backfill_max_catchup_messages: 43 + matrix_bridge_beeper_line_backfill_unread_hours_threshold: 168 + matrix_bridge_beeper_line_provisioning_shared_secret: molecule_line_provisioning_68c93d + matrix_bridge_beeper_line_logging_level: info + matrix_bridge_beeper_line_bridge_permissions: + "*": relay + molecule.local: admin + + # Traefik itself is not needed. These values exercise both the public address consumed + # by the bridge and the labels consumed by Docker. + matrix_bridge_beeper_line_exposure_enabled: true + matrix_bridge_beeper_line_exposure_hostname: line-api.molecule.local + matrix_bridge_beeper_line_exposure_path_prefix: /bridges/line-api + matrix_bridge_beeper_line_scheme: http + matrix_bridge_beeper_line_container_labels_exposure_traefik_priority: 1722 + matrix_bridge_beeper_line_container_labels_exposure_traefik_entrypoints: web + matrix_bridge_beeper_line_container_labels_additional_labels: | + molecule.beeper-line.coverage=enabled + + # Exercise the systemd template's extensible Docker argument list. + matrix_bridge_beeper_line_container_extra_arguments: + - --env=MOLECULE_BEEPER_LINE_COVERAGE=enabled + + # verify.yml is a separate play, where role defaults are not in scope. + matrix_bridge_beeper_line_base_path: /matrix/beeper-line + matrix_bridge_beeper_line_config_path: /matrix/beeper-line/config + matrix_bridge_beeper_line_data_path: /matrix/beeper-line/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-beeper-line/molecule/default/prepare.yml b/roles/custom/matrix-bridge-beeper-line/molecule/default/prepare.yml new file mode 100644 index 000000000..07216da17 --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/molecule/default/prepare.yml @@ -0,0 +1,86 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare beeper-line Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role creates this during converge, but the fixtures need it first. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_beeper_line_container_network }}" + register: beeper_line_molecule_network + changed_when: beeper_line_molecule_network.rc == 0 + failed_when: + - beeper_line_molecule_network.rc != 0 + - "'already exists' not in beeper_line_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_beeper_line_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_beeper_line_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_beeper_line_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_beeper_line_database_password }}" + + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_beeper_line_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_beeper_line_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_beeper_line_appservice_bot_username }}:{{ matrix_bridge_beeper_line_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-beeper-line/molecule/default/requirements.yml b/roles/custom/matrix-bridge-beeper-line/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-beeper-line/molecule/default/verify.yml b/roles/custom/matrix-bridge-beeper-line/molecule/default/verify.yml new file mode 100644 index 000000000..9e1236a80 --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/molecule/default/verify.yml @@ -0,0 +1,399 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the logged-out bridge accepts the role-rendered configuration and registration, +# migrates real Postgres, opens its appservice listener, and authenticates transactions. +# A LINE login is deliberately outside this scenario's third-party boundary. +- name: Verify beeper-line + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + beeper_line_config: "{{ beeper_line_config_file.content | b64decode | from_yaml }}" + beeper_line_registration: "{{ beeper_line_registration_file.content | b64decode | from_yaml }}" + beeper_line_labels_rendered: "{{ beeper_line_labels_file.content | b64decode }}" + beeper_line_expected_public_address: http://line-api.molecule.local/bridges/line-api + gather_facts: false + + tasks: + # A Renovate digest bump changes this source of truth and therefore the image expectation. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: beeper_line_role_defaults + + - name: Wait for the beeper-line service to become active + ansible.builtin.systemd_service: + name: matrix-beeper-line.service + register: beeper_line_service + until: beeper_line_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes ActiveState insufficient for detecting a crash loop. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - beeper_line_service.status.ActiveState == 'active' + - beeper_line_service.status.NRestarts is defined + - beeper_line_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-beeper-line.service is {{ beeper_line_service.status.ActiveState | default('unknown') }} + after {{ beeper_line_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-beeper-line.service is active and has not restarted" + + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_beeper_line_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-beeper-line:29322/_matrix/mau/live + register: beeper_line_live + changed_when: false + until: beeper_line_live.rc == 0 and beeper_line_live.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_beeper_line_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-beeper-line:29322/_matrix/mau/ready + register: beeper_line_ready + changed_when: false + until: beeper_line_ready.rc == 0 and beeper_line_ready.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on the configured appservice port + ansible.builtin.assert: + that: + - beeper_line_live.rc == 0 + - beeper_line_live.stdout == 'HTTP_STATUS=200' + - beeper_line_ready.rc == 0 + - beeper_line_ready.stdout == 'HTTP_STATUS=200' + fail_msg: >- + Health probes returned live={{ beeper_line_live.stdout | default('none') }} and + ready={{ beeper_line_ready.stdout | default('none') }} + success_msg: "The bridge is live and ready on its appservice port" + + # This is a real inbound appservice handshake using the role-rendered hs_token. + - name: Submit an empty appservice transaction with the configured token + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_beeper_line_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --fail-with-body + - --request + - PUT + - --header + - "Content-Type: application/json" + - --header + - "Authorization: Bearer {{ matrix_bridge_beeper_line_homeserver_token }}" + - --data-binary + - '{"events": [], "ephemeral": []}' + - http://matrix-beeper-line:29322/_matrix/app/v1/transactions/molecule-coverage + register: beeper_line_transaction + changed_when: false + + - name: Submit an appservice transaction with an invalid token + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_beeper_line_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - --request + - PUT + - --header + - "Content-Type: application/json" + - --header + - "Authorization: Bearer definitely-wrong-token" + - --data-binary + - '{"events": [], "ephemeral": []}' + - http://matrix-beeper-line:29322/_matrix/app/v1/transactions/molecule-unauthorized + register: beeper_line_transaction_unauthorized + changed_when: false + failed_when: false + + - name: Assert the live appservice accepts only the configured handshake token + ansible.builtin.assert: + that: + - beeper_line_transaction.rc == 0 + - beeper_line_transaction.stdout | from_json == {} + - beeper_line_transaction_unauthorized.rc == 0 + - beeper_line_transaction_unauthorized.stdout == 'HTTP_STATUS=401' + fail_msg: "The appservice transaction endpoint did not enforce the rendered hs_token" + success_msg: "The live appservice accepts the configured hs_token and rejects another" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_beeper_line_config_path }}/config.yaml" + register: beeper_line_config_file + + - name: Assert the rendered configuration carries the appservice identity + ansible.builtin.assert: + that: + - beeper_line_config.homeserver.address == matrix_bridge_beeper_line_homeserver_address + - beeper_line_config.homeserver.domain == matrix_bridge_beeper_line_homeserver_domain + - beeper_line_config.appservice.id == 'line' + - beeper_line_config.appservice.address == 'http://matrix-beeper-line:29322' + - beeper_line_config.appservice.public_address == beeper_line_expected_public_address + - beeper_line_config.appservice.bot.username == matrix_bridge_beeper_line_appservice_bot_username + - beeper_line_config.appservice.bot.displayname == matrix_bridge_beeper_line_appservice_bot_displayname + - beeper_line_config.appservice.bot.avatar == matrix_bridge_beeper_line_appservice_bot_avatar + - beeper_line_config.appservice.as_token == matrix_bridge_beeper_line_appservice_token + - beeper_line_config.appservice.hs_token == matrix_bridge_beeper_line_homeserver_token + - beeper_line_config.appservice.username_template == matrix_bridge_beeper_line_appservice_username_prefix + '{' + '{.}' + '}' + fail_msg: "The rendered configuration does not carry the scenario's appservice identity" + success_msg: "The rendered configuration carries the scenario's appservice identity" + + - name: Assert the rendered configuration carries non-default bridge behavior + ansible.builtin.assert: + that: + - beeper_line_config.bridge.command_prefix == matrix_bridge_beeper_line_command_prefix + - not beeper_line_config.bridge.personal_filtering_spaces + - beeper_line_config.bridge.permissions['*'] == 'relay' + - beeper_line_config.bridge.permissions[matrix_bridge_beeper_line_homeserver_domain] == 'admin' + - not beeper_line_config.matrix.federate_rooms + - beeper_line_config.provisioning.shared_secret == matrix_bridge_beeper_line_provisioning_shared_secret + - beeper_line_config.logging.min_level == matrix_bridge_beeper_line_logging_level + fail_msg: "The rendered configuration does not carry the scenario's bridge behavior" + success_msg: "The rendered configuration carries the scenario's bridge behavior" + + - name: Assert the rendered configuration carries the non-default backfill policy + ansible.builtin.assert: + that: + - beeper_line_config.backfill.enabled + - beeper_line_config.backfill.max_initial_messages == 27 + - beeper_line_config.backfill.max_catchup_messages == 43 + - beeper_line_config.backfill.unread_hours_threshold == 168 + fail_msg: "The rendered configuration does not carry the scenario's backfill policy" + success_msg: "The rendered configuration carries the scenario's backfill policy" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - beeper_line_config.database.type == 'postgres' + - matrix_bridge_beeper_line_database_username in beeper_line_config.database.uri + - matrix_bridge_beeper_line_database_hostname in beeper_line_config.database.uri + - matrix_bridge_beeper_line_database_name in beeper_line_config.database.uri + fail_msg: >- + database.uri is {{ beeper_line_config.database.uri | default('unset') }}, which was not + composed from the scenario's connection settings + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_beeper_line_config_path }}/registration.yaml" + register: beeper_line_registration_file + + - name: Assert the registration carries the configured handshake values + ansible.builtin.assert: + that: + - beeper_line_registration.id == 'line' + - beeper_line_registration.as_token == matrix_bridge_beeper_line_appservice_token + - beeper_line_registration.hs_token == matrix_bridge_beeper_line_homeserver_token + - beeper_line_registration.sender_localpart == '_bot_' + matrix_bridge_beeper_line_appservice_bot_username + - beeper_line_registration.url == 'http://matrix-beeper-line:29322' + fail_msg: "The registration does not carry the configured handshake values" + success_msg: "The registration carries the configured handshake values" + + - name: Assert the registration namespaces use the shared LINE ghost prefix and cover the bridge bot + ansible.builtin.assert: + that: + - beeper_line_registration.namespaces.users | length == 2 + - beeper_line_ghost_regex == beeper_line_expected_ghost_regex + - beeper_line_bot_regex == beeper_line_expected_bot_regex + - beeper_line_ghost_mxid is match(beeper_line_ghost_regex) + - beeper_line_wrong_ghost_mxid is not match(beeper_line_ghost_regex) + - beeper_line_bot_mxid is match(beeper_line_bot_regex) + fail_msg: "The registration namespaces do not use the shared LINE ghost prefix or cover the bot" + success_msg: "The registration namespaces use the shared LINE ghost prefix and cover the bot" + vars: + beeper_line_ghost_regex: "{{ beeper_line_registration.namespaces.users[0].regex }}" + beeper_line_bot_regex: "{{ beeper_line_registration.namespaces.users[1].regex }}" + beeper_line_expected_ghost_regex: '^@{{ matrix_bridge_beeper_line_appservice_username_prefix | regex_escape }}.+:{{ matrix_bridge_beeper_line_homeserver_domain | regex_escape }}$' + beeper_line_expected_bot_regex: '^@{{ matrix_bridge_beeper_line_appservice_bot_username | regex_escape }}:{{ matrix_bridge_beeper_line_homeserver_domain | regex_escape }}$' + beeper_line_ghost_mxid: "@{{ matrix_bridge_beeper_line_appservice_username_prefix }}moleculefixture:{{ matrix_bridge_beeper_line_homeserver_domain }}" + beeper_line_wrong_ghost_mxid: "@twitter_moleculefixture:{{ matrix_bridge_beeper_line_homeserver_domain }}" + beeper_line_bot_mxid: "@{{ matrix_bridge_beeper_line_appservice_bot_username }}:{{ matrix_bridge_beeper_line_homeserver_domain }}" + + # Tables can appear only after hostname resolution, authentication, and real migrations. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_beeper_line_database_username }} + - --dbname={{ matrix_bridge_beeper_line_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: beeper_line_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - beeper_line_tables.rc == 0 + - "'version' in beeper_line_table_names" + - "'portal' in beeper_line_table_names" + - "'user_login' in beeper_line_table_names" + - "'message' in beeper_line_table_names" + - beeper_line_table_names | length > 10 + fail_msg: >- + The bridge did not migrate its schema into {{ matrix_bridge_beeper_line_database_name }} + (found {{ beeper_line_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + beeper_line_table_names: "{{ beeper_line_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_beeper_line_base_path }}/labels" + register: beeper_line_labels_file + + - name: Assert the labels route the public endpoint to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in beeper_line_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_beeper_line_container_network in beeper_line_labels_rendered" + - "'traefik.http.services.matrix-beeper-line-exposure.loadbalancer.server.port=29322' in beeper_line_labels_rendered" + - "'traefik.http.routers.matrix-beeper-line-exposure.rule=Host(`line-api.molecule.local`) && PathPrefix(`/bridges/line-api`)' in beeper_line_labels_rendered" + - "'traefik.http.middlewares.matrix-beeper-line-exposure-strip-prefix.stripprefix.prefixes=/bridges/line-api' in beeper_line_labels_rendered" + - "'traefik.http.routers.matrix-beeper-line-exposure.priority=1722' in beeper_line_labels_rendered" + - "'traefik.http.routers.matrix-beeper-line-exposure.entrypoints=web' in beeper_line_labels_rendered" + - "'traefik.http.routers.matrix-beeper-line-exposure.tls=false' in beeper_line_labels_rendered" + - "'molecule.beeper-line.coverage=enabled' in beeper_line_labels_rendered" + fail_msg: "The rendered labels do not carry the scenario's exposure configuration" + success_msg: "The rendered labels carry the scenario's exposure configuration" + + - name: Inspect the running bridge container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-beeper-line + register: beeper_line_container_inspect + changed_when: false + + - name: Parse the running bridge container inspection + ansible.builtin.set_fact: + beeper_line_container: "{{ (beeper_line_container_inspect.stdout | from_json) | first }}" + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - beeper_line_container.Config.Image == beeper_line_expected_image + fail_msg: >- + The running container uses {{ beeper_line_container.Config.Image }}, expected + {{ beeper_line_expected_image }} + success_msg: "The running container uses the exact image pinned by the role" + vars: + beeper_line_expected_image: >- + {{ beeper_line_role_defaults.matrix_bridge_beeper_line_container_image_registry_prefix_upstream_default }}crispyduck/beeper-line:{{ beeper_line_role_defaults.matrix_bridge_beeper_line_version }} + + - name: Assert the running container uses the playbook-supplied runtime + ansible.builtin.assert: + that: + - beeper_line_container.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + - beeper_line_container.Config.WorkingDir == '/data' + - beeper_line_container.Config.Cmd == ['/usr/bin/matrix-line', '-c', '/config/config.yaml', '-r', '/config/registration.yaml', '--no-update'] + - beeper_line_container.Config.Env is contains('MOLECULE_BEEPER_LINE_COVERAGE=enabled') + - beeper_line_container.HostConfig.RestartPolicy.Name == 'no' + - beeper_line_container.HostConfig.AutoRemove + - beeper_line_container.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container does not use the role's exact identity and command" + success_msg: "The running container uses the role's exact identity, command, and extra argument" + + - name: Assert the running container has the intended privilege isolation + ansible.builtin.assert: + that: + - "'ALL' in beeper_line_container.HostConfig.CapDrop" + - not beeper_line_container.HostConfig.Privileged + fail_msg: "The running container does not have the intended privilege isolation" + success_msg: "The running container drops all capabilities and is unprivileged" + + - name: Assert the running container carries the role's exact bind mounts + ansible.builtin.assert: + that: + - beeper_line_config_mount | length > 0 + - beeper_line_config_mount.Source == matrix_bridge_beeper_line_config_path + - not beeper_line_config_mount.RW + - beeper_line_data_mount | length > 0 + - beeper_line_data_mount.Source == matrix_bridge_beeper_line_data_path + - beeper_line_data_mount.RW + - beeper_line_container.Mounts | length == 2 + fail_msg: "The running container does not carry the role's exact config and data mounts" + success_msg: "The running container carries read-only config and writable data mounts" + vars: + beeper_line_config_mount: >- + {{ beeper_line_container.Mounts + | selectattr('Destination', 'equalto', '/config') + | first | default({}) }} + beeper_line_data_mount: >- + {{ beeper_line_container.Mounts + | selectattr('Destination', 'equalto', '/data') + | first | default({}) }} + + - name: Assert the rendered labels are attached to the running container + ansible.builtin.assert: + that: + - beeper_line_container.Config.Labels['traefik.enable'] == 'true' + - beeper_line_container.Config.Labels['traefik.docker.network'] == matrix_bridge_beeper_line_container_network + - beeper_line_container.Config.Labels['traefik.http.services.matrix-beeper-line-exposure.loadbalancer.server.port'] == '29322' + - beeper_line_container.Config.Labels['molecule.beeper-line.coverage'] == 'enabled' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The running container carries the labels the role rendered" + + - name: Assert the running container has the exact network and port exposure + ansible.builtin.assert: + that: + - beeper_line_container.HostConfig.NetworkMode == matrix_bridge_beeper_line_container_network + - matrix_bridge_beeper_line_container_network in beeper_line_container.NetworkSettings.Networks + - beeper_line_container.NetworkSettings.Networks | length == 1 + - beeper_line_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: >- + The container has unexpected networks or host ports: + networks={{ beeper_line_container.NetworkSettings.Networks.keys() | list }}, + ports={{ beeper_line_container.HostConfig.PortBindings | default({}) }} + success_msg: "The container uses only its dedicated network and publishes no host ports" diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/main.yml b/roles/custom/matrix-bridge-beeper-line/tasks/main.yml similarity index 52% rename from roles/custom/matrix-bridge-appservice-kakaotalk/tasks/main.yml rename to roles/custom/matrix-bridge-beeper-line/tasks/main.yml index c99b77fbe..ec400c916 100644 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/tasks/main.yml +++ b/roles/custom/matrix-bridge-beeper-line/tasks/main.yml @@ -1,4 +1,5 @@ -# SPDX-FileCopyrightText: 2019 - 2023 Slavi Pantaleev +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -6,19 +7,19 @@ - tags: - setup-all - - setup-appservice-kakaotalk + - setup-beeper-line - install-all - - install-appservice-kakaotalk + - install-beeper-line block: - - when: matrix_appservice_kakaotalk_enabled | bool + - when: matrix_bridge_beeper_line_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_appservice_kakaotalk_enabled | bool + - when: matrix_bridge_beeper_line_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - - setup-appservice-kakaotalk + - setup-beeper-line block: - - when: not matrix_appservice_kakaotalk_enabled | bool + - when: not matrix_bridge_beeper_line_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-beeper-line/tasks/setup_install.yml b/roles/custom/matrix-bridge-beeper-line/tasks/setup_install.yml new file mode 100644 index 000000000..58a66299d --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/tasks/setup_install.yml @@ -0,0 +1,153 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- ansible.builtin.set_fact: + matrix_bridge_beeper_line_migration_requires_restart: false + +- when: "matrix_bridge_beeper_line_database_engine == 'postgres'" + block: + - name: Check if an SQLite database already exists + ansible.builtin.stat: + path: "{{ matrix_bridge_beeper_line_sqlite_database_path_local }}" + register: matrix_bridge_beeper_line_sqlite_database_path_local_stat_result + + - when: "matrix_bridge_beeper_line_sqlite_database_path_local_stat_result.stat.exists | bool" + block: + - ansible.builtin.include_role: + name: galaxy/postgres + tasks_from: migrate_db_to_postgres + vars: + postgres_db_migration_request: + src: "{{ matrix_bridge_beeper_line_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_beeper_line_database_connection_string }}" + caller: "{{ role_path | basename }}" + engine_variable_name: 'matrix_bridge_beeper_line_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-beeper-line.service'] + pgloader_options: ['--with "quote identifiers"'] + + - ansible.builtin.set_fact: + matrix_bridge_beeper_line_migration_requires_restart: true + +- name: Ensure Beeper LINE paths exist + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + mode: '0750' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - {path: "{{ matrix_bridge_beeper_line_base_path }}", when: true} + - {path: "{{ matrix_bridge_beeper_line_config_path }}", when: true} + - {path: "{{ matrix_bridge_beeper_line_data_path }}", when: true} + - {path: "{{ matrix_bridge_beeper_line_container_src_files_path }}", when: "{{ matrix_bridge_beeper_line_container_image_self_build }}"} + when: item.when | bool + +- name: Ensure Beeper LINE image is pulled + community.docker.docker_image_pull: + name: "{{ matrix_bridge_beeper_line_container_image }}" + pull: always + when: not matrix_bridge_beeper_line_container_image_self_build + register: matrix_bridge_beeper_line_container_image_pull_result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: matrix_bridge_beeper_line_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Beeper LINE repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_beeper_line_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_beeper_line_container_image_self_build | bool" + +- name: Ensure Beeper LINE repository is present on self-build + ansible.builtin.git: + repo: "{{ matrix_bridge_beeper_line_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_beeper_line_container_src_files_path }}" + version: "{{ matrix_bridge_beeper_line_container_image_self_build_branch }}" + force: "yes" + become: true + become_user: "{{ matrix_user_name }}" + register: matrix_bridge_beeper_line_git_pull_results + when: "matrix_bridge_beeper_line_container_image_self_build | bool" + +- name: Ensure Beeper LINE Docker image is built + community.docker.docker_image_build: + name: "{{ matrix_bridge_beeper_line_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_beeper_line_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_beeper_line_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_beeper_line_container_image_self_build | bool" + register: matrix_bridge_beeper_line_container_image_build_result + +- name: Ensure beeper-line config.yaml installed + ansible.builtin.copy: + content: "{{ matrix_bridge_beeper_line_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_beeper_line_config_path }}/config.yaml" + mode: '0644' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bridge_beeper_line_config_result + +- name: Ensure beeper-line registration.yaml installed + ansible.builtin.copy: + content: "{{ matrix_bridge_beeper_line_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_beeper_line_config_path }}/registration.yaml" + mode: '0644' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bridge_beeper_line_registration_result + +- name: Ensure matrix-beeper-line.service installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-beeper-line.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-beeper-line.service" + mode: '0644' + register: matrix_bridge_beeper_line_systemd_service_result + +- name: Ensure beeper-line support files installed + ansible.builtin.template: + src: "{{ role_path }}/templates/{{ item }}.j2" + dest: "{{ matrix_bridge_beeper_line_base_path }}/{{ item }}" + mode: '0640' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - labels + register: matrix_bridge_beeper_line_support_files_result + +- name: Ensure matrix-beeper-line container network is created + when: matrix_bridge_beeper_line_container_network != 'host' + community.general.docker_network: + enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" + name: "{{ matrix_bridge_beeper_line_container_network }}" + driver: bridge + driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" + +- name: Determine whether matrix-beeper-line needs a restart + ansible.builtin.set_fact: + matrix_bridge_beeper_line_restart_necessary: >- + {{ + matrix_bridge_beeper_line_migration_requires_restart | default(false) + or matrix_bridge_beeper_line_config_result.changed | default(false) + or matrix_bridge_beeper_line_registration_result.changed | default(false) + or matrix_bridge_beeper_line_support_files_result.changed | default(false) + or matrix_bridge_beeper_line_systemd_service_result.changed | default(false) + or matrix_bridge_beeper_line_container_image_pull_result.changed | default(false) + or matrix_bridge_beeper_line_container_image_build_result.changed | default(false) + }} + +- name: Ensure matrix-beeper-line.service restarted, if necessary + ansible.builtin.service: + name: "matrix-beeper-line.service" + state: restarted + daemon_reload: true + when: "matrix_bridge_beeper_line_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-beeper-line/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-beeper-line/tasks/setup_uninstall.yml new file mode 100644 index 000000000..3b8947701 --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/tasks/setup_uninstall.yml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Check existence of matrix-beeper-line service + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-beeper-line.service" + register: matrix_bridge_beeper_line_service_stat + +- when: matrix_bridge_beeper_line_service_stat.stat.exists | bool + block: + - name: Ensure matrix-beeper-line is stopped + ansible.builtin.service: + name: matrix-beeper-line + state: stopped + enabled: false + daemon_reload: true + + - name: Ensure matrix-beeper-line.service doesn't exist + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-beeper-line.service" + state: absent diff --git a/roles/custom/matrix-bridge-beeper-line/tasks/validate_config.yml b/roles/custom/matrix-bridge-beeper-line/tasks/validate_config.yml new file mode 100644 index 000000000..b522187ed --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/tasks/validate_config.yml @@ -0,0 +1,28 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: (Deprecation) Catch and report renamed settings + ansible.builtin.fail: + msg: >- + Your configuration contains a variable, which now has a different name. + Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_bridge_beeper_line_appservice_username_template', 'new': 'matrix_bridge_beeper_line_appservice_username_prefix'} + +- name: Fail if required beeper-line settings not defined + ansible.builtin.fail: + msg: >- + You need to define a required configuration setting (`{{ item.name }}`). + when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" + with_items: + - {'name': 'matrix_bridge_beeper_line_appservice_token', when: true} + - {'name': 'matrix_bridge_beeper_line_homeserver_address', when: true} + - {'name': 'matrix_bridge_beeper_line_homeserver_token', when: true} + - {'name': 'matrix_bridge_beeper_line_appservice_username_prefix', when: true} + - {'name': 'matrix_bridge_beeper_line_database_hostname', when: "{{ matrix_bridge_beeper_line_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_beeper_line_container_network', when: true} diff --git a/roles/custom/matrix-bridge-beeper-line/templates/config.yaml.j2 b/roles/custom/matrix-bridge-beeper-line/templates/config.yaml.j2 new file mode 100644 index 000000000..a7ea76d2f --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/templates/config.yaml.j2 @@ -0,0 +1,495 @@ +#jinja2: lstrip_blocks: True +# Network-specific config options +network: {} + +# Config options that affect the central bridge module. +bridge: + # The prefix for commands. Only required in non-management rooms. + command_prefix: {{ matrix_bridge_beeper_line_command_prefix | to_json }} + # Should the bridge create a space for each login containing the rooms that account is in? + personal_filtering_spaces: {{ matrix_bridge_beeper_line_bridge_personal_filtering_spaces | to_json }} + # Whether the bridge should set names and avatars explicitly for DM portals. + # This is only necessary when using clients that don't support MSC4171. + private_chat_portal_meta: true + # Should events be handled asynchronously within portal rooms? + # If true, events may end up being out of order, but slow events won't block other ones. + # This is not yet safe to use. + async_events: false + # Should every user have their own portals rather than sharing them? + # By default, users who are in the same group on the remote network will be + # in the same Matrix room bridged to that group. If this is set to true, + # every user will get their own Matrix room instead. + # SETTING THIS IS IRREVERSIBLE AND POTENTIALLY DESTRUCTIVE IF PORTALS ALREADY EXIST. + split_portals: false + # Should the bridge resend `m.bridge` events to all portals on startup? + resend_bridge_info: false + # Should `m.bridge` events be sent without a state key? + # By default, the bridge uses a unique key that won't conflict with other bridges. + no_bridge_info_state_key: false + # Should bridge connection status be sent to the management room as `m.notice` events? + # These contain the same data that can be posted to an external HTTP server using homeserver -> status_endpoint. + # Allowed values: none, errors, all + bridge_status_notices: errors + # How long after an unknown error should the bridge attempt a full reconnect? + # Must be at least 1 minute. The bridge will add an extra ±20% jitter to this value. + unknown_error_auto_reconnect: null + # Maximum number of times to do the auto-reconnect above. + # The counter is per login, but is never reset except on logout and restart. + unknown_error_max_auto_reconnects: 10 + + # Should leaving Matrix rooms be bridged as leaving groups on the remote network? + bridge_matrix_leave: false + # Should `m.notice` messages be bridged? + bridge_notices: false + # Should room tags only be synced when creating the portal? Tags mean things like favorite/pin and archive/low priority. + # Tags currently can't be synced back to the remote network, so a continuous sync means tagging from Matrix will be undone. + tag_only_on_create: true + # List of tags to allow bridging. If empty, no tags will be bridged. + only_bridge_tags: [m.favourite, m.lowpriority] + # Should room mute status only be synced when creating the portal? + # Like tags, mutes can't currently be synced back to the remote network. + mute_only_on_create: true + # Should the bridge check the db to ensure that incoming events haven't been handled before + deduplicate_matrix_messages: false + # Should cross-room reply metadata be bridged? + # Most Matrix clients don't support this and servers may reject such messages too. + cross_room_replies: false + # If a state event fails to bridge, should the bridge revert any state changes made by that event? + revert_failed_state_changes: false + # In portals with no relay set, should Matrix users be kicked if they're + # not logged into an account that's in the remote chat? + kick_matrix_users: true + # Should the bridge listen to com.beeper.state_request events? + # This is not necessary for anything outside of Beeper. + enable_send_state_requests: false + # Should the com.beeper.bridge.identifiers list in global ghost profiles include phone numbers? + phone_numbers_in_profile: false + + # What should be done to portal rooms when a user logs out or is logged out? + # Permitted values: + # nothing - Do nothing, let the user stay in the portals + # kick - Remove the user from the portal rooms, but don't delete them + # unbridge - Remove all ghosts in the room and disassociate it from the remote chat + # delete - Remove all ghosts and users from the room (i.e. delete it) + cleanup_on_logout: + # Should cleanup on logout be enabled at all? + enabled: false + # Settings for manual logouts (explicitly initiated by the Matrix user) + manual: + # Action for private portals which will never be shared with other Matrix users. + private: nothing + # Action for portals with a relay user configured. + relayed: nothing + # Action for portals which may be shared, but don't currently have any other Matrix users. + shared_no_users: nothing + # Action for portals which have other logged-in Matrix users. + shared_has_users: nothing + # Settings for credentials being invalidated (initiated by the remote network, possibly through user action). + # Keys have the same meanings as in the manual section. + bad_credentials: + private: nothing + relayed: nothing + shared_no_users: nothing + shared_has_users: nothing + + # Settings for relay mode + relay: + # Whether relay mode should be allowed. If allowed, the set-relay command can be used to turn any + # authenticated user into a relaybot for that chat. + enabled: false + # Should only admins be allowed to set themselves as relay users? + # If true, non-admins can only set users listed in default_relays as relays in a room. + admin_only: true + # Should default relays be preferred when an explicit login ID isn't specified even if the user is logged in? + # This applies to the set-relay and bridge commands sent by any user, including admins. + prefer_default: true + # Should non-admins be allowed to use the bridge and sync-chat commands via default relays specified below? + allow_bridge: true + # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. + default_relays: [] + # The formats to use when sending messages via the relaybot. + # Available variables: + # .Sender.UserID - The Matrix user ID of the sender. + # .Sender.Displayname - The display name of the sender (if set). + # .Sender.RequiresDisambiguation - Whether the sender's name may be confused with the name of another user in the room. + # .Sender.DisambiguatedName - The disambiguated name of the sender. This will be the displayname if set, + # plus the user ID in parentheses if the displayname is not unique. + # If the displayname is not set, this is just the user ID. + # .Message - The `formatted_body` field of the message. + # .Caption - The `formatted_body` field of the message, if it's a caption. Otherwise an empty string. + # .FileName - The name of the file being sent. + message_formats: + m.text: "{% raw %}{{ .Sender.DisambiguatedName }}: {{ .Message }}{% endraw %}" + m.notice: "{% raw %}{{ .Sender.DisambiguatedName }}: {{ .Message }}{% endraw %}" + m.emote: "{% raw %}* {{ .Sender.DisambiguatedName }} {{ .Message }}{% endraw %}" + m.file: "{% raw %}{{ .Sender.DisambiguatedName }} sent a file{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.image: "{% raw %}{{ .Sender.DisambiguatedName }} sent an image{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.audio: "{% raw %}{{ .Sender.DisambiguatedName }} sent an audio file{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.video: "{% raw %}{{ .Sender.DisambiguatedName }} sent a video{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.location: "{% raw %}{{ .Sender.DisambiguatedName }} sent a location{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + # For networks that support per-message displaynames (i.e. Slack and Discord), the template for those names. + # This has all the Sender variables available under message_formats (but without the .Sender prefix). + # Note that you need to manually remove the displayname from message_formats above. + displayname_format: "{% raw %}{{ .DisambiguatedName }}{% endraw %}" + + # Filter for automatically creating portals. + portal_create_filter: + # The mode for filtering, either `deny` or `allow` + mode: deny + # The list of portal IDs to deny or allow depending on the mode config. + # Items here can either be the plain portal ID as a string, or an object with `id` and `receiver` fields. + # The receiver field is necessary if you want to target a specific DM portal for example. + list: [] + # A list of user login IDs from which to always deny creating portals. + # This is meant to be used with default relays, such that the relay bot + # being added to a group wouldn't automatically trigger portal creation. + always_deny_from_login: [] + + # Permissions for using the bridge. + # Permitted values: + # relay - Talk through the relaybot (if enabled), no access otherwise + # commands - Access to use commands in the bridge, but not login. + # user - Access to use the bridge with puppeting. + # admin - Full access, user level with some additional administration tools. + # Permitted keys: + # * - All Matrix users + # domain - All users on that homeserver + # mxid - Specific user + permissions: {{ matrix_bridge_beeper_line_bridge_permissions | to_json }} + +# Config for the bridge's database. +database: + # The database type. "sqlite3-fk-wal" and "postgres" are supported. + type: {{ matrix_bridge_beeper_line_appservice_database_type | to_json }} + # The database URI. + # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. + # https://github.com/mattn/go-sqlite3#connection-string + # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable + # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql + uri: {{ matrix_bridge_beeper_line_appservice_database_uri | to_json }} + # Maximum number of connections. + max_open_conns: 5 + max_idle_conns: 1 + # Maximum connection idle time and lifetime before they're closed. Disabled if null. + # Parsed with https://pkg.go.dev/time#ParseDuration + max_conn_idle_time: null + max_conn_lifetime: null + +# Homeserver details. +homeserver: + # The address that this appservice can use to connect to the homeserver. + # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, + # but https also works if they run on different machines. + address: {{ matrix_bridge_beeper_line_homeserver_address | to_json }} + # The domain of the homeserver (also known as server_name, used for MXIDs, etc). + domain: {{ matrix_bridge_beeper_line_homeserver_domain | to_json }} + + # What software is the homeserver running? + # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. + software: standard + # The URL to push real-time bridge status to. + # If set, the bridge will make POST requests to this URL whenever a user's remote network connection state changes. + # The bridge will use the appservice as_token to authorize requests. + status_endpoint: + # Endpoint for reporting per-message status. + # If set, the bridge will make POST requests to this URL when processing a message from Matrix. + # It will make one request when receiving the message (step BRIDGE), one after decrypting if applicable + # (step DECRYPTED) and one after sending to the remote network (step REMOTE). Errors will also be reported. + # The bridge will use the appservice as_token to authorize requests. + message_send_checkpoint_endpoint: + # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? + async_media: {{ matrix_bridge_beeper_line_homeserver_async_media | to_json }} + + # Should the bridge use a websocket for connecting to the homeserver? + # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, + # mautrix-asmux (deprecated), and hungryserv (proprietary). + websocket: false + # How often should the websocket be pinged? Pinging will be disabled if this is zero. + ping_interval_seconds: 0 + +# Application service host/registration related details. +# Changing these values requires regeneration of the registration (except when noted otherwise) +appservice: + # The address that the homeserver can use to connect to this appservice. + # Like the homeserver address, a local non-https address is recommended when the bridge is on the same machine. + # If the bridge is elsewhere, you must secure the connection yourself (e.g. with https or wireguard) + # If you want to use https, you need to use a reverse proxy. The bridge does not have TLS support built in. + address: {{ matrix_bridge_beeper_line_appservice_address | to_json }} + # A public address that external services can use to reach this appservice. + # A reverse proxy is generally necessary when using this field. + # This value doesn't affect the registration file. + public_address: {{ matrix_bridge_beeper_line_bridge_public_address | to_json }} + + # The hostname and port where this appservice should listen. + # For Docker, you generally have to change the hostname to 0.0.0.0. + hostname: 0.0.0.0 + port: 29322 + + # The unique ID of this appservice. + id: line + # Appservice bot details. + bot: + # Username of the appservice bot. + username: {{ matrix_bridge_beeper_line_appservice_bot_username | to_json }} + # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty + # to leave display name/avatar as-is. + displayname: {{ matrix_bridge_beeper_line_appservice_bot_displayname | to_json }} + avatar: {{ matrix_bridge_beeper_line_appservice_bot_avatar | to_json }} + + # Whether to receive ephemeral events via appservice transactions. + ephemeral_events: true + # Should incoming events be handled asynchronously? + # This may be necessary for large public instances with lots of messages going through. + # However, messages will not be guaranteed to be bridged in the same order they were sent in. + # This value doesn't affect the registration file. + async_transactions: false + + # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. + as_token: {{ matrix_bridge_beeper_line_appservice_token | to_json }} + hs_token: {{ matrix_bridge_beeper_line_homeserver_token | to_json }} + + # Localpart template of MXIDs for remote users. + # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. + username_template: {{ (matrix_bridge_beeper_line_appservice_username_prefix + '{{.}}') | to_json }} + +# Config options that affect the Matrix connector of the bridge. +matrix: + # Whether the bridge should send the message status as a custom com.beeper.message_send_status event. + message_status_events: false + # Whether the bridge should send a read receipt after successfully bridging a message. + delivery_receipts: false + # Whether the bridge should send error notices via m.notice events when a message fails to bridge. + message_error_notices: true + # Whether the bridge should update the m.direct account data event when double puppeting is enabled. + sync_direct_chat_list: true + # Whether created rooms should have federation enabled. If false, created portal rooms + # will never be federated. Changing this option requires recreating rooms. + federate_rooms: {{ matrix_bridge_beeper_line_federate_rooms | to_json }} + # The threshold as bytes after which the bridge should roundtrip uploads via the disk + # rather than keeping the whole file in memory. + upload_file_threshold: 5242880 + # Should the bridge set additional custom profile info for ghosts? + # This can make a lot of requests, as there's no batch profile update endpoint. + ghost_extra_profile_info: false + +# Segment-compatible analytics endpoint for tracking some events, like provisioning API login and encryption errors. +analytics: + # API key to send with tracking requests. Tracking is disabled if this is null. + token: null + # Address to send tracking requests to. + url: https://api.segment.io/v1/track + # Optional user ID for tracking events. If null, defaults to using Matrix user ID. + user_id: null + +# Settings for provisioning API +provisioning: + # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, + # or if set to "disable", the provisioning API will be disabled. Must be at least 16 characters. + shared_secret: {{ matrix_bridge_beeper_line_provisioning_shared_secret | to_json }} + # Whether to allow provisioning API requests to be authed using Matrix access tokens. + # This follows the same rules as double puppeting to determine which server to contact to check the token, + # which means that by default, it only works for users on the same server as the bridge. + allow_matrix_auth: true + # Enable debug API at /debug with provisioning authentication. + debug_endpoints: false + # Enable session transfers between bridges. Note that this only validates Matrix or shared secret + # auth before passing live network client credentials down in the response. + enable_session_transfers: false + +# Some networks require publicly accessible media download links (e.g. for user avatars when using Discord webhooks). +# These settings control whether the bridge will provide such public media access. +public_media: + # Should public media be enabled at all? + # The public_address field under the appservice section MUST be set when enabling public media. + enabled: false + # A key for signing public media URLs. + # If set to "generate", a random key will be generated. + signing_key: "" + # Number of seconds that public media URLs are valid for. + # If set to 0, URLs will never expire. + expiry: 0 + # Length of hash to use for public media URLs. Must be between 0 and 32. + hash_length: 32 + # The path prefix for generated URLs. Note that this will NOT change the path where media is actually served. + # If you change this, you must configure your reverse proxy to rewrite the path accordingly. + path_prefix: /_mautrix/publicmedia + # Should the bridge store media metadata in the database in order to support encrypted media and generate shorter URLs? + # If false, the generated URLs will just have the MXC URI and a HMAC signature. + # The hash_length field will be used to decide the length of the generated URL. + # This also allows invalidating URLs by deleting the database entry. + use_database: false + +# Settings for converting remote media to custom mxc:// URIs instead of reuploading. +# More details can be found at https://docs.mau.fi/bridges/go/discord/direct-media.html +direct_media: + # Should custom mxc:// URIs be used instead of reuploading media? + enabled: false + # The server name to use for the custom mxc:// URIs. + # This server name will effectively be a real Matrix server, it just won't implement anything other than media. + # You must either set up .well-known delegation from this domain to the bridge, or proxy the domain directly to the bridge. + server_name: line-media.example.com + # Optionally a custom .well-known response. This defaults to `server_name:443` + well_known_response: + # Optionally specify a custom prefix for the media ID part of the MXC URI. + media_id_prefix: + # If the remote network supports media downloads over HTTP, then the bridge will use MSC3860/MSC3916 + # media download redirects if the requester supports it. Optionally, you can force redirects + # and not allow proxying at all by setting this to false. + # This option does nothing if the remote network does not support media downloads over HTTP. + allow_proxy: true + # Matrix server signing key to make the federation tester pass, same format as synapse's .signing.key file. + # This key is also used to sign the mxc:// URIs to ensure only the bridge can generate them. + server_key: "" + +# Settings for backfilling messages. +# Note that the exact way settings are applied depends on the network connector. +# See https://docs.mau.fi/bridges/general/backfill.html for more details. +backfill: + # Whether to do backfilling at all. + enabled: {{ matrix_bridge_beeper_line_backfill_enabled | to_json }} + # Maximum number of messages to backfill in empty rooms. + # If this is zero or negative, backfill will be disabled in new rooms. + max_initial_messages: {{ matrix_bridge_beeper_line_backfill_max_initial_messages | to_json }} + # Maximum number of missed messages to backfill after bridge restarts. + max_catchup_messages: {{ matrix_bridge_beeper_line_backfill_max_catchup_messages | to_json }} + # If a backfilled chat is older than this number of hours, + # mark it as read even if it's unread on the remote network. + unread_hours_threshold: {{ matrix_bridge_beeper_line_backfill_unread_hours_threshold | to_json }} + # Settings for backfilling threads within other backfills. + threads: + # Maximum number of messages to backfill in a new thread. + max_initial_messages: 50 + # Settings for the backwards backfill queue. This only applies when connecting to + # Beeper as standard Matrix servers don't support inserting messages into history. + queue: + # Should the backfill queue be enabled? + enabled: false + # Should manual calls to backfill queue tasks be allowed? + manual: false + # Number of messages to backfill in one batch. + batch_size: 100 + # Delay between batches in seconds. + batch_delay: 20 + # Maximum number of batches to backfill per portal. + # If set to -1, all available messages will be backfilled. + max_batches: -1 + # Optional network-specific overrides for max batches. + # Interpretation of this field depends on the network connector. + max_batches_override: {} + +# Settings for enabling double puppeting +double_puppet: + # Servers to always allow double puppeting from. + # This is only for other servers and should NOT contain the server the bridge is on. + servers: {} + # Whether to allow client API URL discovery for other servers. When using this option, + # users on other servers can use double puppeting even if their server URLs aren't + # explicitly added to the servers map above. + allow_discovery: false + # Shared secrets for automatic double puppeting. + # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. + secrets: {{ matrix_bridge_beeper_line_double_puppet_secrets | to_json }} + +# End-to-bridge encryption support options. +# +# See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. +encryption: + # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. + allow: {{ matrix_bridge_beeper_line_bridge_encryption_allow | to_json }} + # Whether to force-enable encryption in all bridged rooms. + default: {{ matrix_bridge_beeper_line_bridge_encryption_default | to_json }} + # Whether to require all messages to be encrypted and drop any unencrypted messages. + require: {{ matrix_bridge_beeper_line_bridge_encryption_require | to_json }} + # Whether to use MSC3202/MSC4203 instead of /sync long polling for receiving encryption-related data. + # This is an experimental option, see the docs for more info. + # Changing this option requires updating the appservice registration file. + appservice: {{ matrix_bridge_beeper_line_bridge_encryption_appservice | to_json }} + # Whether to use MSC4190 instead of appservice login to create the bridge bot device. + # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. + # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). + msc4190: {{ matrix_bridge_beeper_line_msc4190_enabled | to_json }} + # Whether to encrypt reactions and reply metadata as per MSC4392. + # This is not supported by most clients. + msc4392: false + # Should the bridge bot generate a recovery key and cross-signing keys and verify itself? + # Note that without the latest version of MSC4190, this will fail if you reset the bridge database. + # The generated recovery key will be saved in the kv_store table under `recovery_key`. + self_sign: {{ matrix_bridge_beeper_line_self_sign_enabled | to_json }} + # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. + # You must use a client that supports requesting keys from other users to use this feature. + allow_key_sharing: {{ matrix_bridge_beeper_line_bridge_encryption_key_sharing_allow | to_json }} + # Pickle key for encrypting encryption keys in the bridge database. + # If set to generate, a random key will be generated. + pickle_key: {{ matrix_bridge_beeper_line_bridge_encryption_pickle_key | to_json }} + # Options for deleting megolm sessions from the bridge. + delete_keys: + # Beeper-specific: delete outbound sessions when hungryserv confirms + # that the user has uploaded the key to key backup. + delete_outbound_on_ack: false + # Don't store outbound sessions in the inbound table. + dont_store_outbound: false + # Ratchet megolm sessions forward after decrypting messages. + ratchet_on_decrypt: false + # Delete fully used keys (index >= max_messages) after decrypting messages. + delete_fully_used_on_decrypt: false + # Delete previous megolm sessions from same device when receiving a new one. + delete_prev_on_new_session: false + # Delete megolm sessions received from a device when the device is deleted. + delete_on_device_delete: false + # Periodically delete megolm sessions when 2x max_age has passed since receiving the session. + periodically_delete_expired: false + # Delete inbound megolm sessions that don't have the received_at field used for + # automatic ratcheting and expired session deletion. This is meant as a migration + # to delete old keys prior to the bridge update. + delete_outdated_inbound: false + # What level of device verification should be required from users? + # + # Valid levels: + # unverified - Send keys to all device in the room. + # cross-signed-untrusted - Require valid cross-signing, but trust all cross-signing keys. + # cross-signed-tofu - Require valid cross-signing, trust cross-signing keys on first use (and reject changes). + # cross-signed-verified - Require valid cross-signing, plus a valid user signature from the bridge bot. + # Note that creating user signatures from the bridge bot is not currently possible. + # verified - Require manual per-device verification + # (currently only possible by modifying the `trust` column in the `crypto_device` database table). + verification_levels: + # Minimum level for which the bridge should send keys to when bridging messages from the remote network to Matrix. + receive: unverified + # Minimum level that the bridge should accept for incoming Matrix messages. + send: unverified + # Minimum level that the bridge should require for accepting key requests. + share: cross-signed-tofu + # Options for Megolm room key rotation. These options allow you to configure the m.room.encryption event content. + # See https://spec.matrix.org/v1.10/client-server-api/#mroomencryption for more information about that event. + rotation: + # Enable custom Megolm room key rotation settings. Note that these + # settings will only apply to rooms created after this option is set. + enable_custom: false + # The maximum number of milliseconds a session should be used + # before changing it. The Matrix spec recommends 604800000 (a week) + # as the default. + milliseconds: 604800000 + # The maximum number of messages that should be sent with a given a + # session before changing it. The Matrix spec recommends 100 as the + # default. + messages: 100 + # Disable rotating keys when a user's devices change? + # You should not enable this option unless you understand all the implications. + disable_device_change_key_rotation: false + +# Prefix for environment variables. All variables with this prefix must map to valid config fields. +# Nesting in variable names is represented with a dot (.). +# If there are no dots in the name, two underscores (__) are replaced with a dot. +# +# e.g. if the prefix is set to `BRIDGE_`, then `BRIDGE_APPSERVICE__AS_TOKEN` will set appservice.as_token. +# `BRIDGE_appservice.as_token` would work as well, but can't be set in a shell as easily. +# +# If this is null, reading config fields from environment will be disabled. +env_config_prefix: null + +# Logging config. See https://github.com/tulir/zeroconfig for details. +logging: + min_level: {{ matrix_bridge_beeper_line_logging_level }} + writers: + - type: stdout + format: pretty diff --git a/roles/custom/matrix-bridge-beeper-line/templates/config.yaml.j2.license b/roles/custom/matrix-bridge-beeper-line/templates/config.yaml.j2.license new file mode 100644 index 000000000..bd628c0b6 --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/templates/config.yaml.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-beeper-line/templates/labels.j2 b/roles/custom/matrix-bridge-beeper-line/templates/labels.j2 new file mode 100644 index 000000000..f3f995b45 --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/templates/labels.j2 @@ -0,0 +1,49 @@ +{# +SPDX-FileCopyrightText: 2026 MDAD project contributors + +SPDX-License-Identifier: AGPL-3.0-or-later +#} + +{% if matrix_bridge_beeper_line_container_labels_traefik_enabled %} +traefik.enable=true + +{% if matrix_bridge_beeper_line_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_beeper_line_container_labels_traefik_docker_network }} +{% endif %} + +{% if matrix_bridge_beeper_line_container_labels_exposure_enabled %} +############################################################ +# # +# Bridge API exposure # +# # +############################################################ + +traefik.http.services.matrix-beeper-line-exposure.loadbalancer.server.port=29322 + +traefik.http.middlewares.matrix-beeper-line-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_beeper_line_exposure_path_prefix }} +traefik.http.routers.matrix-beeper-line-exposure.middlewares=matrix-beeper-line-exposure-strip-prefix + +traefik.http.routers.matrix-beeper-line-exposure.rule={{ matrix_bridge_beeper_line_container_labels_exposure_traefik_rule }} + +{% if matrix_bridge_beeper_line_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-beeper-line-exposure.priority={{ matrix_bridge_beeper_line_container_labels_exposure_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-beeper-line-exposure.service=matrix-beeper-line-exposure +traefik.http.routers.matrix-beeper-line-exposure.entrypoints={{ matrix_bridge_beeper_line_container_labels_exposure_traefik_entrypoints }} + +traefik.http.routers.matrix-beeper-line-exposure.tls={{ matrix_bridge_beeper_line_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_beeper_line_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-beeper-line-exposure.tls.certResolver={{ matrix_bridge_beeper_line_container_labels_exposure_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Bridge API exposure # +# # +############################################################ +{% endif %} + +{% endif %} + +{{ matrix_bridge_beeper_line_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk.service.j2 b/roles/custom/matrix-bridge-beeper-line/templates/systemd/matrix-beeper-line.service.j2 similarity index 53% rename from roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk.service.j2 rename to roles/custom/matrix-bridge-beeper-line/templates/systemd/matrix-beeper-line.service.j2 index e65572b55..a8787f180 100644 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk.service.j2 +++ b/roles/custom/matrix-bridge-beeper-line/templates/systemd/matrix-beeper-line.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] -Description=appservice-kakaotalk bridge -{% for service in matrix_appservice_kakaotalk_systemd_required_services_list %} +Description=Matrix Beeper LINE bridge +{% for service in matrix_bridge_beeper_line_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_appservice_kakaotalk_systemd_wanted_services_list %} +{% for service in matrix_bridge_beeper_line_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -13,35 +13,39 @@ DefaultDependencies=no [Service] Type=simple Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-appservice-kakaotalk 2>/dev/null || true' -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-appservice-kakaotalk 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-beeper-line 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-beeper-line 2>/dev/null || true' ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --rm \ - --name=matrix-appservice-kakaotalk \ + --name=matrix-beeper-line \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_appservice_kakaotalk_container_network }} \ - --mount type=bind,src={{ matrix_appservice_kakaotalk_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_appservice_kakaotalk_data_path }},dst=/data \ - {% for arg in matrix_appservice_kakaotalk_container_extra_arguments %} + --network={{ matrix_bridge_beeper_line_container_network }} \ + --mount type=bind,src={{ matrix_bridge_beeper_line_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_beeper_line_data_path }},dst=/data \ + --label-file={{ matrix_bridge_beeper_line_base_path }}/labels \ + --workdir=/data \ + {% for arg in matrix_bridge_beeper_line_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_appservice_kakaotalk_container_image }} \ - python3 -m matrix_appservice_kakaotalk -c /config/config.yaml --no-update + {{ matrix_bridge_beeper_line_container_image }} \ + /usr/bin/matrix-line -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_appservice_discord_container_additional_networks %} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-appservice-kakaotalk +{% if matrix_bridge_beeper_line_container_network != 'host' %} +{% for network in matrix_bridge_beeper_line_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-beeper-line {% endfor %} +{% endif %} -ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-appservice-kakaotalk +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-beeper-line -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-appservice-kakaotalk 2>/dev/null || true' -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-appservice-kakaotalk 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-beeper-line 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-beeper-line 2>/dev/null || true' Restart=always RestartSec=30 -SyslogIdentifier=matrix-appservice-kakaotalk +SyslogIdentifier=matrix-beeper-line [Install] WantedBy=multi-user.target diff --git a/roles/custom/matrix-bridge-beeper-line/templates/systemd/matrix-beeper-line.service.j2.license b/roles/custom/matrix-bridge-beeper-line/templates/systemd/matrix-beeper-line.service.j2.license new file mode 100644 index 000000000..bd628c0b6 --- /dev/null +++ b/roles/custom/matrix-bridge-beeper-line/templates/systemd/matrix-beeper-line.service.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-beeper-linkedin/defaults/main.yml b/roles/custom/matrix-bridge-beeper-linkedin/defaults/main.yml index bdec9b099..1f342e347 100644 --- a/roles/custom/matrix-bridge-beeper-linkedin/defaults/main.yml +++ b/roles/custom/matrix-bridge-beeper-linkedin/defaults/main.yml @@ -13,168 +13,163 @@ # beeper-linkedin is a Matrix <-> LinkedIn bridge # Project source code URL: https://github.com/beeper/linkedin -matrix_beeper_linkedin_enabled: true +matrix_bridge_beeper_linkedin_enabled: true # renovate: datasource=docker depName=ghcr.io/beeper/linkedin -matrix_beeper_linkedin_version: latest +matrix_bridge_beeper_linkedin_version: latest # See: https://github.com/beeper/linkedin/pkgs/container/linkedin -matrix_beeper_linkedin_container_image: "{{ matrix_beeper_linkedin_container_image_registry_prefix }}beeper/linkedin:{{ matrix_beeper_linkedin_container_image_tag }}" -matrix_beeper_linkedin_container_image_force_pull: "{{ matrix_beeper_linkedin_container_image_tag.startswith('latest') }}" -matrix_beeper_linkedin_container_image_registry_prefix: "{{ 'localhost/' if matrix_beeper_linkedin_container_image_self_build else matrix_beeper_linkedin_container_image_registry_prefix_upstream }}" -matrix_beeper_linkedin_container_image_registry_prefix_upstream: "{{ matrix_beeper_linkedin_container_image_registry_prefix_upstream_default }}" -matrix_beeper_linkedin_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_beeper_linkedin_container_image_tag: "{{ 'latest' if matrix_beeper_linkedin_version == 'master' else matrix_beeper_linkedin_version }}" - -matrix_beeper_linkedin_container_image_self_build: false -matrix_beeper_linkedin_container_image_self_build_repo: "https://github.com/beeper/linkedin" -matrix_beeper_linkedin_container_image_self_build_branch: "{{ 'master' if matrix_beeper_linkedin_version == 'latest' else matrix_beeper_linkedin_version }}" - -matrix_beeper_linkedin_base_path: "{{ matrix_base_data_path }}/beeper-linkedin" -matrix_beeper_linkedin_config_path: "{{ matrix_beeper_linkedin_base_path }}/config" -matrix_beeper_linkedin_data_path: "{{ matrix_beeper_linkedin_base_path }}/data" -matrix_beeper_linkedin_container_src_files_path: "{{ matrix_beeper_linkedin_base_path }}/docker-src" - -matrix_beeper_linkedin_homeserver_address: "" -matrix_beeper_linkedin_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_beeper_linkedin_container_image: "{{ matrix_bridge_beeper_linkedin_container_image_registry_prefix }}beeper/linkedin:{{ matrix_bridge_beeper_linkedin_container_image_tag }}" +matrix_bridge_beeper_linkedin_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_beeper_linkedin_container_image_self_build else matrix_bridge_beeper_linkedin_container_image_registry_prefix_upstream }}" +matrix_bridge_beeper_linkedin_container_image_registry_prefix_upstream: "{{ matrix_bridge_beeper_linkedin_container_image_registry_prefix_upstream_default }}" +matrix_bridge_beeper_linkedin_container_image_registry_prefix_upstream_default: "ghcr.io/" +matrix_bridge_beeper_linkedin_container_image_tag: "{{ 'latest' if matrix_bridge_beeper_linkedin_version == 'master' else matrix_bridge_beeper_linkedin_version }}" + +matrix_bridge_beeper_linkedin_container_image_self_build: false +matrix_bridge_beeper_linkedin_container_image_self_build_repo: "https://github.com/beeper/linkedin" +matrix_bridge_beeper_linkedin_container_image_self_build_branch: "{{ 'master' if matrix_bridge_beeper_linkedin_version == 'latest' else matrix_bridge_beeper_linkedin_version }}" + +matrix_bridge_beeper_linkedin_base_path: "{{ matrix_base_data_path }}/beeper-linkedin" +matrix_bridge_beeper_linkedin_config_path: "{{ matrix_bridge_beeper_linkedin_base_path }}/config" +matrix_bridge_beeper_linkedin_data_path: "{{ matrix_bridge_beeper_linkedin_base_path }}/data" +matrix_bridge_beeper_linkedin_container_src_files_path: "{{ matrix_bridge_beeper_linkedin_base_path }}/docker-src" + +matrix_bridge_beeper_linkedin_homeserver_address: "" +matrix_bridge_beeper_linkedin_homeserver_domain: "{{ matrix_domain }}" # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_beeper_linkedin_homeserver_async_media: false -matrix_beeper_linkedin_appservice_address: "http://matrix-beeper-linkedin:29319" +matrix_bridge_beeper_linkedin_homeserver_async_media: false +matrix_bridge_beeper_linkedin_appservice_address: "http://matrix-beeper-linkedin:29319" -matrix_beeper_linkedin_bridge_presence: true +matrix_bridge_beeper_linkedin_bridge_presence: true -matrix_beeper_linkedin_bridge_space_support_enable: true +matrix_bridge_beeper_linkedin_bridge_space_support_enable: true -matrix_beeper_linkedin_command_prefix: "!li" +matrix_bridge_beeper_linkedin_command_prefix: "!li" -matrix_beeper_linkedin_bridge_permissions: | +matrix_bridge_beeper_linkedin_bridge_permissions: | {{ - {matrix_beeper_linkedin_homeserver_domain: 'user'} + {matrix_bridge_beeper_linkedin_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} -matrix_beeper_linkedin_container_network: "" +matrix_bridge_beeper_linkedin_container_network: "" -matrix_beeper_linkedin_container_additional_networks: "{{ matrix_beeper_linkedin_container_additional_networks_auto + matrix_beeper_linkedin_container_additional_networks_custom }}" -matrix_beeper_linkedin_container_additional_networks_auto: [] -matrix_beeper_linkedin_container_additional_networks_custom: [] +matrix_bridge_beeper_linkedin_container_additional_networks: "{{ matrix_bridge_beeper_linkedin_container_additional_networks_auto + matrix_bridge_beeper_linkedin_container_additional_networks_custom }}" +matrix_bridge_beeper_linkedin_container_additional_networks_auto: [] +matrix_bridge_beeper_linkedin_container_additional_networks_custom: [] # A list of extra arguments to pass to the container -matrix_beeper_linkedin_container_extra_arguments: [] +matrix_bridge_beeper_linkedin_container_extra_arguments: [] # List of systemd services that matrix-beeper-linkedin.service depends on. -matrix_beeper_linkedin_systemd_required_services_list: "{{ matrix_beeper_linkedin_systemd_required_services_list_default + matrix_beeper_linkedin_systemd_required_services_list_auto + matrix_beeper_linkedin_systemd_required_services_list_custom }}" -matrix_beeper_linkedin_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_beeper_linkedin_systemd_required_services_list_auto: [] -matrix_beeper_linkedin_systemd_required_services_list_custom: [] +matrix_bridge_beeper_linkedin_systemd_required_services_list: "{{ matrix_bridge_beeper_linkedin_systemd_required_services_list_default + matrix_bridge_beeper_linkedin_systemd_required_services_list_auto + matrix_bridge_beeper_linkedin_systemd_required_services_list_custom }}" +matrix_bridge_beeper_linkedin_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_beeper_linkedin_systemd_required_services_list_auto: [] +matrix_bridge_beeper_linkedin_systemd_required_services_list_custom: [] # List of systemd services that matrix-beeper-linkedin.service wants -matrix_beeper_linkedin_systemd_wanted_services_list: [] +matrix_bridge_beeper_linkedin_systemd_wanted_services_list: [] -matrix_beeper_linkedin_appservice_token: "" -matrix_beeper_linkedin_homeserver_token: "" +matrix_bridge_beeper_linkedin_appservice_token: "" +matrix_bridge_beeper_linkedin_homeserver_token: "" -matrix_beeper_linkedin_appservice_bot_username: linkedinbot -matrix_beeper_linkedin_appservice_bot_displayname: LinkedIn bridge bot -matrix_beeper_linkedin_appservice_bot_avatar: mxc://nevarro.space/cwsWnmeMpWSMZLUNblJHaIvP +matrix_bridge_beeper_linkedin_appservice_bot_username: linkedinbot +matrix_bridge_beeper_linkedin_appservice_bot_displayname: LinkedIn bridge bot +matrix_bridge_beeper_linkedin_appservice_bot_avatar: mxc://nevarro.space/cwsWnmeMpWSMZLUNblJHaIvP # Database-related configuration fields. # Only Postgres is supported. -matrix_beeper_linkedin_database_engine: "postgres" +matrix_bridge_beeper_linkedin_database_engine: "postgres" -matrix_beeper_linkedin_database_username: 'matrix_beeper_linkedin' -matrix_beeper_linkedin_database_password: 'some-password' -matrix_beeper_linkedin_database_hostname: '' -matrix_beeper_linkedin_database_port: 5432 -matrix_beeper_linkedin_database_name: 'matrix_beeper_linkedin' -matrix_beeper_linkedin_database_sslmode: disable +matrix_bridge_beeper_linkedin_database_username: 'matrix_beeper_linkedin' +matrix_bridge_beeper_linkedin_database_password: 'some-password' +matrix_bridge_beeper_linkedin_database_hostname: '' +matrix_bridge_beeper_linkedin_database_port: 5432 +matrix_bridge_beeper_linkedin_database_name: 'matrix_beeper_linkedin' +matrix_bridge_beeper_linkedin_database_sslmode: disable -matrix_beeper_linkedin_database_connection_string: 'postgresql://{{ matrix_beeper_linkedin_database_username }}:{{ matrix_beeper_linkedin_database_password }}@{{ matrix_beeper_linkedin_database_hostname }}:{{ matrix_beeper_linkedin_database_port }}/{{ matrix_beeper_linkedin_database_name }}?sslmode={{ matrix_beeper_linkedin_database_sslmode }}' +matrix_bridge_beeper_linkedin_database_connection_string: 'postgresql://{{ matrix_bridge_beeper_linkedin_database_username }}:{{ matrix_bridge_beeper_linkedin_database_password }}@{{ matrix_bridge_beeper_linkedin_database_hostname }}:{{ matrix_bridge_beeper_linkedin_database_port }}/{{ matrix_bridge_beeper_linkedin_database_name }}?sslmode={{ matrix_bridge_beeper_linkedin_database_sslmode }}' -matrix_beeper_linkedin_appservice_database_type: "{{ - { - 'postgres':'postgres', - }[matrix_beeper_linkedin_database_engine] -}}" +matrix_bridge_beeper_linkedin_appservice_database_type: "{{ { + 'postgres': 'postgres', +}[matrix_bridge_beeper_linkedin_database_engine] }}" -matrix_beeper_linkedin_appservice_database_uri: "{{ - { - 'postgres': matrix_beeper_linkedin_database_connection_string, - }[matrix_beeper_linkedin_database_engine] -}}" +matrix_bridge_beeper_linkedin_appservice_database_uri: "{{ { + 'postgres': matrix_bridge_beeper_linkedin_database_connection_string, +}[matrix_bridge_beeper_linkedin_database_engine] }}" -matrix_beeper_linkedin_bridge_login_shared_secret_map: "{{ matrix_beeper_linkedin_bridge_login_shared_secret_map_auto | combine(matrix_beeper_linkedin_bridge_login_shared_secret_map_custom) }}" -matrix_beeper_linkedin_bridge_login_shared_secret_map_auto: {} -matrix_beeper_linkedin_bridge_login_shared_secret_map_custom: {} +matrix_bridge_beeper_linkedin_bridge_login_shared_secret_map: "{{ matrix_bridge_beeper_linkedin_bridge_login_shared_secret_map_auto | combine(matrix_bridge_beeper_linkedin_bridge_login_shared_secret_map_custom) }}" +matrix_bridge_beeper_linkedin_bridge_login_shared_secret_map_auto: {} +matrix_bridge_beeper_linkedin_bridge_login_shared_secret_map_custom: {} # Servers to always allow double puppeting from -matrix_beeper_linkedin_bridge_double_puppet_server_map: "{{ matrix_beeper_linkedin_bridge_double_puppet_server_map_default | combine(matrix_beeper_linkedin_bridge_double_puppet_server_map_auto) | combine(matrix_beeper_linkedin_bridge_double_puppet_server_map_custom) }}" -matrix_beeper_linkedin_bridge_double_puppet_server_map_default: |- +matrix_bridge_beeper_linkedin_bridge_double_puppet_server_map: "{{ matrix_bridge_beeper_linkedin_bridge_double_puppet_server_map_default | combine(matrix_bridge_beeper_linkedin_bridge_double_puppet_server_map_auto) | combine(matrix_bridge_beeper_linkedin_bridge_double_puppet_server_map_custom) }}" +matrix_bridge_beeper_linkedin_bridge_double_puppet_server_map_default: |- {{ {} | combine({ - matrix_beeper_linkedin_homeserver_domain: matrix_beeper_linkedin_homeserver_address + matrix_bridge_beeper_linkedin_homeserver_domain: matrix_bridge_beeper_linkedin_homeserver_address }) }} -matrix_beeper_linkedin_bridge_double_puppet_server_map_auto: {} -matrix_beeper_linkedin_bridge_double_puppet_server_map_custom: {} +matrix_bridge_beeper_linkedin_bridge_double_puppet_server_map_auto: {} +matrix_bridge_beeper_linkedin_bridge_double_puppet_server_map_custom: {} -matrix_beeper_linkedin_provisioning_enabled: false -matrix_beeper_linkedin_provisioning_shared_secret: '' +matrix_bridge_beeper_linkedin_provisioning_enabled: false +matrix_bridge_beeper_linkedin_provisioning_shared_secret: '' # Specifies the default log level for all bridge loggers. -matrix_beeper_linkedin_logging_level: WARNING +matrix_bridge_beeper_linkedin_logging_level: WARNING # Enable End-to-bridge encryption -matrix_beeper_linkedin_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_beeper_linkedin_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_beeper_linkedin_bridge_encryption_appservice: "{{ matrix_beeper_linkedin_bridge_encryption_default }}" -matrix_beeper_linkedin_bridge_encryption_require: false -matrix_beeper_linkedin_bridge_encryption_key_sharing_allow: "{{ matrix_beeper_linkedin_bridge_encryption_allow }}" +matrix_bridge_beeper_linkedin_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_beeper_linkedin_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_beeper_linkedin_bridge_encryption_appservice: "{{ matrix_bridge_beeper_linkedin_bridge_encryption_default }}" +matrix_bridge_beeper_linkedin_bridge_encryption_require: false +matrix_bridge_beeper_linkedin_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_beeper_linkedin_bridge_encryption_allow }}" # Default beeper-linkedin configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_beeper_linkedin_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_beeper_linkedin_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_beeper_linkedin_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_beeper_linkedin_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_beeper_linkedin_configuration_extension_yaml: | +matrix_bridge_beeper_linkedin_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_beeper_linkedin_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_beeper_linkedin_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_beeper_linkedin_configuration_yaml`. + # completely redefining `matrix_bridge_beeper_linkedin_configuration_yaml`. -matrix_beeper_linkedin_configuration_extension: "{{ matrix_beeper_linkedin_configuration_extension_yaml | from_yaml if matrix_beeper_linkedin_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_beeper_linkedin_configuration_extension: "{{ matrix_bridge_beeper_linkedin_configuration_extension_yaml | from_yaml if matrix_bridge_beeper_linkedin_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_beeper_linkedin_configuration_yaml`. -matrix_beeper_linkedin_configuration: "{{ matrix_beeper_linkedin_configuration_yaml | from_yaml | combine(matrix_beeper_linkedin_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_beeper_linkedin_configuration_yaml`. +matrix_bridge_beeper_linkedin_configuration: "{{ matrix_bridge_beeper_linkedin_configuration_yaml | from_yaml | combine(matrix_bridge_beeper_linkedin_configuration_extension, recursive=True) }}" -matrix_beeper_linkedin_registration_yaml: | +matrix_bridge_beeper_linkedin_registration_yaml: | id: beeper_linkedin - url: {{ matrix_beeper_linkedin_appservice_address }} - as_token: "{{ matrix_beeper_linkedin_appservice_token }}" - hs_token: "{{ matrix_beeper_linkedin_homeserver_token }}" + url: {{ matrix_bridge_beeper_linkedin_appservice_address }} + as_token: "{{ matrix_bridge_beeper_linkedin_appservice_token }}" + hs_token: "{{ matrix_bridge_beeper_linkedin_homeserver_token }}" - sender_localpart: _bot_{{ matrix_beeper_linkedin_appservice_bot_username }} + sender_localpart: _bot_{{ matrix_bridge_beeper_linkedin_appservice_bot_username }} rate_limited: false namespaces: users: - - regex: '^@linkedin_.+:{{ matrix_beeper_linkedin_homeserver_domain | regex_escape }}$' + - regex: '^@linkedin_.+:{{ matrix_bridge_beeper_linkedin_homeserver_domain | regex_escape }}$' exclusive: true - exclusive: true - regex: '^@{{ matrix_beeper_linkedin_appservice_bot_username | regex_escape }}:{{ matrix_beeper_linkedin_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_beeper_linkedin_appservice_bot_username | regex_escape }}:{{ matrix_bridge_beeper_linkedin_homeserver_domain | regex_escape }}$' de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true -matrix_beeper_linkedin_registration: "{{ matrix_beeper_linkedin_registration_yaml | from_yaml }}" +matrix_bridge_beeper_linkedin_registration: "{{ matrix_bridge_beeper_linkedin_registration_yaml | from_yaml }}" -# matrix_beeper_linkedin_restart_necessary controls whether the service +# matrix_bridge_beeper_linkedin_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -182,4 +177,4 @@ matrix_beeper_linkedin_registration: "{{ matrix_beeper_linkedin_registration_yam # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_beeper_linkedin_restart_necessary: false +matrix_bridge_beeper_linkedin_restart_necessary: false diff --git a/roles/custom/matrix-bridge-beeper-linkedin/tasks/main.yml b/roles/custom/matrix-bridge-beeper-linkedin/tasks/main.yml index 34a4ea3dd..ea7de37b1 100644 --- a/roles/custom/matrix-bridge-beeper-linkedin/tasks/main.yml +++ b/roles/custom/matrix-bridge-beeper-linkedin/tasks/main.yml @@ -12,15 +12,15 @@ - install-all - install-beeper-linkedin block: - - when: matrix_beeper_linkedin_enabled | bool + - when: matrix_bridge_beeper_linkedin_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_beeper_linkedin_enabled | bool + - when: matrix_bridge_beeper_linkedin_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-beeper-linkedin block: - - when: not matrix_beeper_linkedin_enabled | bool + - when: not matrix_bridge_beeper_linkedin_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-beeper-linkedin/tasks/setup_install.yml b/roles/custom/matrix-bridge-beeper-linkedin/tasks/setup_install.yml index a871105e6..163d83559 100644 --- a/roles/custom/matrix-bridge-beeper-linkedin/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-beeper-linkedin/tasks/setup_install.yml @@ -19,53 +19,60 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_beeper_linkedin_base_path }}", when: true} - - {path: "{{ matrix_beeper_linkedin_config_path }}", when: true} - - {path: "{{ matrix_beeper_linkedin_data_path }}", when: true} - - {path: "{{ matrix_beeper_linkedin_container_src_files_path }}", when: "{{ matrix_beeper_linkedin_container_image_self_build }}"} + - {path: "{{ matrix_bridge_beeper_linkedin_base_path }}", when: true} + - {path: "{{ matrix_bridge_beeper_linkedin_config_path }}", when: true} + - {path: "{{ matrix_bridge_beeper_linkedin_data_path }}", when: true} + - {path: "{{ matrix_bridge_beeper_linkedin_container_src_files_path }}", when: "{{ matrix_bridge_beeper_linkedin_container_image_self_build }}"} when: "item.when | bool" - name: Ensure beeper-linkedin config.yaml installed ansible.builtin.copy: - content: "{{ matrix_beeper_linkedin_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_beeper_linkedin_config_path }}/config.yaml" + content: "{{ matrix_bridge_beeper_linkedin_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_beeper_linkedin_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_beeper_linkedin_config_result + register: matrix_bridge_beeper_linkedin_config_result - name: Ensure beeper-linkedin registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_beeper_linkedin_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_beeper_linkedin_config_path }}/registration.yaml" + content: "{{ matrix_bridge_beeper_linkedin_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_beeper_linkedin_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_beeper_linkedin_registration_result + register: matrix_bridge_beeper_linkedin_registration_result - name: Ensure Beeper LinkedIn container image is pulled - community.docker.docker_image: - name: "{{ matrix_beeper_linkedin_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_beeper_linkedin_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_beeper_linkedin_container_image_force_pull }}" - when: "not matrix_beeper_linkedin_container_image_self_build | bool" - register: matrix_beeper_linkedin_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_beeper_linkedin_container_image }}" + pull: always + when: "not matrix_bridge_beeper_linkedin_container_image_self_build | bool" + register: matrix_bridge_beeper_linkedin_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_beeper_linkedin_container_image_pull_result is not failed + until: matrix_bridge_beeper_linkedin_container_image_pull_result is not failed -- when: "matrix_beeper_linkedin_container_image_self_build | bool" +- when: "matrix_bridge_beeper_linkedin_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure Beeper LinkedIn repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_beeper_linkedin_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure Beeper LinkedIn repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_beeper_linkedin_container_image_self_build_repo }}" - dest: "{{ matrix_beeper_linkedin_container_src_files_path }}" - version: "{{ matrix_beeper_linkedin_container_image_self_build_branch }}" + repo: "{{ matrix_bridge_beeper_linkedin_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_beeper_linkedin_container_src_files_path }}" + version: "{{ matrix_bridge_beeper_linkedin_container_image_self_build_branch }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_beeper_linkedin_git_pull_results + register: matrix_bridge_beeper_linkedin_git_pull_results # Building the container image (using the default Dockerfile) requires that a docker-requirements.txt file be generated. # See: https://github.com/beeper/linkedin/blob/94442db17ccb9769b377cdb8e4bf1cb3955781d7/.gitlab-ci.yml#L30-40 @@ -75,30 +82,29 @@ {{ devture_systemd_docker_base_host_command_docker }} run --rm --entrypoint=/bin/sh - --mount type=bind,src={{ matrix_beeper_linkedin_container_src_files_path }},dst=/work + --mount type=bind,src={{ matrix_bridge_beeper_linkedin_container_src_files_path }},dst=/work -w /work docker.io/python:3.9.6-buster -c "pip install poetry && poetry export --without-hashes -E e2be -E images -E metrics | sed 's/==.*//g' > docker-requirements.txt" - register: matrix_beeper_linkedin_generate_docker_requirements_result - changed_when: matrix_beeper_linkedin_generate_docker_requirements_result.rc == 0 + register: matrix_bridge_beeper_linkedin_generate_docker_requirements_result + changed_when: matrix_bridge_beeper_linkedin_generate_docker_requirements_result.rc == 0 - name: Ensure Beeper LinkedIn container image is built - community.docker.docker_image: - name: "{{ matrix_beeper_linkedin_container_image }}" - source: build - force_source: "{{ matrix_beeper_linkedin_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_beeper_linkedin_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_beeper_linkedin_container_src_files_path }}" - pull: true - args: - TARGETARCH: "{{ matrix_architecture }}" + community.docker.docker_image_build: + name: "{{ matrix_bridge_beeper_linkedin_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_beeper_linkedin_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_beeper_linkedin_git_pull_results.changed | bool else 'never' }}" + args: + TARGETARCH: "{{ matrix_architecture }}" + register: matrix_bridge_beeper_linkedin_container_image_build_result - name: Ensure beeper-linkedin container network is created + when: matrix_bridge_beeper_linkedin_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_beeper_linkedin_container_network }}" + name: "{{ matrix_bridge_beeper_linkedin_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -107,14 +113,15 @@ src: "{{ role_path }}/templates/systemd/matrix-beeper-linkedin.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-beeper-linkedin.service" mode: '0644' - register: matrix_beeper_linkedin_systemd_service_result + register: matrix_bridge_beeper_linkedin_systemd_service_result - name: Determine whether matrix-beeper-linkedin needs a restart ansible.builtin.set_fact: - matrix_beeper_linkedin_restart_necessary: >- + matrix_bridge_beeper_linkedin_restart_necessary: >- {{ - matrix_beeper_linkedin_config_result.changed | default(false) - or matrix_beeper_linkedin_registration_result.changed | default(false) - or matrix_beeper_linkedin_systemd_service_result.changed | default(false) - or matrix_beeper_linkedin_container_image_pull_result.changed | default(false) + matrix_bridge_beeper_linkedin_config_result.changed | default(false) + or matrix_bridge_beeper_linkedin_registration_result.changed | default(false) + or matrix_bridge_beeper_linkedin_systemd_service_result.changed | default(false) + or matrix_bridge_beeper_linkedin_container_image_pull_result.changed | default(false) + or matrix_bridge_beeper_linkedin_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-bridge-beeper-linkedin/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-beeper-linkedin/tasks/setup_uninstall.yml index aea2f34cf..5b1b45659 100644 --- a/roles/custom/matrix-bridge-beeper-linkedin/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-beeper-linkedin/tasks/setup_uninstall.yml @@ -9,9 +9,9 @@ - name: Check existence of matrix-beeper-linkedin service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-beeper-linkedin.service" - register: matrix_beeper_linkedin_service_stat + register: matrix_bridge_beeper_linkedin_service_stat -- when: matrix_beeper_linkedin_service_stat.stat.exists | bool +- when: matrix_bridge_beeper_linkedin_service_stat.stat.exists | bool block: - name: Ensure matrix-beeper-linkedin is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-beeper-linkedin/tasks/validate_config.yml b/roles/custom/matrix-bridge-beeper-linkedin/tasks/validate_config.yml index f993c923f..0f0b55955 100644 --- a/roles/custom/matrix-bridge-beeper-linkedin/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-beeper-linkedin/tasks/validate_config.yml @@ -14,15 +14,16 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_beeper_linkedin_login_shared_secret', 'new': ''} - - {'old': 'matrix_beeper_linkedin_docker_image_name_prefix', 'new': 'matrix_beeper_linkedin_container_image_registry_prefix'} - - {'old': 'matrix_beeper_linkedin_docker_image', 'new': 'matrix_beeper_linkedin_container_image'} - - {'old': 'matrix_beeper_linkedin_docker_image_force_pull', 'new': 'matrix_beeper_linkedin_container_image_force_pull'} - - {'old': 'matrix_beeper_linkedin_docker_image_registry_prefix', 'new': 'matrix_beeper_linkedin_container_image_registry_prefix'} - - {'old': 'matrix_beeper_linkedin_docker_image_registry_prefix_upstream', 'new': 'matrix_beeper_linkedin_container_image_registry_prefix_upstream'} - - {'old': 'matrix_beeper_linkedin_docker_image_registry_prefix_upstream_default', 'new': 'matrix_beeper_linkedin_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_beeper_linkedin_docker_image_tag', 'new': 'matrix_beeper_linkedin_container_image_tag'} - - {'old': 'matrix_beeper_linkedin_docker_src_files_path', 'new': 'matrix_beeper_linkedin_container_src_files_path'} + - {'old': 'matrix_bridge_beeper_linkedin_login_shared_secret', 'new': ''} + - {'old': 'matrix_bridge_beeper_linkedin_docker_image_name_prefix', 'new': 'matrix_bridge_beeper_linkedin_container_image_registry_prefix'} + - {'old': 'matrix_bridge_beeper_linkedin_docker_image', 'new': 'matrix_bridge_beeper_linkedin_container_image'} + - {'old': 'matrix_bridge_beeper_linkedin_docker_image_force_pull', 'new': 'matrix_bridge_beeper_linkedin_container_image_force_pull'} + - {'old': 'matrix_bridge_beeper_linkedin_docker_image_registry_prefix', 'new': 'matrix_bridge_beeper_linkedin_container_image_registry_prefix'} + - {'old': 'matrix_bridge_beeper_linkedin_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_beeper_linkedin_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_beeper_linkedin_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_beeper_linkedin_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_beeper_linkedin_docker_image_tag', 'new': 'matrix_bridge_beeper_linkedin_container_image_tag'} + - {'old': 'matrix_bridge_beeper_linkedin_docker_src_files_path', 'new': 'matrix_bridge_beeper_linkedin_container_src_files_path'} + - {'old': 'matrix_bridge_beeper_linkedin_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required beeper-linkedin settings not defined ansible.builtin.fail: @@ -30,8 +31,8 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_beeper_linkedin_appservice_token', when: true} - - {'name': 'matrix_beeper_linkedin_homeserver_address', when: true} - - {'name': 'matrix_beeper_linkedin_homeserver_token', when: true} - - {'name': 'matrix_beeper_linkedin_database_hostname', when: "{{ matrix_beeper_linkedin_database_engine == 'postgres' }}"} - - {'name': 'matrix_beeper_linkedin_container_network', when: true} + - {'name': 'matrix_bridge_beeper_linkedin_appservice_token', when: true} + - {'name': 'matrix_bridge_beeper_linkedin_homeserver_address', when: true} + - {'name': 'matrix_bridge_beeper_linkedin_homeserver_token', when: true} + - {'name': 'matrix_bridge_beeper_linkedin_database_hostname', when: "{{ matrix_bridge_beeper_linkedin_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_beeper_linkedin_container_network', when: true} diff --git a/roles/custom/matrix-bridge-beeper-linkedin/templates/config.yaml.j2 b/roles/custom/matrix-bridge-beeper-linkedin/templates/config.yaml.j2 index 2213b1fde..4d6fc445b 100644 --- a/roles/custom/matrix-bridge-beeper-linkedin/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-beeper-linkedin/templates/config.yaml.j2 @@ -2,9 +2,9 @@ # Homeserver details homeserver: # The address that this appservice can use to connect to the homeserver. - address: {{ matrix_beeper_linkedin_homeserver_address | to_json }} + address: {{ matrix_bridge_beeper_linkedin_homeserver_address | to_json }} # The domain of the homeserver (for MXIDs, etc). - domain: {{ matrix_beeper_linkedin_homeserver_domain | to_json }} + domain: {{ matrix_bridge_beeper_linkedin_homeserver_domain | to_json }} # Whether or not to verify the SSL certificate of the homeserver. # Only applies if address starts with https:// verify_ssl: true @@ -21,13 +21,13 @@ homeserver: message_send_checkpoint_endpoint: null # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a media repo that supports MSC2246. - async_media: {{ matrix_beeper_linkedin_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_beeper_linkedin_homeserver_async_media | to_json }} # Application service host/registration related details # Changing these values requires regeneration of the registration. appservice: # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_beeper_linkedin_appservice_address | to_json }} + address: {{ matrix_bridge_beeper_linkedin_appservice_address | to_json }} # The hostname and port where this appservice should listen. hostname: 0.0.0.0 @@ -40,7 +40,7 @@ appservice: # Format examples: # SQLite: sqlite:filename.db # Postgres: postgres://username:password@hostname/dbname - database: {{ matrix_beeper_linkedin_appservice_database_uri | to_json }} + database: {{ matrix_bridge_beeper_linkedin_appservice_database_uri | to_json }} # Additional arguments for asyncpg.create_pool() or sqlite3.connect() # https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.pool.create_pool # https://docs.python.org/3/library/sqlite3.html#sqlite3.connect @@ -54,21 +54,21 @@ appservice: # Used by things like mautrix-manager (https://github.com/tulir/mautrix-manager). provisioning: # Whether or not the provisioning API should be enabled. - enabled: {{ matrix_beeper_linkedin_provisioning_enabled | to_json }} + enabled: {{ matrix_bridge_beeper_linkedin_provisioning_enabled | to_json }} # The prefix to use in the provisioning API endpoints. prefix: /_matrix/provision/v1 # The shared secret to authorize users of the API. # Set to "generate" to generate and save a new token. - shared_secret: {{ matrix_beeper_linkedin_provisioning_shared_secret | to_json }} + shared_secret: {{ matrix_bridge_beeper_linkedin_provisioning_shared_secret | to_json }} # The unique ID of this appservice. id: beeper_linkedin # Username of the appservice bot. - bot_username: {{ matrix_beeper_linkedin_appservice_bot_username | to_json }} + bot_username: {{ matrix_bridge_beeper_linkedin_appservice_bot_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. - bot_displayname: {{ matrix_beeper_linkedin_appservice_bot_displayname | to_json(ensure_ascii=False) }} - bot_avatar: {{ matrix_beeper_linkedin_appservice_bot_avatar | to_json }} + bot_displayname: {{ matrix_bridge_beeper_linkedin_appservice_bot_displayname | to_json(ensure_ascii=False) }} + bot_avatar: {{ matrix_bridge_beeper_linkedin_appservice_bot_avatar | to_json }} # Whether or not to receive ephemeral events via appservice transactions. # Requires MSC2409 support (i.e. Synapse 1.22+). @@ -76,8 +76,8 @@ appservice: ephemeral_events: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_beeper_linkedin_appservice_token | to_json }} - hs_token: {{ matrix_beeper_linkedin_homeserver_token | to_json }} + as_token: {{ matrix_bridge_beeper_linkedin_appservice_token | to_json }} + hs_token: {{ matrix_bridge_beeper_linkedin_homeserver_token | to_json }} # Segment-compatible analytics endpoint for tracking some events, like provisioning API login and encryption errors. analytics: @@ -113,7 +113,7 @@ bridge: space_support: # Whether or not to enable creating a space per user and inviting the # user (as well as all of the puppets) to that space. - enable: {{ matrix_beeper_linkedin_bridge_space_support_enable | to_json }} + enable: {{ matrix_bridge_beeper_linkedin_bridge_space_support_enable | to_json }} # The name of the space name: "LinkedIn" # Displayname template for LinkedIn users. @@ -134,7 +134,7 @@ bridge: set_topic_on_dms: true # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_beeper_linkedin_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_beeper_linkedin_command_prefix | to_json }} # Number of chats to sync (and create portals for) on startup/login. # Set 0 to disable automatic syncing. @@ -150,7 +150,7 @@ bridge: # and is therefore prone to race conditions. sync_direct_chat_list: false # Servers to always allow double puppeting from - double_puppet_server_map: {{ matrix_beeper_linkedin_bridge_double_puppet_server_map | to_json }} + double_puppet_server_map: {{ matrix_bridge_beeper_linkedin_bridge_double_puppet_server_map | to_json }} # Allow using double puppeting from any server with a valid client .well-known file. double_puppet_allow_discovery: false # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth @@ -160,10 +160,10 @@ bridge: # manually. # If using this for other servers than the bridge's server, # you must also set the URL in the double_puppet_server_map. - login_shared_secret_map: {{ matrix_beeper_linkedin_bridge_login_shared_secret_map | to_json }} + login_shared_secret_map: {{ matrix_bridge_beeper_linkedin_bridge_login_shared_secret_map | to_json }} # Whether or not to bridge presence in both directions. LinkedIn allows users not to broadcast # presence, but then it won't send other users' presence to the client. - presence: {{ matrix_beeper_linkedin_bridge_presence | to_json }} + presence: {{ matrix_bridge_beeper_linkedin_bridge_presence | to_json }} # Whether or not to update avatars when syncing all contacts at startup. update_avatar_initial_sync: true # Whether or not created rooms should have federation enabled. @@ -180,17 +180,17 @@ bridge: # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Allow encryption, work in group chat rooms with e2ee enabled - allow: {{ matrix_beeper_linkedin_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_beeper_linkedin_bridge_encryption_allow | to_json }} # Default to encryption, force-enable encryption in all portals the bridge creates # This will cause the bridge bot to be in private chats for the encryption to work properly. - default: {{ matrix_beeper_linkedin_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_beeper_linkedin_bridge_encryption_default | to_json }} # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. - appservice: {{ matrix_beeper_linkedin_bridge_encryption_appservice | to_json }} + appservice: {{ matrix_bridge_beeper_linkedin_bridge_encryption_appservice | to_json }} # Require encryption, drop any unencrypted messages. - require: {{ matrix_beeper_linkedin_bridge_encryption_require | to_json }} + require: {{ matrix_bridge_beeper_linkedin_bridge_encryption_require | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_beeper_linkedin_bridge_encryption_key_sharing_allow | to_json }} + allow_key_sharing: {{ matrix_bridge_beeper_linkedin_bridge_encryption_key_sharing_allow | to_json }} # Options for deleting megolm sessions from the bridge. delete_keys: # Beeper-specific: delete outbound sessions when hungryserv confirms @@ -314,7 +314,7 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_beeper_linkedin_bridge_permissions | to_json }} + permissions: {{ matrix_bridge_beeper_linkedin_bridge_permissions | to_json }} # Python logging configuration. # @@ -334,9 +334,9 @@ logging: formatter: colored loggers: mau: - level: {{ matrix_beeper_linkedin_logging_level|to_json }} + level: {{ matrix_bridge_beeper_linkedin_logging_level|to_json }} aiohttp: - level: {{ matrix_beeper_linkedin_logging_level|to_json }} + level: {{ matrix_bridge_beeper_linkedin_logging_level|to_json }} root: level: DEBUG handlers: [console] diff --git a/roles/custom/matrix-bridge-beeper-linkedin/templates/systemd/matrix-beeper-linkedin.service.j2 b/roles/custom/matrix-bridge-beeper-linkedin/templates/systemd/matrix-beeper-linkedin.service.j2 index 327813430..faf4aa61d 100644 --- a/roles/custom/matrix-bridge-beeper-linkedin/templates/systemd/matrix-beeper-linkedin.service.j2 +++ b/roles/custom/matrix-bridge-beeper-linkedin/templates/systemd/matrix-beeper-linkedin.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Beeper Linkedin bridge -{% for service in matrix_beeper_linkedin_systemd_required_services_list %} +{% for service in matrix_bridge_beeper_linkedin_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_beeper_linkedin_systemd_wanted_services_list %} +{% for service in matrix_bridge_beeper_linkedin_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,18 +22,20 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_beeper_linkedin_container_network }} \ - --mount type=bind,src={{ matrix_beeper_linkedin_config_path }},dst=/config,ro \ + --network={{ matrix_bridge_beeper_linkedin_container_network }} \ + --mount type=bind,src={{ matrix_bridge_beeper_linkedin_config_path }},dst=/config,ro \ --workdir=/opt/linkedin-matrix \ - {% for arg in matrix_beeper_linkedin_container_extra_arguments %} + {% for arg in matrix_bridge_beeper_linkedin_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_beeper_linkedin_container_image }} \ + {{ matrix_bridge_beeper_linkedin_container_image }} \ python3 -m linkedin_matrix -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_beeper_linkedin_container_additional_networks %} +{% if matrix_bridge_beeper_linkedin_container_network != 'host' %} +{% for network in matrix_bridge_beeper_linkedin_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-beeper-linkedin {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-beeper-linkedin diff --git a/roles/custom/matrix-bridge-heisenbridge/defaults/main.yml b/roles/custom/matrix-bridge-heisenbridge/defaults/main.yml index 019e30d03..73306c13e 100644 --- a/roles/custom/matrix-bridge-heisenbridge/defaults/main.yml +++ b/roles/custom/matrix-bridge-heisenbridge/defaults/main.yml @@ -12,106 +12,105 @@ # Heisenbridge is a bouncer-style Matrix IRC bridge # Project source code URL: https://github.com/hifi/heisenbridge -matrix_heisenbridge_enabled: true +matrix_bridge_heisenbridge_enabled: true -matrix_heisenbridge_scheme: https -matrix_heisenbridge_hostname: "{{ matrix_server_fqn_matrix }}" -matrix_heisenbridge_path_prefix: "/heisenbridge" +matrix_bridge_heisenbridge_scheme: https +matrix_bridge_heisenbridge_hostname: "{{ matrix_server_fqn_matrix }}" +matrix_bridge_heisenbridge_path_prefix: "/heisenbridge" # renovate: datasource=docker depName=hif1/heisenbridge -matrix_heisenbridge_version: 1.15.4 -matrix_heisenbridge_container_image: "{{ matrix_heisenbridge_container_image_registry_prefix }}hif1/heisenbridge:{{ matrix_heisenbridge_version }}" -matrix_heisenbridge_container_image_registry_prefix: "{{ matrix_heisenbridge_container_image_registry_prefix_upstream }}" -matrix_heisenbridge_container_image_registry_prefix_upstream: "{{ matrix_heisenbridge_container_image_registry_prefix_upstream_default }}" -matrix_heisenbridge_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_heisenbridge_container_image_force_pull: "{{ matrix_heisenbridge_container_image.endswith(':latest') }}" +matrix_bridge_heisenbridge_version: 1.15.4 +matrix_bridge_heisenbridge_container_image: "{{ matrix_bridge_heisenbridge_container_image_registry_prefix }}hif1/heisenbridge:{{ matrix_bridge_heisenbridge_version }}" +matrix_bridge_heisenbridge_container_image_registry_prefix: "{{ matrix_bridge_heisenbridge_container_image_registry_prefix_upstream }}" +matrix_bridge_heisenbridge_container_image_registry_prefix_upstream: "{{ matrix_bridge_heisenbridge_container_image_registry_prefix_upstream_default }}" +matrix_bridge_heisenbridge_container_image_registry_prefix_upstream_default: "docker.io/" # Set this to your Matrix ID if you want to enforce the owner, otherwise first _local_ user becomes one -matrix_heisenbridge_owner: "" +matrix_bridge_heisenbridge_owner: "" # Enabling identd will bind to host port 113/TCP -matrix_heisenbridge_identd_enabled: false +matrix_bridge_heisenbridge_identd_enabled: false -matrix_heisenbridge_base_path: "{{ matrix_base_data_path }}/heisenbridge" +matrix_bridge_heisenbridge_base_path: "{{ matrix_base_data_path }}/heisenbridge" -matrix_heisenbridge_container_network: "" +matrix_bridge_heisenbridge_container_network: "" -matrix_heisenbridge_container_additional_networks: "{{ matrix_heisenbridge_container_additional_networks_auto + matrix_heisenbridge_container_additional_networks_custom }}" -matrix_heisenbridge_container_additional_networks_auto: [] -matrix_heisenbridge_container_additional_networks_custom: [] +matrix_bridge_heisenbridge_container_additional_networks: "{{ matrix_bridge_heisenbridge_container_additional_networks_auto + matrix_bridge_heisenbridge_container_additional_networks_custom }}" +matrix_bridge_heisenbridge_container_additional_networks_auto: [] +matrix_bridge_heisenbridge_container_additional_networks_custom: [] # Controls how long to wait for the container to stop gracefully before killing it. # We use a small value here, because this container does not seem to handle the SIGTERM signal. -matrix_heisenbridge_container_stop_grace_time_seconds: 1 +matrix_bridge_heisenbridge_container_stop_grace_time_seconds: 1 -# matrix_heisenbridge_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_heisenbridge_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_heisenbridge_container_labels_additional_labels`. -matrix_heisenbridge_container_labels_traefik_enabled: true -matrix_heisenbridge_container_labels_traefik_docker_network: "{{ matrix_heisenbridge_container_network }}" -matrix_heisenbridge_container_labels_traefik_hostname: "{{ matrix_heisenbridge_hostname }}" -matrix_heisenbridge_container_labels_traefik_path_prefix: "{{ matrix_heisenbridge_path_prefix }}" -matrix_heisenbridge_container_labels_traefik_entrypoints: web-secure -matrix_heisenbridge_container_labels_traefik_tls_certResolver: default # noqa var-naming +# To inject your own other container labels, see `matrix_bridge_heisenbridge_container_labels_additional_labels`. +matrix_bridge_heisenbridge_container_labels_traefik_enabled: true +matrix_bridge_heisenbridge_container_labels_traefik_docker_network: "{{ matrix_bridge_heisenbridge_container_network }}" +matrix_bridge_heisenbridge_container_labels_traefik_hostname: "{{ matrix_bridge_heisenbridge_hostname }}" +matrix_bridge_heisenbridge_container_labels_traefik_path_prefix: "{{ matrix_bridge_heisenbridge_path_prefix }}" +matrix_bridge_heisenbridge_container_labels_traefik_entrypoints: web-secure +matrix_bridge_heisenbridge_container_labels_traefik_tls_certResolver: default # noqa var-naming # Controls if the media router is enabled -matrix_heisenbridge_container_labels_traefik_media_enabled: true -matrix_heisenbridge_container_labels_traefik_media_hostname: "{{ matrix_heisenbridge_container_labels_traefik_hostname }}" +matrix_bridge_heisenbridge_container_labels_traefik_media_enabled: true +matrix_bridge_heisenbridge_container_labels_traefik_media_hostname: "{{ matrix_bridge_heisenbridge_container_labels_traefik_hostname }}" # The path prefix must either be `/` or not end with a slash (e.g. `/heisenbridge`). -matrix_heisenbridge_container_labels_traefik_media_path_prefix: "{{ '' if matrix_heisenbridge_container_labels_traefik_path_prefix == '/' else (matrix_heisenbridge_container_labels_traefik_path_prefix) }}/_heisenbridge/media" -matrix_heisenbridge_container_labels_traefik_media_rule: "Host(`{{ matrix_heisenbridge_container_labels_traefik_media_hostname }}`){% if matrix_heisenbridge_container_labels_traefik_media_path_prefix != '/' %} && PathPrefix(`{{ matrix_heisenbridge_container_labels_traefik_media_path_prefix }}`){% endif %}" -matrix_heisenbridge_container_labels_traefik_media_priority: 0 -matrix_heisenbridge_container_labels_traefik_media_entrypoints: "{{ matrix_heisenbridge_container_labels_traefik_entrypoints }}" -matrix_heisenbridge_container_labels_traefik_media_tls: "{{ matrix_heisenbridge_container_labels_traefik_media_entrypoints != 'web' }}" -matrix_heisenbridge_container_labels_traefik_media_tls_certResolver: "{{ matrix_heisenbridge_container_labels_traefik_tls_certResolver }}" # noqa var-naming - -# matrix_heisenbridge_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +matrix_bridge_heisenbridge_container_labels_traefik_media_path_prefix: "{{ '' if matrix_bridge_heisenbridge_container_labels_traefik_path_prefix == '/' else (matrix_bridge_heisenbridge_container_labels_traefik_path_prefix) }}/_heisenbridge/media" +matrix_bridge_heisenbridge_container_labels_traefik_media_rule: "Host(`{{ matrix_bridge_heisenbridge_container_labels_traefik_media_hostname }}`){% if matrix_bridge_heisenbridge_container_labels_traefik_media_path_prefix != '/' %} && PathPrefix(`{{ matrix_bridge_heisenbridge_container_labels_traefik_media_path_prefix }}`){% endif %}" +matrix_bridge_heisenbridge_container_labels_traefik_media_priority: 0 +matrix_bridge_heisenbridge_container_labels_traefik_media_entrypoints: "{{ matrix_bridge_heisenbridge_container_labels_traefik_entrypoints }}" +matrix_bridge_heisenbridge_container_labels_traefik_media_tls: "{{ matrix_bridge_heisenbridge_container_labels_traefik_media_entrypoints != 'web' }}" +matrix_bridge_heisenbridge_container_labels_traefik_media_tls_certResolver: "{{ matrix_bridge_heisenbridge_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_heisenbridge_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_heisenbridge_container_labels_additional_labels: | +# matrix_bridge_heisenbridge_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_heisenbridge_container_labels_additional_labels: '' +matrix_bridge_heisenbridge_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_heisenbridge_container_extra_arguments: [] +matrix_bridge_heisenbridge_container_extra_arguments: [] # List of systemd services that service depends on. -matrix_heisenbridge_systemd_required_services_list: "{{ matrix_heisenbridge_systemd_required_services_list_default + matrix_heisenbridge_systemd_required_services_list_auto + matrix_heisenbridge_systemd_required_services_list_custom }}" -matrix_heisenbridge_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_heisenbridge_systemd_required_services_list_auto: [] -matrix_heisenbridge_systemd_required_services_list_custom: [] +matrix_bridge_heisenbridge_systemd_required_services_list: "{{ matrix_bridge_heisenbridge_systemd_required_services_list_default + matrix_bridge_heisenbridge_systemd_required_services_list_auto + matrix_bridge_heisenbridge_systemd_required_services_list_custom }}" +matrix_bridge_heisenbridge_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_heisenbridge_systemd_required_services_list_auto: [] +matrix_bridge_heisenbridge_systemd_required_services_list_custom: [] # List of systemd services that service wants -matrix_heisenbridge_systemd_wanted_services_list: [] +matrix_bridge_heisenbridge_systemd_wanted_services_list: [] -matrix_heisenbridge_homeserver_url: "" +matrix_bridge_heisenbridge_homeserver_url: "" -matrix_heisenbridge_appservice_token: '' -matrix_heisenbridge_homeserver_token: '' +matrix_bridge_heisenbridge_appservice_token: '' +matrix_bridge_heisenbridge_homeserver_token: '' -matrix_heisenbridge_config_media_url: "{{ matrix_heisenbridge_scheme }}://{{ matrix_heisenbridge_hostname }}" -# This matches the hardcoded `DEFAULT_MEDIA_PATH` in Heisenbridge, but uses `matrix_heisenbridge_path_prefix` as the path prefix. +matrix_bridge_heisenbridge_config_media_url: "{{ matrix_bridge_heisenbridge_scheme }}://{{ matrix_bridge_heisenbridge_hostname }}" +# This matches the hardcoded `DEFAULT_MEDIA_PATH` in Heisenbridge, but uses `matrix_bridge_heisenbridge_path_prefix` as the path prefix. # See: https://github.com/hifi/heisenbridge/blob/7e18a5818f4a8c86cc62e474eee1631d16cb2602/heisenbridge/__main__.py#L66 -matrix_heisenbridge_config_media_path: "{{ matrix_heisenbridge_container_labels_traefik_media_path_prefix }}/{server}/{media_id}/{checksum}{filename}" -matrix_heisenbridge_config_media_key: "{{ matrix_heisenbridge_homeserver_token }}" -matrix_heisenbridge_config_displayname: "Heisenbridge" +matrix_bridge_heisenbridge_config_media_path: "{{ matrix_bridge_heisenbridge_container_labels_traefik_media_path_prefix }}/{server}/{media_id}/{checksum}{filename}" +matrix_bridge_heisenbridge_config_media_key: "{{ matrix_bridge_heisenbridge_homeserver_token }}" +matrix_bridge_heisenbridge_config_displayname: "Heisenbridge" -matrix_heisenbridge_registration_yaml_heisenbridge: - media_url: "{{ matrix_heisenbridge_config_media_url }}" - media_path: "{{ matrix_heisenbridge_config_media_path }}" - media_key: "{{ matrix_heisenbridge_config_media_key }}" - displayname: "{{ matrix_heisenbridge_config_displayname }}" +matrix_bridge_heisenbridge_registration_yaml_heisenbridge: + media_url: "{{ matrix_bridge_heisenbridge_config_media_url }}" + media_path: "{{ matrix_bridge_heisenbridge_config_media_path }}" + media_key: "{{ matrix_bridge_heisenbridge_config_media_key }}" + displayname: "{{ matrix_bridge_heisenbridge_config_displayname }}" # Default registration file consumed by both the homeserver and Heisenbridge. # Besides registration information, it contains configuration (see the Heisenbridge key). -matrix_heisenbridge_registration_yaml: +matrix_bridge_heisenbridge_registration_yaml: id: heisenbridge url: http://matrix-heisenbridge:9898 - as_token: "{{ matrix_heisenbridge_appservice_token }}" - hs_token: "{{ matrix_heisenbridge_homeserver_token }}" + as_token: "{{ matrix_bridge_heisenbridge_appservice_token }}" + hs_token: "{{ matrix_bridge_heisenbridge_homeserver_token }}" rate_limited: false sender_localpart: heisenbridge namespaces: @@ -120,11 +119,11 @@ matrix_heisenbridge_registration_yaml: exclusive: true aliases: [] rooms: [] - heisenbridge: "{{ matrix_heisenbridge_registration_yaml_heisenbridge }}" + heisenbridge: "{{ matrix_bridge_heisenbridge_registration_yaml_heisenbridge }}" -matrix_heisenbridge_registration: "{{ matrix_heisenbridge_registration_yaml | from_yaml }}" +matrix_bridge_heisenbridge_registration: "{{ matrix_bridge_heisenbridge_registration_yaml | from_yaml }}" -# matrix_heisenbridge_restart_necessary controls whether the service +# matrix_bridge_heisenbridge_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -132,4 +131,4 @@ matrix_heisenbridge_registration: "{{ matrix_heisenbridge_registration_yaml | fr # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_heisenbridge_restart_necessary: false +matrix_bridge_heisenbridge_restart_necessary: false diff --git a/roles/custom/matrix-bridge-heisenbridge/molecule/default/converge.yml b/roles/custom/matrix-bridge-heisenbridge/molecule/default/converge.yml new file mode 100644 index 000000000..989ed2bb6 --- /dev/null +++ b/roles/custom/matrix-bridge-heisenbridge/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for heisenbridge Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for heisenbridge Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure heisenbridge is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the heisenbridge systemd service is started + ansible.builtin.systemd_service: + name: matrix-heisenbridge.service + state: started diff --git a/roles/custom/matrix-bridge-heisenbridge/molecule/default/molecule.yml b/roles/custom/matrix-bridge-heisenbridge/molecule/default/molecule.yml new file mode 100644 index 000000000..cdf297b7d --- /dev/null +++ b/roles/custom/matrix-bridge-heisenbridge/molecule/default/molecule.yml @@ -0,0 +1,73 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: heisenbridge-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_heisenbridge_container_network: heisenbridge-molecule + + # The stub prepare.yml stands up. Not a real homeserver, and nothing is asserted + # about it. + matrix_bridge_heisenbridge_homeserver_url: http://matrix.molecule.local:8008 + + matrix_bridge_heisenbridge_appservice_token: molecule_as_token_4f2a91 + + # Heisenbridge refuses to start without an owner: the Matrix user allowed to + # administer the bridge. + matrix_bridge_heisenbridge_owner: "@molecule-admin:molecule.local" + + # Different from the role's defaults, so verify.yml can tell what the role rendered + # apart from what heisenbridge would have chosen. + matrix_bridge_heisenbridge_path_prefix: /molecule-heisenbridge + + # identd binds host port 113, which would collide with anything else on the machine. + matrix_bridge_heisenbridge_identd_enabled: false + + # Traefik is not deployed here, so the labels the role would render for it are + # switched off and their absence is asserted instead. + matrix_bridge_heisenbridge_container_labels_traefik_enabled: false + + # verify.yml runs as its own play, where role defaults are out of scope. Unlike the + # mautrix bridges, heisenbridge keeps everything directly under its base path. + matrix_bridge_heisenbridge_base_path: /matrix/heisenbridge + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-heisenbridge/molecule/default/prepare.yml b/roles/custom/matrix-bridge-heisenbridge/molecule/default/prepare.yml new file mode 100644 index 000000000..00a3f3f67 --- /dev/null +++ b/roles/custom/matrix-bridge-heisenbridge/molecule/default/prepare.yml @@ -0,0 +1,80 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare heisenbridge Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks set owner/group by name, which Ansible resolves through the + # passwd database, so they have to exist first. `matrix-base` creates them for real. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_heisenbridge_container_network }}" + register: heisenbridge_molecule_network + changed_when: heisenbridge_molecule_network.rc == 0 + failed_when: + - heisenbridge_molecule_network.rc != 0 + - "'already exists' not in heisenbridge_molecule_network.stderr" + + # The bridge contacts the homeserver as it starts. It is not being asked to bridge + # anything. See molecule-shared/homeserver-stub.py. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_heisenbridge_container_network }}" + molecule_shared_stub_server_name: molecule.local + molecule_shared_stub_user_id: "@heisenbridge:molecule.local" diff --git a/roles/custom/matrix-bridge-heisenbridge/molecule/default/requirements.yml b/roles/custom/matrix-bridge-heisenbridge/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-heisenbridge/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-heisenbridge/molecule/default/verify.yml b/roles/custom/matrix-bridge-heisenbridge/molecule/default/verify.yml new file mode 100644 index 000000000..692d61e01 --- /dev/null +++ b/roles/custom/matrix-bridge-heisenbridge/molecule/default/verify.yml @@ -0,0 +1,126 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves heisenbridge starts, reads the registration the role rendered, and is the version +# the role pins. It does NOT connect to IRC. See docs/molecule-testing.md. +- name: Verify heisenbridge + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + + tasks: + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: heisenbridge_role_defaults + + - name: Wait for the heisenbridge service to become active + ansible.builtin.systemd_service: + name: matrix-heisenbridge.service + register: heisenbridge_service + until: heisenbridge_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # `Restart=always` means a bridge crash-looping on unreadable config still reports + # `active`, so the restart counter is checked too. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - heisenbridge_service.status.ActiveState == 'active' + - heisenbridge_service.status.NRestarts is defined + - heisenbridge_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-heisenbridge.service is + {{ heisenbridge_service.status.ActiveState | default('unknown') }} + after {{ heisenbridge_service.status.NRestarts | default('?') }} + automatic restart(s) + success_msg: "matrix-heisenbridge.service is active and has not restarted" + + # Heisenbridge keeps everything directly under its base path, unlike the mautrix bridges. + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_heisenbridge_base_path }}/registration.yaml" + register: heisenbridge_registration_file + + # Token and URL both differ from anything heisenbridge would pick on its own, so their + # presence means the role rendered this file rather than the bridge generating one. + - name: Assert the registration carries the scenario's token and namespace + ansible.builtin.assert: + that: + - matrix_bridge_heisenbridge_appservice_token in heisenbridge_registration_rendered + - "'heisenbridge' in heisenbridge_registration_rendered" + fail_msg: "The appservice registration does not carry the scenario's token" + success_msg: "The appservice registration carries the scenario's token" + vars: + heisenbridge_registration_rendered: "{{ heisenbridge_registration_file.content | b64decode }}" + + # The role passes the owner on the command line rather than through a config file, + # so the unit is where it can be checked. + - name: Read the systemd unit the role rendered + ansible.builtin.slurp: + src: /etc/systemd/system/matrix-heisenbridge.service + register: heisenbridge_unit_file + + - name: Assert the unit carries the owner and homeserver URL the scenario set + ansible.builtin.assert: + that: + - matrix_bridge_heisenbridge_owner in heisenbridge_unit_rendered + - matrix_bridge_heisenbridge_homeserver_url in heisenbridge_unit_rendered + fail_msg: "The unit does not carry the scenario's owner and homeserver URL" + success_msg: "The unit carries the scenario's owner and homeserver URL" + vars: + heisenbridge_unit_rendered: "{{ heisenbridge_unit_file.content | b64decode }}" + + # identd binds host port 113 when enabled. Asserting its absence keeps the default from + # silently becoming "on". + - name: Assert identd is not published while it is disabled + ansible.builtin.assert: + that: + - "'-p 113:' not in (heisenbridge_unit_file.content | b64decode)" + fail_msg: >- + The unit publishes identd on port 113 even though + matrix_bridge_heisenbridge_identd_enabled is false + success_msg: "identd is not published while it is disabled" + + - name: Read the image of the running container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-heisenbridge + - --format + - "{{ '{{' }} .Config.Image {{ '}}' }}" + register: heisenbridge_image + changed_when: false + + - name: Assert the running container is the version defaults/main.yml pins + ansible.builtin.assert: + that: + - heisenbridge_role_defaults.matrix_bridge_heisenbridge_version | string in heisenbridge_image.stdout + fail_msg: >- + The running container is {{ heisenbridge_image.stdout }}, which does not + carry the pinned version + {{ heisenbridge_role_defaults.matrix_bridge_heisenbridge_version }} + success_msg: "The running container is the version defaults/main.yml pins" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_heisenbridge_base_path }}/labels" + register: heisenbridge_labels + + - name: Assert no Traefik labels are emitted while Traefik support is disabled + ansible.builtin.assert: + that: + - "'traefik.' not in (heisenbridge_labels.content | b64decode)" + fail_msg: >- + Traefik labels were emitted even though + matrix_bridge_heisenbridge_container_labels_traefik_enabled is false + success_msg: "No Traefik labels are emitted while Traefik support is disabled" diff --git a/roles/custom/matrix-bridge-heisenbridge/tasks/main.yml b/roles/custom/matrix-bridge-heisenbridge/tasks/main.yml index 7de077071..1d9ee6500 100644 --- a/roles/custom/matrix-bridge-heisenbridge/tasks/main.yml +++ b/roles/custom/matrix-bridge-heisenbridge/tasks/main.yml @@ -12,15 +12,15 @@ - install-all - install-heisenbridge block: - - when: matrix_heisenbridge_enabled | bool + - when: matrix_bridge_heisenbridge_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_heisenbridge_enabled | bool + - when: matrix_bridge_heisenbridge_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-heisenbridge block: - - when: not matrix_heisenbridge_enabled | bool + - when: not matrix_bridge_heisenbridge_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-heisenbridge/tasks/setup_install.yml b/roles/custom/matrix-bridge-heisenbridge/tasks/setup_install.yml index ec8ef82d1..da44002e7 100644 --- a/roles/custom/matrix-bridge-heisenbridge/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-heisenbridge/tasks/setup_install.yml @@ -11,15 +11,13 @@ --- - name: Ensure Heisenbridge image is pulled - community.docker.docker_image: - name: "{{ matrix_heisenbridge_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_heisenbridge_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_heisenbridge_container_image_force_pull }}" - register: matrix_heisenbridge_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_heisenbridge_container_image }}" + pull: always + register: matrix_bridge_heisenbridge_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_heisenbridge_container_image_pull_result is not failed + until: matrix_bridge_heisenbridge_container_image_pull_result is not failed - name: Ensure Heisenbridge paths exist ansible.builtin.file: @@ -29,32 +27,33 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - "{{ matrix_heisenbridge_base_path }}" + - "{{ matrix_bridge_heisenbridge_base_path }}" - name: Ensure Heisenbridge registration.yaml installed if provided ansible.builtin.copy: - content: "{{ matrix_heisenbridge_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_heisenbridge_base_path }}/registration.yaml" + content: "{{ matrix_bridge_heisenbridge_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_heisenbridge_base_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_heisenbridge_registration_result + register: matrix_bridge_heisenbridge_registration_result - name: Ensure Heisenbridge support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_heisenbridge_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_heisenbridge_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_heisenbridge_support_files_result + register: matrix_bridge_heisenbridge_support_files_result - name: Ensure Heisenbridge container network is created + when: matrix_bridge_heisenbridge_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_heisenbridge_container_network }}" + name: "{{ matrix_bridge_heisenbridge_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -63,14 +62,14 @@ src: "{{ role_path }}/templates/systemd/matrix-heisenbridge.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-heisenbridge.service" mode: '0644' - register: matrix_heisenbridge_systemd_service_result + register: matrix_bridge_heisenbridge_systemd_service_result - name: Determine whether matrix-heisenbridge needs a restart ansible.builtin.set_fact: - matrix_heisenbridge_restart_necessary: >- + matrix_bridge_heisenbridge_restart_necessary: >- {{ - matrix_heisenbridge_registration_result.changed | default(false) - or matrix_heisenbridge_support_files_result.changed | default(false) - or matrix_heisenbridge_systemd_service_result.changed | default(false) - or matrix_heisenbridge_container_image_pull_result.changed | default(false) + matrix_bridge_heisenbridge_registration_result.changed | default(false) + or matrix_bridge_heisenbridge_support_files_result.changed | default(false) + or matrix_bridge_heisenbridge_systemd_service_result.changed | default(false) + or matrix_bridge_heisenbridge_container_image_pull_result.changed | default(false) }} diff --git a/roles/custom/matrix-bridge-heisenbridge/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-heisenbridge/tasks/setup_uninstall.yml index ba42105de..ae4025153 100644 --- a/roles/custom/matrix-bridge-heisenbridge/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-heisenbridge/tasks/setup_uninstall.yml @@ -10,9 +10,9 @@ - name: Check existence of matrix-heisenbridge service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-heisenbridge.service" - register: matrix_heisenbridge_service_stat + register: matrix_bridge_heisenbridge_service_stat -- when: matrix_heisenbridge_service_stat.stat.exists | bool +- when: matrix_bridge_heisenbridge_service_stat.stat.exists | bool block: - name: Ensure matrix-heisenbridge is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-heisenbridge/tasks/validate_config.yml b/roles/custom/matrix-bridge-heisenbridge/tasks/validate_config.yml index 515094b85..b39ec8486 100644 --- a/roles/custom/matrix-bridge-heisenbridge/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-heisenbridge/tasks/validate_config.yml @@ -12,11 +12,12 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_heisenbridge_docker_image', 'new': 'matrix_heisenbridge_container_image'} - - {'old': 'matrix_heisenbridge_docker_image_force_pull', 'new': 'matrix_heisenbridge_container_image_force_pull'} - - {'old': 'matrix_heisenbridge_docker_image_registry_prefix', 'new': 'matrix_heisenbridge_container_image_registry_prefix'} - - {'old': 'matrix_heisenbridge_docker_image_registry_prefix_upstream', 'new': 'matrix_heisenbridge_container_image_registry_prefix_upstream'} - - {'old': 'matrix_heisenbridge_docker_image_registry_prefix_upstream_default', 'new': 'matrix_heisenbridge_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_heisenbridge_docker_image', 'new': 'matrix_bridge_heisenbridge_container_image'} + - {'old': 'matrix_bridge_heisenbridge_docker_image_force_pull', 'new': 'matrix_bridge_heisenbridge_container_image_force_pull'} + - {'old': 'matrix_bridge_heisenbridge_docker_image_registry_prefix', 'new': 'matrix_bridge_heisenbridge_container_image_registry_prefix'} + - {'old': 'matrix_bridge_heisenbridge_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_heisenbridge_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_heisenbridge_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_heisenbridge_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_heisenbridge_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required Heisenbridge settings not defined @@ -25,5 +26,5 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_heisenbridge_container_network', when: true} - - {'name': 'matrix_heisenbridge_homeserver_url', when: true} + - {'name': 'matrix_bridge_heisenbridge_container_network', when: true} + - {'name': 'matrix_bridge_heisenbridge_homeserver_url', when: true} diff --git a/roles/custom/matrix-bridge-heisenbridge/templates/labels.j2 b/roles/custom/matrix-bridge-heisenbridge/templates/labels.j2 index fa2cb1ee1..bf435a907 100644 --- a/roles/custom/matrix-bridge-heisenbridge/templates/labels.j2 +++ b/roles/custom/matrix-bridge-heisenbridge/templates/labels.j2 @@ -4,33 +4,33 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_heisenbridge_container_labels_traefik_enabled %} +{% if matrix_bridge_heisenbridge_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_heisenbridge_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_heisenbridge_container_labels_traefik_docker_network }} +{% if matrix_bridge_heisenbridge_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_heisenbridge_container_labels_traefik_docker_network }} {% endif %} traefik.http.services.matrix-heisenbridge.loadbalancer.server.port=9898 {% set middlewares = [] %} -{% if matrix_heisenbridge_container_labels_traefik_path_prefix != '/' %} -traefik.http.middlewares.matrix-heisenbridge-strip-prefix.stripprefix.prefixes={{ matrix_heisenbridge_container_labels_traefik_path_prefix }} +{% if matrix_bridge_heisenbridge_container_labels_traefik_path_prefix != '/' %} +traefik.http.middlewares.matrix-heisenbridge-strip-prefix.stripprefix.prefixes={{ matrix_bridge_heisenbridge_container_labels_traefik_path_prefix }} {% set middlewares = middlewares + ['matrix-heisenbridge-strip-prefix'] %} {% endif %} -{% if matrix_heisenbridge_container_labels_traefik_media_enabled %} +{% if matrix_bridge_heisenbridge_container_labels_traefik_media_enabled %} ########################################################################## # # # Media # # # ########################################################################## -traefik.http.routers.matrix-heisenbridge-media.rule={{ matrix_heisenbridge_container_labels_traefik_media_rule }} +traefik.http.routers.matrix-heisenbridge-media.rule={{ matrix_bridge_heisenbridge_container_labels_traefik_media_rule }} -{% if matrix_heisenbridge_container_labels_traefik_media_priority | int > 0 %} -traefik.http.routers.matrix-heisenbridge-media.priority={{ matrix_heisenbridge_container_labels_traefik_media_priority }} +{% if matrix_bridge_heisenbridge_container_labels_traefik_media_priority | int > 0 %} +traefik.http.routers.matrix-heisenbridge-media.priority={{ matrix_bridge_heisenbridge_container_labels_traefik_media_priority }} {% endif %} {% if middlewares | length > 0 %} @@ -38,11 +38,11 @@ traefik.http.routers.matrix-heisenbridge-media.middlewares={{ middlewares | join {% endif %} traefik.http.routers.matrix-heisenbridge-media.service=matrix-heisenbridge -traefik.http.routers.matrix-heisenbridge-media.entrypoints={{ matrix_heisenbridge_container_labels_traefik_entrypoints }} +traefik.http.routers.matrix-heisenbridge-media.entrypoints={{ matrix_bridge_heisenbridge_container_labels_traefik_entrypoints }} -traefik.http.routers.matrix-heisenbridge-media.tls={{ matrix_heisenbridge_container_labels_traefik_media_tls | to_json }} -{% if matrix_heisenbridge_container_labels_traefik_media_entrypoints %} -traefik.http.routers.matrix-heisenbridge-media.tls.certResolver={{ matrix_heisenbridge_container_labels_traefik_media_tls_certResolver }} +traefik.http.routers.matrix-heisenbridge-media.tls={{ matrix_bridge_heisenbridge_container_labels_traefik_media_tls | to_json }} +{% if matrix_bridge_heisenbridge_container_labels_traefik_media_entrypoints %} +traefik.http.routers.matrix-heisenbridge-media.tls.certResolver={{ matrix_bridge_heisenbridge_container_labels_traefik_media_tls_certResolver }} {% endif %} ########################################################################## @@ -55,4 +55,4 @@ traefik.http.routers.matrix-heisenbridge-media.tls.certResolver={{ matrix_heisen {% endif %} -{{ matrix_heisenbridge_container_labels_additional_labels }} +{{ matrix_bridge_heisenbridge_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-heisenbridge/templates/systemd/matrix-heisenbridge.service.j2 b/roles/custom/matrix-bridge-heisenbridge/templates/systemd/matrix-heisenbridge.service.j2 index e653ad2e8..e164cc6b9 100644 --- a/roles/custom/matrix-bridge-heisenbridge/templates/systemd/matrix-heisenbridge.service.j2 +++ b/roles/custom/matrix-bridge-heisenbridge/templates/systemd/matrix-heisenbridge.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=a bouncer-style Matrix IRC bridge -{% for service in matrix_heisenbridge_systemd_required_services_list %} +{% for service in matrix_bridge_heisenbridge_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_heisenbridge_systemd_wanted_services_list %} +{% for service in matrix_bridge_heisenbridge_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -13,7 +13,7 @@ DefaultDependencies=no [Service] Type=simple Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ matrix_heisenbridge_container_stop_grace_time_seconds }} matrix-heisenbridge +ExecStartPre=-{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ matrix_bridge_heisenbridge_container_stop_grace_time_seconds }} matrix-heisenbridge ExecStartPre=-{{ devture_systemd_docker_base_host_command_docker }} rm matrix-heisenbridge ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ @@ -22,35 +22,37 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_heisenbridge_container_network }} \ - {% if matrix_heisenbridge_identd_enabled %} + --network={{ matrix_bridge_heisenbridge_container_network }} \ + {% if matrix_bridge_heisenbridge_identd_enabled %} -p 113:13113 \ {% endif %} - --mount type=bind,src={{ matrix_heisenbridge_base_path }},dst=/config \ - --label-file={{ matrix_heisenbridge_base_path }}/labels \ - {% for arg in matrix_heisenbridge_container_extra_arguments %} + --mount type=bind,src={{ matrix_bridge_heisenbridge_base_path }},dst=/config \ + --label-file={{ matrix_bridge_heisenbridge_base_path }}/labels \ + {% for arg in matrix_bridge_heisenbridge_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_heisenbridge_container_image }} \ - {% if matrix_heisenbridge_identd_enabled %} + {{ matrix_bridge_heisenbridge_container_image }} \ + {% if matrix_bridge_heisenbridge_identd_enabled %} --identd \ --identd-port 13113 \ {% endif %} - {% if matrix_heisenbridge_owner %} - -o {{ matrix_heisenbridge_owner }} \ + {% if matrix_bridge_heisenbridge_owner %} + -o {{ matrix_bridge_heisenbridge_owner }} \ {% endif %} --config /config/registration.yaml \ --listen-address 0.0.0.0 \ --listen-port 9898 \ - {{ matrix_heisenbridge_homeserver_url }} + {{ matrix_bridge_heisenbridge_homeserver_url }} -{% for network in matrix_heisenbridge_container_additional_networks %} +{% if matrix_bridge_heisenbridge_container_network != 'host' %} +{% for network in matrix_bridge_heisenbridge_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-heisenbridge {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-heisenbridge -ExecStop=-{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ matrix_heisenbridge_container_stop_grace_time_seconds }} matrix-heisenbridge +ExecStop=-{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ matrix_bridge_heisenbridge_container_stop_grace_time_seconds }} matrix-heisenbridge ExecStop=-{{ devture_systemd_docker_base_host_command_docker }} rm matrix-heisenbridge Restart=always RestartSec=30 diff --git a/roles/custom/matrix-bridge-hookshot/defaults/main.yml b/roles/custom/matrix-bridge-hookshot/defaults/main.yml index 6c3922313..d5026ec25 100644 --- a/roles/custom/matrix-bridge-hookshot/defaults/main.yml +++ b/roles/custom/matrix-bridge-hookshot/defaults/main.yml @@ -15,192 +15,192 @@ # A bridge between Matrix and multiple project management services, such as GitHub, GitLab and JIRA. # Project source code URL: https://github.com/matrix-org/matrix-hookshot -matrix_hookshot_enabled: true +matrix_bridge_hookshot_enabled: true -matrix_hookshot_identifier: matrix-hookshot +matrix_bridge_hookshot_identifier: matrix-hookshot -matrix_hookshot_container_image_self_build: false -matrix_hookshot_container_image_self_build_repo: "https://github.com/matrix-org/matrix-hookshot.git" -matrix_hookshot_container_image_self_build_branch: "{{ 'main' if matrix_hookshot_version == 'latest' else matrix_hookshot_version }}" +matrix_bridge_hookshot_container_image_self_build: false +matrix_bridge_hookshot_container_image_self_build_repo: "https://github.com/matrix-org/matrix-hookshot.git" +matrix_bridge_hookshot_container_image_self_build_branch: "{{ 'main' if matrix_bridge_hookshot_version == 'latest' else matrix_bridge_hookshot_version }}" # Specifies additional networks for the Hookshot container to connect with -matrix_hookshot_container_additional_networks: "{{ matrix_hookshot_container_additional_networks_auto + matrix_hookshot_container_additional_networks_custom }}" -matrix_hookshot_container_additional_networks_auto: [] -matrix_hookshot_container_additional_networks_custom: [] +matrix_bridge_hookshot_container_additional_networks: "{{ matrix_bridge_hookshot_container_additional_networks_auto + matrix_bridge_hookshot_container_additional_networks_custom }}" +matrix_bridge_hookshot_container_additional_networks_auto: [] +matrix_bridge_hookshot_container_additional_networks_custom: [] # renovate: datasource=docker depName=halfshot/matrix-hookshot -matrix_hookshot_version: 7.3.2 +matrix_bridge_hookshot_version: 7.3.2 -matrix_hookshot_container_image: "{{ matrix_hookshot_container_image_registry_prefix }}matrix-org/matrix-hookshot:{{ matrix_hookshot_version }}" -matrix_hookshot_container_image_registry_prefix: "{{ 'localhost/' if matrix_hookshot_container_image_self_build else matrix_hookshot_container_image_registry_prefix_upstream }}" -matrix_hookshot_container_image_registry_prefix_upstream: "{{ matrix_hookshot_container_image_registry_prefix_upstream_default }}" -matrix_hookshot_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_hookshot_container_image_force_pull: "{{ matrix_hookshot_container_image.endswith(':latest') }}" +matrix_bridge_hookshot_container_image: "{{ matrix_bridge_hookshot_container_image_registry_prefix }}matrix-org/matrix-hookshot:{{ matrix_bridge_hookshot_version }}" +matrix_bridge_hookshot_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_hookshot_container_image_self_build else matrix_bridge_hookshot_container_image_registry_prefix_upstream }}" +matrix_bridge_hookshot_container_image_registry_prefix_upstream: "{{ matrix_bridge_hookshot_container_image_registry_prefix_upstream_default }}" +matrix_bridge_hookshot_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_hookshot_base_path: "{{ matrix_base_data_path }}/hookshot" +matrix_bridge_hookshot_base_path: "{{ matrix_base_data_path }}/hookshot" -matrix_hookshot_container_src_files_path: "{{ matrix_hookshot_base_path }}/docker-src" +matrix_bridge_hookshot_container_src_files_path: "{{ matrix_bridge_hookshot_base_path }}/docker-src" -matrix_hookshot_homeserver_address: "" -matrix_hookshot_container_url: 'matrix-hookshot' +matrix_bridge_hookshot_homeserver_address: "" +matrix_bridge_hookshot_container_url: 'matrix-hookshot' # Sets the localpart of the Matrix ID for the hookshot bot -matrix_hookshot_bot_localpart: "hookshot" +matrix_bridge_hookshot_bot_localpart: "hookshot" -matrix_hookshot_public_scheme: https -matrix_hookshot_public_hostname: "{{ matrix_server_fqn_matrix }}" -matrix_hookshot_public_endpoint: /hookshot +matrix_bridge_hookshot_public_scheme: https +matrix_bridge_hookshot_public_hostname: "{{ matrix_server_fqn_matrix }}" +matrix_bridge_hookshot_public_endpoint: /hookshot # This is the base URL prefix shared among all endpoints. # -# It intentionally does not include the path prefix (`matrix_hookshot_public_endpoint`), -# because of how it's used - it's concatenated with paths that already use matrix_hookshot_public_endpoint` within them. -matrix_hookshot_urlprefix: "{{ matrix_hookshot_public_scheme }}://{{ matrix_hookshot_public_hostname }}" +# It intentionally does not include the path prefix (`matrix_bridge_hookshot_public_endpoint`), +# because of how it's used - it's concatenated with paths that already use matrix_bridge_hookshot_public_endpoint` within them. +matrix_bridge_hookshot_urlprefix: "{{ matrix_bridge_hookshot_public_scheme }}://{{ matrix_bridge_hookshot_public_hostname }}" -# There is no need to edit ports. use matrix_hookshot_container_http_host_bind_ports below to expose ports instead. -matrix_hookshot_appservice_port: 9993 -matrix_hookshot_appservice_hostname: "{{ matrix_hookshot_public_hostname }}" -matrix_hookshot_appservice_endpoint: "{{ matrix_hookshot_public_endpoint }}/_matrix/app" +# There is no need to edit ports. use matrix_bridge_hookshot_container_http_host_bind_ports below to expose ports instead. +matrix_bridge_hookshot_appservice_port: 9993 +matrix_bridge_hookshot_appservice_hostname: "{{ matrix_bridge_hookshot_public_hostname }}" +matrix_bridge_hookshot_appservice_endpoint: "{{ matrix_bridge_hookshot_public_endpoint }}/_matrix/app" # The variables below control the Redis cache parameters. -# Using caching is required when encryption is enabled (`matrix_hookshot_encryption_enabled`) +# Using caching is required when encryption is enabled (`matrix_bridge_hookshot_encryption_enabled`) # but may also speed up Hookshot startup, etc. -matrix_hookshot_cache_redis_host: '' -matrix_hookshot_cache_redis_port: "6379" -matrix_hookshot_cache_redisUri: "{{ ('redis://' + matrix_hookshot_cache_redis_host + ':' + matrix_hookshot_cache_redis_port) if matrix_hookshot_cache_redis_host else '' }}" # noqa var-naming +matrix_bridge_hookshot_cache_redis_host: '' +matrix_bridge_hookshot_cache_redis_port: "6379" +matrix_bridge_hookshot_cache_redisUri: "{{ ('redis://' + matrix_bridge_hookshot_cache_redis_host + ':' + matrix_bridge_hookshot_cache_redis_port) if matrix_bridge_hookshot_cache_redis_host else '' }}" # noqa var-naming # Controls whether the end-to-bridge encryption support is enabled. # This requires that: -# - support to also be enabled in the homeserver, see the documentation of Hookshot. -# - Hookshot to be pointed at a Redis instance via the `matrix_hookshot_cache_redis*` variables. Note that this is configured automatically by the playbook when encryption is enabled. +# - the homeserver to support MSC2409 (to-device messages for appservices) and MSC3202 (encryption-related appservice transaction extensions), and to have them enabled. +# These are typically experimental homeserver features which are disabled by default. Note that this is configured automatically by the playbook when encryption is enabled and the homeserver is Synapse. +# - Hookshot to be pointed at a Redis instance via the `matrix_bridge_hookshot_cache_redis*` variables. Note that this is configured automatically by the playbook when encryption is enabled. # See: https://matrix-org.github.io/matrix-hookshot/latest/advanced/encryption.html # NOTE: Encryption is not currently (2025-12-30) supported when using MAS (https://github.com/matrix-org/matrix-hookshot/issues/1084) -matrix_hookshot_encryption_enabled: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_hookshot_encryption_enabled: "{{ matrix_bridges_encryption_enabled }}" # Controls whether metrics are enabled in the bridge configuration. # Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_hookshot_metrics_proxying_enabled`. -matrix_hookshot_metrics_enabled: false +# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_bridge_hookshot_metrics_proxying_enabled`. +matrix_bridge_hookshot_metrics_enabled: false # Controls whether Hookshot metrics should be proxied (exposed) on a public URL. -matrix_hookshot_metrics_proxying_enabled: false -matrix_hookshot_metrics_proxying_hostname: '' -matrix_hookshot_metrics_proxying_path_prefix: '' +matrix_bridge_hookshot_metrics_proxying_enabled: false +matrix_bridge_hookshot_metrics_proxying_hostname: '' +matrix_bridge_hookshot_metrics_proxying_path_prefix: '' # There is no need to edit ports. # Read the documentation to learn about using Hookshot metrics with external Prometheus -# If you still want something different, use matrix_hookshot_container_http_host_bind_ports below to expose ports instead. -matrix_hookshot_metrics_port: 9001 +# If you still want something different, use matrix_bridge_hookshot_container_http_host_bind_ports below to expose ports instead. +matrix_bridge_hookshot_metrics_port: 9001 -# There is no need to edit ports. use matrix_hookshot_container_http_host_bind_ports below to expose ports instead. -matrix_hookshot_webhook_port: 9000 -matrix_hookshot_webhook_hostname: "{{ matrix_hookshot_public_hostname }}" -matrix_hookshot_webhook_endpoint: "{{ matrix_hookshot_public_endpoint }}/webhooks" +# There is no need to edit ports. use matrix_bridge_hookshot_container_http_host_bind_ports below to expose ports instead. +matrix_bridge_hookshot_webhook_port: 9000 +matrix_bridge_hookshot_webhook_hostname: "{{ matrix_bridge_hookshot_public_hostname }}" +matrix_bridge_hookshot_webhook_endpoint: "{{ matrix_bridge_hookshot_public_endpoint }}/webhooks" # You need to create a GitHub app to enable this and fill in the empty variables below # https://matrix-org.github.io/matrix-hookshot/setup/github.html -matrix_hookshot_github_enabled: false -matrix_hookshot_github_auth_id: '' +matrix_bridge_hookshot_github_enabled: false +matrix_bridge_hookshot_github_auth_id: '' # Set this variable to the contents of the generated and downloaded GitHub private key: -# matrix_hookshot_github_private_key: | +# matrix_bridge_hookshot_github_private_key: | # -----BEGIN RSA PRIVATE KEY----- # 0123456789ABCDEF… # -----END RSA PRIVATE KEY----- # Alternatively, leave it empty and do it manually or use matrix-aux instead, see docs/matrix-bridge-hookshot.md for info. -matrix_hookshot_github_private_key: '' -matrix_hookshot_github_private_key_file: 'private-key.pem' -matrix_hookshot_github_webhook_secret: '' # "Webhook secret" on the GitHub App page -matrix_hookshot_github_oauth_enabled: false +matrix_bridge_hookshot_github_private_key: '' +matrix_bridge_hookshot_github_private_key_file: 'private-key.pem' +matrix_bridge_hookshot_github_webhook_secret: '' # "Webhook secret" on the GitHub App page +matrix_bridge_hookshot_github_oauth_enabled: false # You need to configure oauth settings only when you have enabled oauth (optional) -matrix_hookshot_github_oauth_client_id: '' # "Client ID" on the GitHub App page -matrix_hookshot_github_oauth_client_secret: '' # "Client Secret" on the GitHub App page -# Default value of matrix_hookshot_github_oauth_endpoint: "/hookshot/webhooks/oauth" -matrix_hookshot_github_oauth_endpoint: "{{ matrix_hookshot_webhook_endpoint }}/oauth" -matrix_hookshot_github_oauth_redirect_uri: "{{ matrix_hookshot_urlprefix }}{{ matrix_hookshot_github_oauth_endpoint }}" +matrix_bridge_hookshot_github_oauth_client_id: '' # "Client ID" on the GitHub App page +matrix_bridge_hookshot_github_oauth_client_secret: '' # "Client Secret" on the GitHub App page +# Default value of matrix_bridge_hookshot_github_oauth_endpoint: "/hookshot/webhooks/oauth" +matrix_bridge_hookshot_github_oauth_endpoint: "{{ matrix_bridge_hookshot_webhook_endpoint }}/oauth" +matrix_bridge_hookshot_github_oauth_redirect_uri: "{{ matrix_bridge_hookshot_urlprefix }}{{ matrix_bridge_hookshot_github_oauth_endpoint }}" # These are the default settings mentioned here and don't need to be modified: https://matrix-org.github.io/matrix-hookshot/usage/room_configuration/github_repo.html#configuration -matrix_hookshot_github_defaultOptions_ignoreHooks: {} # noqa var-naming -matrix_hookshot_github_defaultOptions_commandPrefix: '!gh' # noqa var-naming -matrix_hookshot_github_defaultOptions_showIssueRoomLink: false # noqa var-naming -matrix_hookshot_github_defaultOptions_prDiff: # noqa var-naming +matrix_bridge_hookshot_github_defaultOptions_ignoreHooks: {} # noqa var-naming +matrix_bridge_hookshot_github_defaultOptions_commandPrefix: '!gh' # noqa var-naming +matrix_bridge_hookshot_github_defaultOptions_showIssueRoomLink: false # noqa var-naming +matrix_bridge_hookshot_github_defaultOptions_prDiff: # noqa var-naming enabled: false maxLines: 5 -matrix_hookshot_github_defaultOptions_includingLabels: '' # noqa var-naming -matrix_hookshot_github_defaultOptions_excludingLabels: '' # noqa var-naming -matrix_hookshot_github_defaultOptions_hotlinkIssues_prefix: "#" # noqa var-naming +matrix_bridge_hookshot_github_defaultOptions_includingLabels: '' # noqa var-naming +matrix_bridge_hookshot_github_defaultOptions_excludingLabels: '' # noqa var-naming +matrix_bridge_hookshot_github_defaultOptions_hotlinkIssues_prefix: "#" # noqa var-naming -matrix_hookshot_gitlab_enabled: true +matrix_bridge_hookshot_gitlab_enabled: true # Optionally add your instances, e.g. -# matrix_hookshot_gitlab_instances: +# matrix_bridge_hookshot_gitlab_instances: # gitlab.com: # url: https://gitlab.com # mygitlab: # url: https://gitlab.example.org -matrix_hookshot_gitlab_instances: +matrix_bridge_hookshot_gitlab_instances: gitlab.com: url: https://gitlab.com # This will be the "Secret token" you have to enter into all GitLab instances for authentication -matrix_hookshot_gitlab_webhook_secret: '' -matrix_hookshot_gitlab_webhook_publicUrl: "{{ matrix_hookshot_urlprefix }}{{ matrix_hookshot_webhook_endpoint }}" # noqa var-naming +matrix_bridge_hookshot_gitlab_webhook_secret: '' +matrix_bridge_hookshot_gitlab_webhook_publicUrl: "{{ matrix_bridge_hookshot_urlprefix }}{{ matrix_bridge_hookshot_webhook_endpoint }}" # noqa var-naming -matrix_hookshot_figma_enabled: false -# Default value of matrix_hookshot_figma_endpoint: "/hookshot/webhooks/figma/webhook" -matrix_hookshot_figma_endpoint: "{{ matrix_hookshot_webhook_endpoint }}/figma/webhook" -matrix_hookshot_figma_publicUrl: "{{ matrix_hookshot_urlprefix }}{{ matrix_hookshot_figma_endpoint }}" # noqa var-naming +matrix_bridge_hookshot_figma_enabled: false +# Default value of matrix_bridge_hookshot_figma_endpoint: "/hookshot/webhooks/figma/webhook" +matrix_bridge_hookshot_figma_endpoint: "{{ matrix_bridge_hookshot_webhook_endpoint }}/figma/webhook" +matrix_bridge_hookshot_figma_publicUrl: "{{ matrix_bridge_hookshot_urlprefix }}{{ matrix_bridge_hookshot_figma_endpoint }}" # noqa var-naming # To bridge figma webhooks, you need to configure one of multiple instances like this: -# matrix_hookshot_figma_instances: +# matrix_bridge_hookshot_figma_instances: # your-instance: # teamId: your-team-id # accessToken: your-personal-access-token # passcode: your-webhook-passcode -matrix_hookshot_figma_instances: {} +matrix_bridge_hookshot_figma_instances: {} -matrix_hookshot_jira_enabled: false +matrix_bridge_hookshot_jira_enabled: false # Get the these values from https://matrix-org.github.io/matrix-hookshot/setup/jira.html#jira-oauth -matrix_hookshot_jira_webhook_secret: '' -matrix_hookshot_jira_oauth_enabled: false -matrix_hookshot_jira_oauth_client_id: '' -matrix_hookshot_jira_oauth_client_secret: '' -# Default value of matrix_hookshot_jira_oauth_endpoint: "/hookshot/webhooks/jira/oauth" -matrix_hookshot_jira_oauth_endpoint: "{{ matrix_hookshot_webhook_endpoint }}/jira/oauth" -matrix_hookshot_jira_oauth_redirect_uri: "{{ matrix_hookshot_urlprefix }}{{ matrix_hookshot_jira_oauth_endpoint }}" +matrix_bridge_hookshot_jira_webhook_secret: '' +matrix_bridge_hookshot_jira_oauth_enabled: false +matrix_bridge_hookshot_jira_oauth_client_id: '' +matrix_bridge_hookshot_jira_oauth_client_secret: '' +# Default value of matrix_bridge_hookshot_jira_oauth_endpoint: "/hookshot/webhooks/jira/oauth" +matrix_bridge_hookshot_jira_oauth_endpoint: "{{ matrix_bridge_hookshot_webhook_endpoint }}/jira/oauth" +matrix_bridge_hookshot_jira_oauth_redirect_uri: "{{ matrix_bridge_hookshot_urlprefix }}{{ matrix_bridge_hookshot_jira_oauth_endpoint }}" # No need to change these -matrix_hookshot_generic_enabled: true -matrix_hookshot_generic_outbound: true -matrix_hookshot_generic_enableHttpGet: false # noqa var-naming -# Default value of matrix_hookshot_generic_endpoint: "/hookshot/webhooks" -matrix_hookshot_generic_endpoint: "{{ matrix_hookshot_webhook_endpoint }}/webhook" +matrix_bridge_hookshot_generic_enabled: true +matrix_bridge_hookshot_generic_outbound: true +matrix_bridge_hookshot_generic_enableHttpGet: false # noqa var-naming +# Default value of matrix_bridge_hookshot_generic_endpoint: "/hookshot/webhooks" +matrix_bridge_hookshot_generic_endpoint: "{{ matrix_bridge_hookshot_webhook_endpoint }}/webhook" # urlprefix gets updated with protocol & port in group_vars/matrix_servers -matrix_hookshot_generic_urlPrefix: "{{ matrix_hookshot_urlprefix }}{{ matrix_hookshot_generic_endpoint }}" # noqa var-naming +matrix_bridge_hookshot_generic_urlPrefix: "{{ matrix_bridge_hookshot_urlprefix }}{{ matrix_bridge_hookshot_generic_endpoint }}" # noqa var-naming # If you're also using matrix-appservice-webhooks, take care that these prefixes don't overlap -matrix_hookshot_generic_userIdPrefix: '_webhooks_' # noqa var-naming -matrix_hookshot_generic_allowJsTransformationFunctions: false # noqa var-naming -matrix_hookshot_generic_waitForComplete: false # noqa var-naming -matrix_hookshot_generic_sendExpiryNotice: false # noqa var-naming -matrix_hookshot_generic_requireExpiryTime: false # noqa var-naming -matrix_hookshot_generic_maxExpiryTime: "30d" # noqa var-naming +matrix_bridge_hookshot_generic_userIdPrefix: '_webhooks_' # noqa var-naming +matrix_bridge_hookshot_generic_allowJsTransformationFunctions: false # noqa var-naming +matrix_bridge_hookshot_generic_waitForComplete: false # noqa var-naming +matrix_bridge_hookshot_generic_sendExpiryNotice: false # noqa var-naming +matrix_bridge_hookshot_generic_requireExpiryTime: false # noqa var-naming +matrix_bridge_hookshot_generic_maxExpiryTime: "30d" # noqa var-naming -matrix_hookshot_feeds_enabled: true -matrix_hookshot_feeds_pollIntervalSeconds: 600 # noqa var-naming -matrix_hookshot_feeds_pollTimeoutSeconds: 30 # noqa var-naming +matrix_bridge_hookshot_feeds_enabled: true +matrix_bridge_hookshot_feeds_pollIntervalSeconds: 600 # noqa var-naming +matrix_bridge_hookshot_feeds_pollTimeoutSeconds: 30 # noqa var-naming # Valid values: error, warn, info, debug -matrix_hookshot_logging_level: warn +matrix_bridge_hookshot_logging_level: warn -matrix_hookshot_widgets_enabled: true -matrix_hookshot_widgets_port: 9003 -matrix_hookshot_widgets_addToAdminRooms: false # default off as it is a beta feature # noqa var-naming -matrix_hookshot_widgets_roomSetupWidget_enabled: true # noqa var-naming -matrix_hookshot_widgets_roomSetupWidget_addOnInvite: false # noqa var-naming +matrix_bridge_hookshot_widgets_enabled: true +matrix_bridge_hookshot_widgets_port: 9003 +matrix_bridge_hookshot_widgets_addToAdminRooms: false # default off as it is a beta feature # noqa var-naming +matrix_bridge_hookshot_widgets_roomSetupWidget_enabled: true # noqa var-naming +matrix_bridge_hookshot_widgets_roomSetupWidget_addOnInvite: false # noqa var-naming # `disallowedIpRanges` describes which IP ranges should be disallowed when resolving homeserver IP addresses (for security reasons). Unless you know what you are doing, it is recommended to not include this key. The following IPs are blocked by default, unless you supply another list. -# matrix_hookshot_widgets_disallowedIpRanges: +# matrix_bridge_hookshot_widgets_disallowedIpRanges: # - 127.0.0.0/8 # - 10.0.0.0/8 # - 172.16.0.0/12 @@ -220,18 +220,18 @@ matrix_hookshot_widgets_roomSetupWidget_addOnInvite: false # noqa var-naming # - 2001:db8::/32 # - ff00::/8 # - fec0::/10 -matrix_hookshot_widgets_disallowedIpRanges: '' # noqa var-naming -matrix_hookshot_widgets_internal: "/widgetapi" -matrix_hookshot_widgets_hostname: "{{ matrix_hookshot_public_hostname }}" -matrix_hookshot_widgets_endpoint: "{{ matrix_hookshot_public_endpoint }}{{ matrix_hookshot_widgets_internal }}" -matrix_hookshot_widgets_publicUrl: "{{ matrix_hookshot_urlprefix }}{{ matrix_hookshot_widgets_endpoint }}/v1/static/" # noqa var-naming -matrix_hookshot_widgets_branding_widgetTitle: "Hookshot Configuration" # noqa var-naming +matrix_bridge_hookshot_widgets_disallowedIpRanges: '' # noqa var-naming +matrix_bridge_hookshot_widgets_internal: "/widgetapi" +matrix_bridge_hookshot_widgets_hostname: "{{ matrix_bridge_hookshot_public_hostname }}" +matrix_bridge_hookshot_widgets_endpoint: "{{ matrix_bridge_hookshot_public_endpoint }}{{ matrix_bridge_hookshot_widgets_internal }}" +matrix_bridge_hookshot_widgets_publicUrl: "{{ matrix_bridge_hookshot_urlprefix }}{{ matrix_bridge_hookshot_widgets_endpoint }}/v1/static/" # noqa var-naming +matrix_bridge_hookshot_widgets_branding_widgetTitle: "Hookshot Configuration" # noqa var-naming # You can configure access to the bridge as documented here https://matrix-org.github.io/matrix-hookshot/setup.html#permissions # When empty, the default permissions are applied. # Example: -# matrix_hookshot_permissions: +# matrix_bridge_hookshot_permissions: # - actor: * # services: # - service: * @@ -240,148 +240,148 @@ matrix_hookshot_widgets_branding_widgetTitle: "Hookshot Configuration" # noqa # services: # - service: "*" # level: admin -matrix_hookshot_permissions: [] +matrix_bridge_hookshot_permissions: [] # Static connections that can be configured by an administrator, as documented here: # https://matrix-org.github.io/matrix-hookshot/latest/usage/static_connections.html # Currently only generic webhooks are supported. # Example: -# matrix_hookshot_connections: +# matrix_bridge_hookshot_connections: # - connectionType: uk.half-shot.matrix-hookshot.generic.hook # stateKey: my-unique-webhook-id # roomId: "!room-id" # state: # name: My Static Webhook -matrix_hookshot_connections: [] +matrix_bridge_hookshot_connections: [] -matrix_hookshot_bot_displayname: Hookshot Bot -matrix_hookshot_bot_avatar: 'mxc://half-shot.uk/2876e89ccade4cb615e210c458e2a7a6883fe17d' +matrix_bridge_hookshot_bot_displayname: Hookshot Bot +matrix_bridge_hookshot_bot_avatar: 'mxc://half-shot.uk/2876e89ccade4cb615e210c458e2a7a6883fe17d' -matrix_hookshot_container_network: "" +matrix_bridge_hookshot_container_network: "" # A list of extra arguments to pass to the container -matrix_hookshot_container_extra_arguments: [] +matrix_bridge_hookshot_container_extra_arguments: [] -# matrix_hookshot_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_hookshot_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_hookshot_container_labels_additional_labels`. -matrix_hookshot_container_labels_traefik_enabled: true -matrix_hookshot_container_labels_traefik_docker_network: "{{ matrix_hookshot_container_network }}" -matrix_hookshot_container_labels_traefik_entrypoints: web-secure -matrix_hookshot_container_labels_traefik_tls_certResolver: default # noqa var-naming +# To inject your own other container labels, see `matrix_bridge_hookshot_container_labels_additional_labels`. +matrix_bridge_hookshot_container_labels_traefik_enabled: true +matrix_bridge_hookshot_container_labels_traefik_docker_network: "{{ matrix_bridge_hookshot_container_network }}" +matrix_bridge_hookshot_container_labels_traefik_entrypoints: web-secure +matrix_bridge_hookshot_container_labels_traefik_tls_certResolver: default # noqa var-naming # Controls whether labels will be added that expose Hookshot's webhooks endpoint -matrix_hookshot_container_labels_webhooks_enabled: true -matrix_hookshot_container_labels_webhooks_traefik_rule: "Host(`{{ matrix_hookshot_webhook_hostname }}`) && PathPrefix(`{{ matrix_hookshot_webhook_endpoint }}`)" -matrix_hookshot_container_labels_webhooks_traefik_priority: 0 -matrix_hookshot_container_labels_webhooks_traefik_entrypoints: "{{ matrix_hookshot_container_labels_traefik_entrypoints }}" -matrix_hookshot_container_labels_webhooks_traefik_tls: "{{ matrix_hookshot_container_labels_webhooks_traefik_entrypoints != 'web' }}" -matrix_hookshot_container_labels_webhooks_traefik_tls_certResolver: "{{ matrix_hookshot_container_labels_traefik_tls_certResolver }}" # noqa var-naming +matrix_bridge_hookshot_container_labels_webhooks_enabled: true +matrix_bridge_hookshot_container_labels_webhooks_traefik_rule: "Host(`{{ matrix_bridge_hookshot_webhook_hostname }}`) && PathPrefix(`{{ matrix_bridge_hookshot_webhook_endpoint }}`)" +matrix_bridge_hookshot_container_labels_webhooks_traefik_priority: 0 +matrix_bridge_hookshot_container_labels_webhooks_traefik_entrypoints: "{{ matrix_bridge_hookshot_container_labels_traefik_entrypoints }}" +matrix_bridge_hookshot_container_labels_webhooks_traefik_tls: "{{ matrix_bridge_hookshot_container_labels_webhooks_traefik_entrypoints != 'web' }}" +matrix_bridge_hookshot_container_labels_webhooks_traefik_tls_certResolver: "{{ matrix_bridge_hookshot_container_labels_traefik_tls_certResolver }}" # noqa var-naming # Controls whether labels will be added that expose Hookshot's appservice endpoint -matrix_hookshot_container_labels_appservice_enabled: true -matrix_hookshot_container_labels_appservice_traefik_rule: "Host(`{{ matrix_hookshot_appservice_hostname }}`) && PathPrefix(`{{ matrix_hookshot_appservice_endpoint }}`)" -matrix_hookshot_container_labels_appservice_traefik_priority: 0 -matrix_hookshot_container_labels_appservice_traefik_entrypoints: "{{ matrix_hookshot_container_labels_traefik_entrypoints }}" -matrix_hookshot_container_labels_appservice_traefik_tls: "{{ matrix_hookshot_container_labels_appservice_traefik_entrypoints != 'web' }}" -matrix_hookshot_container_labels_appservice_traefik_tls_certResolver: "{{ matrix_hookshot_container_labels_traefik_tls_certResolver }}" # noqa var-naming +matrix_bridge_hookshot_container_labels_appservice_enabled: true +matrix_bridge_hookshot_container_labels_appservice_traefik_rule: "Host(`{{ matrix_bridge_hookshot_appservice_hostname }}`) && PathPrefix(`{{ matrix_bridge_hookshot_appservice_endpoint }}`)" +matrix_bridge_hookshot_container_labels_appservice_traefik_priority: 0 +matrix_bridge_hookshot_container_labels_appservice_traefik_entrypoints: "{{ matrix_bridge_hookshot_container_labels_traefik_entrypoints }}" +matrix_bridge_hookshot_container_labels_appservice_traefik_tls: "{{ matrix_bridge_hookshot_container_labels_appservice_traefik_entrypoints != 'web' }}" +matrix_bridge_hookshot_container_labels_appservice_traefik_tls_certResolver: "{{ matrix_bridge_hookshot_container_labels_traefik_tls_certResolver }}" # noqa var-naming # Controls whether labels will be added that expose Hookshot's widgets endpoint -matrix_hookshot_container_labels_widgets_enabled: "{{ matrix_hookshot_widgets_enabled }}" -matrix_hookshot_container_labels_widgets_traefik_rule: "Host(`{{ matrix_hookshot_widgets_hostname }}`) && PathPrefix(`{{ matrix_hookshot_widgets_endpoint }}`)" -matrix_hookshot_container_labels_widgets_traefik_priority: 0 -matrix_hookshot_container_labels_widgets_traefik_entrypoints: "{{ matrix_hookshot_container_labels_traefik_entrypoints }}" -matrix_hookshot_container_labels_widgets_traefik_tls: "{{ matrix_hookshot_container_labels_widgets_traefik_entrypoints != 'web' }}" -matrix_hookshot_container_labels_widgets_traefik_tls_certResolver: "{{ matrix_hookshot_container_labels_traefik_tls_certResolver }}" # noqa var-naming +matrix_bridge_hookshot_container_labels_widgets_enabled: "{{ matrix_bridge_hookshot_widgets_enabled }}" +matrix_bridge_hookshot_container_labels_widgets_traefik_rule: "Host(`{{ matrix_bridge_hookshot_widgets_hostname }}`) && PathPrefix(`{{ matrix_bridge_hookshot_widgets_endpoint }}`)" +matrix_bridge_hookshot_container_labels_widgets_traefik_priority: 0 +matrix_bridge_hookshot_container_labels_widgets_traefik_entrypoints: "{{ matrix_bridge_hookshot_container_labels_traefik_entrypoints }}" +matrix_bridge_hookshot_container_labels_widgets_traefik_tls: "{{ matrix_bridge_hookshot_container_labels_widgets_traefik_entrypoints != 'web' }}" +matrix_bridge_hookshot_container_labels_widgets_traefik_tls_certResolver: "{{ matrix_bridge_hookshot_container_labels_traefik_tls_certResolver }}" # noqa var-naming # Controls whether labels will be added that expose Hookshot's metrics endpoint -matrix_hookshot_container_labels_metrics_enabled: "{{ matrix_hookshot_metrics_enabled and matrix_hookshot_metrics_proxying_enabled }}" -matrix_hookshot_container_labels_metrics_traefik_rule: "Host(`{{ matrix_hookshot_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_hookshot_metrics_proxying_path_prefix }}`)" -matrix_hookshot_container_labels_metrics_traefik_priority: 0 -matrix_hookshot_container_labels_metrics_traefik_entrypoints: "{{ matrix_hookshot_container_labels_traefik_entrypoints }}" -matrix_hookshot_container_labels_metrics_traefik_tls: "{{ matrix_hookshot_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_hookshot_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_hookshot_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_hookshot_container_labels_metrics_middleware_basic_auth_enabled: false +matrix_bridge_hookshot_container_labels_metrics_enabled: "{{ matrix_bridge_hookshot_metrics_enabled and matrix_bridge_hookshot_metrics_proxying_enabled }}" +matrix_bridge_hookshot_container_labels_metrics_traefik_rule: "Host(`{{ matrix_bridge_hookshot_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_bridge_hookshot_metrics_proxying_path_prefix }}`)" +matrix_bridge_hookshot_container_labels_metrics_traefik_priority: 0 +matrix_bridge_hookshot_container_labels_metrics_traefik_entrypoints: "{{ matrix_bridge_hookshot_container_labels_traefik_entrypoints }}" +matrix_bridge_hookshot_container_labels_metrics_traefik_tls: "{{ matrix_bridge_hookshot_container_labels_metrics_traefik_entrypoints != 'web' }}" +matrix_bridge_hookshot_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_bridge_hookshot_container_labels_traefik_tls_certResolver }}" # noqa var-naming +matrix_bridge_hookshot_container_labels_metrics_middleware_basic_auth_enabled: false # See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_hookshot_container_labels_metrics_middleware_basic_auth_users: '' +matrix_bridge_hookshot_container_labels_metrics_middleware_basic_auth_users: '' -# matrix_hookshot_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# matrix_bridge_hookshot_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_hookshot_container_labels_additional_labels: | +# matrix_bridge_hookshot_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_hookshot_container_labels_additional_labels: '' +matrix_bridge_hookshot_container_labels_additional_labels: '' # List of systemd services that service depends on. -matrix_hookshot_systemd_required_services_list: "{{ matrix_hookshot_systemd_required_services_list_default + matrix_hookshot_systemd_required_services_list_auto + matrix_hookshot_systemd_required_services_list_custom }}" -matrix_hookshot_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_hookshot_systemd_required_services_list_auto: [] -matrix_hookshot_systemd_required_services_list_custom: [] +matrix_bridge_hookshot_systemd_required_services_list: "{{ matrix_bridge_hookshot_systemd_required_services_list_default + matrix_bridge_hookshot_systemd_required_services_list_auto + matrix_bridge_hookshot_systemd_required_services_list_custom }}" +matrix_bridge_hookshot_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_hookshot_systemd_required_services_list_auto: [] +matrix_bridge_hookshot_systemd_required_services_list_custom: [] # List of systemd services that service wants -matrix_hookshot_systemd_wanted_services_list: [] +matrix_bridge_hookshot_systemd_wanted_services_list: [] # List of ports to bind to the host to expose them directly. # Supply docker port bind arguments in a list like this: # -# matrix_hookshot_container_http_host_bind_ports: -# - "127.0.0.1:9999:{{ matrix_hookshot_metrics_port }}" +# matrix_bridge_hookshot_container_http_host_bind_ports: +# - "127.0.0.1:9999:{{ matrix_bridge_hookshot_metrics_port }}" # # Above example will bind the metrics port in the container to port 9999 on localhost. -matrix_hookshot_container_http_host_bind_ports: [] +matrix_bridge_hookshot_container_http_host_bind_ports: [] # These tokens will be set automatically -matrix_hookshot_appservice_token: '' -matrix_hookshot_homeserver_token: '' +matrix_bridge_hookshot_appservice_token: '' +matrix_bridge_hookshot_homeserver_token: '' # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # # For a more advanced customization, you can extend the default (see `matrixhookshot_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_hookshot_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_hookshot_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_hookshot_configuration_extension_yaml: | +matrix_bridge_hookshot_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_hookshot_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_hookshot_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_hookshot_configuration_yaml`. + # completely redefining `matrix_bridge_hookshot_configuration_yaml`. -matrix_hookshot_configuration_extension: "{{ matrix_hookshot_configuration_extension_yaml | from_yaml if matrix_hookshot_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_hookshot_configuration_extension: "{{ matrix_bridge_hookshot_configuration_extension_yaml | from_yaml if matrix_bridge_hookshot_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_hookshot_configuration_yaml`. -matrix_hookshot_configuration: "{{ matrix_hookshot_configuration_yaml | from_yaml | combine(matrix_hookshot_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_hookshot_configuration_yaml`. +matrix_bridge_hookshot_configuration: "{{ matrix_bridge_hookshot_configuration_yaml | from_yaml | combine(matrix_bridge_hookshot_configuration_extension, recursive=True) }}" # Default registration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # # For a more advanced customization, you can extend the default (see `matrixhookshot_registration_extension_yaml`) # or completely replace this variable with your own template. -matrix_hookshot_registration_yaml: "{{ lookup('template', 'templates/registration.yml.j2') }}" +matrix_bridge_hookshot_registration_yaml: "{{ lookup('template', 'templates/registration.yml.j2') }}" -matrix_hookshot_registration_extension_yaml: | +matrix_bridge_hookshot_registration_extension_yaml: | # Your custom YAML registration goes here. - # This registration extends the default starting registration (`matrix_hookshot_registration_yaml`). + # This registration extends the default starting registration (`matrix_bridge_hookshot_registration_yaml`). # # You can override individual variables from the default registration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_hookshot_registration_yaml`. + # completely redefining `matrix_bridge_hookshot_registration_yaml`. -matrix_hookshot_registration_extension: "{{ matrix_hookshot_registration_extension_yaml | from_yaml if matrix_hookshot_registration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_hookshot_registration_extension: "{{ matrix_bridge_hookshot_registration_extension_yaml | from_yaml if matrix_bridge_hookshot_registration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final registration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_hookshot_registration_yaml`. -matrix_hookshot_registration: "{{ matrix_hookshot_registration_yaml | from_yaml | combine(matrix_hookshot_registration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_hookshot_registration_yaml`. +matrix_bridge_hookshot_registration: "{{ matrix_bridge_hookshot_registration_yaml | from_yaml | combine(matrix_bridge_hookshot_registration_extension, recursive=True) }}" -# matrix_hookshot_restart_necessary controls whether the service +# matrix_bridge_hookshot_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -389,4 +389,4 @@ matrix_hookshot_registration: "{{ matrix_hookshot_registration_yaml | from_yaml # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_hookshot_restart_necessary: false +matrix_bridge_hookshot_restart_necessary: false diff --git a/roles/custom/matrix-bridge-hookshot/molecule/default/converge.yml b/roles/custom/matrix-bridge-hookshot/molecule/default/converge.yml new file mode 100644 index 000000000..1865d1b98 --- /dev/null +++ b/roles/custom/matrix-bridge-hookshot/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for hookshot Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for hookshot Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure hookshot is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the hookshot systemd service is started + ansible.builtin.systemd_service: + name: matrix-hookshot.service + state: started diff --git a/roles/custom/matrix-bridge-hookshot/molecule/default/molecule.yml b/roles/custom/matrix-bridge-hookshot/molecule/default/molecule.yml new file mode 100644 index 000000000..5242dd93f --- /dev/null +++ b/roles/custom/matrix-bridge-hookshot/molecule/default/molecule.yml @@ -0,0 +1,102 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: hookshot-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_hookshot_container_network: hookshot-molecule + + # The stub prepare.yml stands up. Not a real homeserver, and nothing is asserted + # about it. + matrix_bridge_hookshot_homeserver_address: http://matrix.molecule.local:8008 + + # Here these only have to reach the rendered configuration and the registration. + matrix_bridge_hookshot_appservice_token: molecule_as_token_4f2a91 + matrix_bridge_hookshot_homeserver_token: molecule_hs_token_9b3e77 + + # Different from the role's default, so the registration's sender_localpart can only + # have come from the role. prepare.yml tells the stub to claim this same user id. + matrix_bridge_hookshot_bot_localpart: molecule-hookshot + + # Hookshot's HTTP surface is the point of this scenario. Every port below differs + # from BOTH the role's default and Hookshot's own, so an answer can only mean the + # role's configuration reached the process. verify.yml also asserts nothing answers + # on the defaults these replace. + matrix_bridge_hookshot_appservice_port: 9772 + matrix_bridge_hookshot_webhook_port: 9741 + + # Off in the role's defaults. Enabling it renders a second entry in the `listeners` + # list, and /metrics is the cheapest listener to assert *content* on. + matrix_bridge_hookshot_metrics_enabled: true + matrix_bridge_hookshot_metrics_port: 9752 + + # On in the role's defaults. Off here so the absence of a listener can be asserted: + # the widgets port staying closed is what tells "the role rendered the listener list" + # apart from "Hookshot binds everything anyway". + matrix_bridge_hookshot_widgets_enabled: false + + # No third-party service is configured here; see the header of verify.yml. + # GitLab is the one the role enables by default, so it is explicitly switched off. + matrix_bridge_hookshot_gitlab_enabled: false + + # The generic webhooks listener needs no account anywhere, so it is what this + # scenario exercises live. The prefix differs from the role's default. + matrix_bridge_hookshot_generic_userIdPrefix: _molecule_hook_ # noqa var-naming + + # Neither the role's default (600) nor Hookshot's own (600). + matrix_bridge_hookshot_feeds_pollIntervalSeconds: 907 # noqa var-naming + + # The role defaults to `warn`, Hookshot itself to `info`. A third value, so finding + # it in config.yml cannot be a coincidence. + matrix_bridge_hookshot_logging_level: debug + + # Traefik is not deployed here, so the labels the role would render for it are + # switched off and their absence is asserted instead. + matrix_bridge_hookshot_container_labels_traefik_enabled: false + + # verify.yml runs as its own play, where role defaults are out of scope, so what it + # reads is pinned here. These two match the role's own defaults on purpose: they name + # things rather than configure them, and nothing is asserted *about* them. + matrix_bridge_hookshot_base_path: /matrix/hookshot + matrix_bridge_hookshot_identifier: matrix-hookshot + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-hookshot/molecule/default/prepare.yml b/roles/custom/matrix-bridge-hookshot/molecule/default/prepare.yml new file mode 100644 index 000000000..975f7312a --- /dev/null +++ b/roles/custom/matrix-bridge-hookshot/molecule/default/prepare.yml @@ -0,0 +1,83 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare hookshot Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks set owner/group by name, which Ansible resolves through the + # passwd database, so they have to exist first. `matrix-base` creates them for real. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_hookshot_container_network }}" + register: hookshot_molecule_network + changed_when: hookshot_molecule_network.rc == 0 + failed_when: + - hookshot_molecule_network.rc != 0 + - "'already exists' not in hookshot_molecule_network.stderr" + + # Hookshot contacts the homeserver as it starts, and - being an appservice - + # refuses to run if /whoami answers with a user other than the bot it was + # configured as, so the stub is told to claim the localpart the scenario set. + # It is not being asked to bridge anything, and nothing is asserted about it; + # see molecule-shared/homeserver-stub.py. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_hookshot_container_network }}" + molecule_shared_stub_server_name: molecule.local + molecule_shared_stub_user_id: "@{{ matrix_bridge_hookshot_bot_localpart }}:molecule.local" diff --git a/roles/custom/matrix-bridge-hookshot/molecule/default/requirements.yml b/roles/custom/matrix-bridge-hookshot/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-hookshot/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-hookshot/molecule/default/verify.yml b/roles/custom/matrix-bridge-hookshot/molecule/default/verify.yml new file mode 100644 index 000000000..5cb8694e8 --- /dev/null +++ b/roles/custom/matrix-bridge-hookshot/molecule/default/verify.yml @@ -0,0 +1,363 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves Hookshot starts on the config.yml and registration.yml the role rendered, +# and opens exactly the HTTP listeners that configuration described - on the ports +# the role put there, and not on the ones it did not. +# +# Deliberately does NOT configure GitHub, GitLab, Jira or Figma. Each needs an account +# and a credential on a third-party service, which is where a scenario stops testing this +# repository and starts testing a fake (see docs/molecule-testing.md). The generic webhooks +# listener needs no credential from anyone, so it is the one exercised live. +- name: Verify hookshot + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + + tasks: + # From the role's own defaults rather than pinned in molecule.yml, so the version + # assertion compares the running image against what the role ships, not against the + # scenario. The default ports come from here for the same reason: "these ports stay + # closed" is only meaningful against the ports the role would otherwise have used. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: hookshot_role_defaults + + - name: Wait for the hookshot service to become active + ansible.builtin.systemd_service: + name: matrix-hookshot.service + register: hookshot_service + until: hookshot_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # `Restart=always` means a bridge crash-looping on unreadable config still reports + # `active`, so the restart counter is checked too. Asserted `is defined` because + # `| int` turns a missing property into 0 and would pass vacuously. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - hookshot_service.status.ActiveState == 'active' + - hookshot_service.status.NRestarts is defined + - hookshot_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-hookshot.service is + {{ hookshot_service.status.ActiveState | default('unknown') }} + after {{ hookshot_service.status.NRestarts | default('?') }} + automatic restart(s) + success_msg: "matrix-hookshot.service is active and has not restarted" + + # ------------------------------------------------------------------ + # The rendered configuration + # ------------------------------------------------------------------ + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_hookshot_base_path }}/config.yml" + register: hookshot_config_file + + - name: Parse the rendered configuration + ansible.builtin.set_fact: + hookshot_config: "{{ hookshot_config_file.content | b64decode | from_yaml }}" + + # Each differs from what Hookshot would use on its own AND from the role's defaults, + # so finding them here rules out a coincidence. + - name: Assert the rendered configuration carries this scenario's values + ansible.builtin.assert: + that: + - hookshot_config.bridge.domain == matrix_domain + - hookshot_config.bridge.url == matrix_bridge_hookshot_homeserver_address + - hookshot_config.bridge.port | int == matrix_bridge_hookshot_appservice_port | int + - hookshot_config.generic.userIdPrefix == matrix_bridge_hookshot_generic_userIdPrefix + - hookshot_config.feeds.pollIntervalSeconds | int == matrix_bridge_hookshot_feeds_pollIntervalSeconds | int + - hookshot_config.logging.level == matrix_bridge_hookshot_logging_level + - hookshot_config.metrics.enabled | bool + fail_msg: "The rendered configuration does not carry the scenario's values" + success_msg: "The rendered configuration carries the scenario's values" + + # The `listeners` list is the role's own construction, assembled from a handful of + # independent switches. Getting it wrong is invisible in a "did it start" test, + # hence asserting the whole shape rather than key by key. + - name: Assert the role rendered exactly the listeners the scenario asked for + ansible.builtin.assert: + that: + - hookshot_config.listeners | length == 2 + - hookshot_listener_ports == [matrix_bridge_hookshot_webhook_port | int, matrix_bridge_hookshot_metrics_port | int] + - hookshot_config.listeners | map(attribute='resources') | flatten == ['webhooks', 'metrics'] + fail_msg: >- + The rendered listeners are {{ hookshot_config.listeners }}, not the + webhooks and metrics listeners this scenario configured + success_msg: "The role rendered exactly the webhooks and metrics listeners" + vars: + hookshot_listener_ports: "{{ hookshot_config.listeners | map(attribute='port') | map('int') | list }}" + + # GitLab is the interesting one: the role turns it ON by default, so its absence + # proves the scenario's switch reached the template. + - name: Assert no third-party service section was rendered + ansible.builtin.assert: + that: + - "'gitlab' not in hookshot_config" + - "'github' not in hookshot_config" + - "'jira' not in hookshot_config" + - "'figma' not in hookshot_config" + fail_msg: >- + The rendered configuration contains a third-party service section + ({{ hookshot_config.keys() | list }}); this scenario configures none + success_msg: "No third-party service section was rendered" + + - name: Assert no widgets section was rendered while widgets are disabled + ansible.builtin.assert: + that: + - "'widgets' not in hookshot_config" + fail_msg: >- + A widgets section was rendered even though + matrix_bridge_hookshot_widgets_enabled is false + success_msg: "No widgets section was rendered while widgets are disabled" + + # ------------------------------------------------------------------ + # The rendered registration + # ------------------------------------------------------------------ + + # The role generates the registration; Hookshot only consumes it. Worth checking + # on its own, as it is the half of the handshake the homeserver reads. + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_hookshot_base_path }}/registration.yml" + register: hookshot_registration_file + + - name: Parse the rendered registration + ansible.builtin.set_fact: + hookshot_registration: "{{ hookshot_registration_file.content | b64decode | from_yaml }}" + + # `url` is built from the container name and the appservice port. It has to agree + # with `bridge.port` in config.yml, or the two halves silently disagree. + - name: Assert the registration carries the scenario's tokens, bot and callback URL + ansible.builtin.assert: + that: + - hookshot_registration.as_token == matrix_bridge_hookshot_appservice_token + - hookshot_registration.hs_token == matrix_bridge_hookshot_homeserver_token + - hookshot_registration.sender_localpart == matrix_bridge_hookshot_bot_localpart + - hookshot_registration.url == 'http://' + matrix_bridge_hookshot_identifier + ':' + (matrix_bridge_hookshot_appservice_port | string) + fail_msg: "The appservice registration does not carry the scenario's tokens, bot and callback URL" + success_msg: "The appservice registration carries the scenario's tokens, bot and callback URL" + + # The user namespace derives from the generic webhook prefix, and the GitLab namespace + # is conditional on that service being enabled. Checks both switches reach the + # registration, not just config.yml. + - name: Assert the registration namespaces follow the enabled services + ansible.builtin.assert: + that: + - hookshot_registration_user_regexes | select('search', matrix_bridge_hookshot_generic_userIdPrefix) | list | length == 1 + - hookshot_registration_user_regexes | select('search', '_gitlab_') | list | length == 0 + fail_msg: >- + The registration's user namespaces are + {{ hookshot_registration_user_regexes }}, which do not follow the + services this scenario enabled + success_msg: "The registration's user namespaces follow the enabled services" + vars: + hookshot_registration_user_regexes: "{{ hookshot_registration.namespaces.users | map(attribute='regex') | list }}" + + # ------------------------------------------------------------------ + # The listeners, live + # ------------------------------------------------------------------ + + # A helper container, because the role publishes no host port - exactly as in a real + # deployment. See docs/molecule-testing.md. + - name: Wait for the webhooks listener to answer on the port the role configured + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_hookshot_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --max-time + - "5" + - --request + - POST + - --header + - "Content-Type: application/json" + - --data + - "{}" + - --write-out + - "|HTTP_STATUS=%{http_code}" + - "http://{{ matrix_bridge_hookshot_identifier }}:{{ matrix_bridge_hookshot_webhook_port }}/webhook/molecule-no-such-hook" + register: hookshot_webhooks_probe + changed_when: false + until: "'HTTP_STATUS=000' not in hookshot_webhooks_probe.stdout" + retries: 24 + delay: 5 + failed_when: false + + # An unknown webhook id draws a JSON body from the generic-webhook handler that no + # other component would produce. An Express "Cannot POST" page would mean the port is + # Hookshot's but the generic webhooks service was never mounted on it; a refused + # connection would mean the listener was never opened at all. + - name: Assert the generic webhooks service is mounted on that listener + ansible.builtin.assert: + that: + - "'\"ok\":false' in hookshot_webhooks_probe.stdout" + - "'Webhook not found' in hookshot_webhooks_probe.stdout" + - "'HTTP_STATUS=404' in hookshot_webhooks_probe.stdout" + fail_msg: >- + Port {{ matrix_bridge_hookshot_webhook_port }} did not answer as + Hookshot's generic webhooks service + ({{ hookshot_webhooks_probe.stdout | default('no output') }}) + success_msg: "The generic webhooks service answers on the port the role configured" + + # Metrics are OFF in the role's defaults, so this listener exists only because the + # scenario asked for it. + - name: Probe the metrics listener on the port the role configured + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_hookshot_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --max-time + - "5" + - --write-out + - "|HTTP_STATUS=%{http_code}" + - "http://{{ matrix_bridge_hookshot_identifier }}:{{ matrix_bridge_hookshot_metrics_port }}/metrics" + register: hookshot_metrics_probe + changed_when: false + failed_when: false + + - name: Assert the metrics listener serves Hookshot's own metrics + ansible.builtin.assert: + that: + - "'HTTP_STATUS=200' in hookshot_metrics_probe.stdout" + - "'hookshot_webhooks_http_request' in hookshot_metrics_probe.stdout" + fail_msg: >- + Port {{ matrix_bridge_hookshot_metrics_port }} did not serve Hookshot's + metrics ({{ hookshot_metrics_probe.stdout | default('no output') | truncate(200) }}) + success_msg: "The metrics listener serves Hookshot's own metrics" + + # The appservice port is not in `listeners`; it comes from `bridge.port`. + # A separate socket, opened by a separate part of the config. + - name: Probe the appservice port the role configured + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_hookshot_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --max-time + - "5" + - --write-out + - "|HTTP_STATUS=%{http_code}" + - "http://{{ matrix_bridge_hookshot_identifier }}:{{ matrix_bridge_hookshot_appservice_port }}/_matrix/app/v1/ping" + register: hookshot_appservice_probe + changed_when: false + failed_when: false + + - name: Assert the appservice API answers on the port the role configured + ansible.builtin.assert: + that: + - "'HTTP_STATUS=000' not in hookshot_appservice_probe.stdout" + - "'errcode' in hookshot_appservice_probe.stdout" + fail_msg: >- + Port {{ matrix_bridge_hookshot_appservice_port }} did not answer as a + Matrix appservice + ({{ hookshot_appservice_probe.stdout | default('no output') }}) + success_msg: "The appservice API answers on the port the role configured" + + # The other half of the story. Every port above is one the scenario chose; these are + # the ones the role and Hookshot would have used had the scenario's configuration never + # reached the process. If any of them answers, the probes above prove much less than + # they appear to. + - name: Probe the ports the role's defaults would have used + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_hookshot_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --max-time + - "5" + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - "http://{{ matrix_bridge_hookshot_identifier }}:{{ item.port }}/" + register: hookshot_closed_probes + changed_when: false + failed_when: false + loop: + - port: "{{ hookshot_role_defaults.matrix_bridge_hookshot_appservice_port }}" + what: the appservice port the role defaults to + - port: "{{ hookshot_role_defaults.matrix_bridge_hookshot_webhook_port }}" + what: the webhooks port the role defaults to + - port: "{{ hookshot_role_defaults.matrix_bridge_hookshot_metrics_port }}" + what: the metrics port the role defaults to + - port: "{{ hookshot_role_defaults.matrix_bridge_hookshot_widgets_port }}" + what: the widgets port, whose listener this scenario disabled + loop_control: + label: "{{ item.port }} - {{ item.what }}" + + - name: Assert nothing listens on the ports the role's defaults would have used + ansible.builtin.assert: + that: + - hookshot_closed_probes.results | rejectattr('stdout', 'search', 'HTTP_STATUS=000') | list | length == 0 + fail_msg: >- + Something answered on + {{ hookshot_closed_probes.results | rejectattr('stdout', 'search', 'HTTP_STATUS=000') | map(attribute='item') | list }}, + so the ports this scenario configured are not the only ones Hookshot + is listening on + success_msg: >- + Nothing listens on the ports the role's defaults would have used + ({{ hookshot_closed_probes.results | map(attribute='item.port') | list | join(', ') }}) + + # ------------------------------------------------------------------ + # The container the role started + # ------------------------------------------------------------------ + + - name: Read the image of the running container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - "{{ matrix_bridge_hookshot_identifier }}" + - --format + - "{{ '{{' }} .Config.Image {{ '}}' }}" + register: hookshot_image + changed_when: false + + - name: Assert the running container is the version defaults/main.yml pins + ansible.builtin.assert: + that: + - hookshot_role_defaults.matrix_bridge_hookshot_version | string in hookshot_image.stdout + fail_msg: >- + The running container is {{ hookshot_image.stdout }}, which does not + carry the pinned version + {{ hookshot_role_defaults.matrix_bridge_hookshot_version }} + success_msg: "The running container is the version defaults/main.yml pins" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_hookshot_base_path }}/labels" + register: hookshot_labels + + - name: Assert no Traefik labels are emitted while Traefik support is disabled + ansible.builtin.assert: + that: + - "'traefik.' not in (hookshot_labels.content | b64decode)" + fail_msg: >- + Traefik labels were emitted even though + matrix_bridge_hookshot_container_labels_traefik_enabled is false + success_msg: "No Traefik labels are emitted while Traefik support is disabled" diff --git a/roles/custom/matrix-bridge-hookshot/tasks/main.yml b/roles/custom/matrix-bridge-hookshot/tasks/main.yml index afe5da088..c6b09ff60 100644 --- a/roles/custom/matrix-bridge-hookshot/tasks/main.yml +++ b/roles/custom/matrix-bridge-hookshot/tasks/main.yml @@ -7,9 +7,15 @@ --- - tags: + # Resetting the crypto store is destructive and is only ever meant to happen + # when explicitly asked for. Without `never`, a playbook run that does not + # select tags at all runs this block along with everything else - which fails + # on a host where the service does not exist yet, and silently resets the + # crypto store on one where it does. + - never - reset-hookshot-encryption block: - - when: matrix_hookshot_enabled | bool + - when: matrix_bridge_hookshot_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/reset_encryption.yml" - tags: @@ -20,10 +26,10 @@ - install-hookshot - install-bridge-hookshot block: - - when: matrix_hookshot_enabled | bool + - when: matrix_bridge_hookshot_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_hookshot_enabled | bool + - when: matrix_bridge_hookshot_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: @@ -31,5 +37,5 @@ - setup-hookshot - setup-bridge-hookshot block: - - when: not matrix_hookshot_enabled | bool + - when: not matrix_bridge_hookshot_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-hookshot/tasks/reset_encryption.yml b/roles/custom/matrix-bridge-hookshot/tasks/reset_encryption.yml index 2a0c27eb5..24ab7182d 100644 --- a/roles/custom/matrix-bridge-hookshot/tasks/reset_encryption.yml +++ b/roles/custom/matrix-bridge-hookshot/tasks/reset_encryption.yml @@ -8,7 +8,7 @@ ansible.builtin.service: name: matrix-hookshot state: stopped - register: matrix_hookshot_stopped + register: matrix_bridge_hookshot_stopped # `yarn start:resetcrypto` fails, as described here: https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3868 # Also related to: https://github.com/matrix-org/matrix-hookshot/issues/730 @@ -17,11 +17,11 @@ cmd: | {{ devture_systemd_docker_base_host_command_docker }} run --rm - --name={{ matrix_hookshot_identifier }}-reset-crypto + --name={{ matrix_bridge_hookshot_identifier }}-reset-crypto --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL - --mount type=bind,src={{ matrix_hookshot_base_path }},dst=/data - {{ matrix_hookshot_container_image }} + --mount type=bind,src={{ matrix_bridge_hookshot_base_path }},dst=/data + {{ matrix_bridge_hookshot_container_image }} node --require source-map-support/register /usr/bin/matrix-hookshot/App/ResetCryptoStore.js changed_when: true @@ -31,4 +31,4 @@ state: started enabled: true daemon_reload: true - when: matrix_hookshot_stopped.changed | bool + when: matrix_bridge_hookshot_stopped.changed | bool diff --git a/roles/custom/matrix-bridge-hookshot/tasks/setup_install.yml b/roles/custom/matrix-bridge-hookshot/tasks/setup_install.yml index 8f452216c..bae2432f4 100644 --- a/roles/custom/matrix-bridge-hookshot/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-hookshot/tasks/setup_install.yml @@ -24,54 +24,60 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_hookshot_base_path }}", when: true} - - {path: "{{ matrix_hookshot_container_src_files_path }}", when: "{{ matrix_hookshot_container_image_self_build }}"} + - {path: "{{ matrix_bridge_hookshot_base_path }}", when: true} + - {path: "{{ matrix_bridge_hookshot_container_src_files_path }}", when: "{{ matrix_bridge_hookshot_container_image_self_build }}"} when: item.when | bool - name: Ensure hookshot image is pulled - community.docker.docker_image: - name: "{{ matrix_hookshot_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_hookshot_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_hookshot_container_image_force_pull }}" - when: not matrix_hookshot_container_image_self_build - register: matrix_hookshot_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_hookshot_container_image }}" + pull: always + when: not matrix_bridge_hookshot_container_image_self_build + register: matrix_bridge_hookshot_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_hookshot_container_image_pull_result is not failed + until: matrix_bridge_hookshot_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure hookshot repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_hookshot_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_hookshot_container_image_self_build | bool" - name: Ensure hookshot repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_hookshot_container_image_self_build_repo }}" - dest: "{{ matrix_hookshot_container_src_files_path }}" - version: "{{ matrix_hookshot_container_image_self_build_branch }}" + repo: "{{ matrix_bridge_hookshot_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_hookshot_container_src_files_path }}" + version: "{{ matrix_bridge_hookshot_container_image_self_build_branch }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_hookshot_git_pull_results - when: "matrix_hookshot_container_image_self_build | bool" + register: matrix_bridge_hookshot_git_pull_results + when: "matrix_bridge_hookshot_container_image_self_build | bool" - name: Ensure hookshot Docker image is built - community.docker.docker_image: - name: "{{ matrix_hookshot_container_image }}" - source: build - force_source: "{{ matrix_hookshot_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_hookshot_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_hookshot_container_src_files_path }}" - pull: true - when: "matrix_hookshot_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_hookshot_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_hookshot_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_hookshot_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_hookshot_container_image_self_build | bool" + register: matrix_bridge_hookshot_container_image_build_result - name: Check if hookshot passkey exists ansible.builtin.stat: - path: "{{ matrix_hookshot_base_path }}/passkey.pem" + path: "{{ matrix_bridge_hookshot_base_path }}/passkey.pem" register: hookshot_passkey_file - name: Generate hookshot passkey if it doesn't exist ansible.builtin.shell: - cmd: "{{ matrix_host_command_openssl }} genpkey -out {{ matrix_hookshot_base_path }}/passkey.pem -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:4096" - creates: "{{ matrix_hookshot_base_path }}/passkey.pem" + cmd: "{{ matrix_host_command_openssl }} genpkey -out {{ matrix_bridge_hookshot_base_path }}/passkey.pem -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:4096" + creates: "{{ matrix_bridge_hookshot_base_path }}/passkey.pem" become: true become_user: "{{ matrix_user_name }}" when: "not hookshot_passkey_file.stat.exists" @@ -83,32 +89,32 @@ # See: https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/5033 - name: Ensure hookshot passkey has correct ownership and mode ansible.builtin.file: - path: "{{ matrix_hookshot_base_path }}/passkey.pem" + path: "{{ matrix_bridge_hookshot_base_path }}/passkey.pem" state: file mode: '0600' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_hookshot_passkey_result + register: matrix_bridge_hookshot_passkey_result - name: Ensure hookshot config.yml installed if provided ansible.builtin.copy: - content: "{{ matrix_hookshot_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_hookshot_base_path }}/config.yml" + content: "{{ matrix_bridge_hookshot_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_hookshot_base_path }}/config.yml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_hookshot_config_result + register: matrix_bridge_hookshot_config_result - name: Validate hookshot config.yml ansible.builtin.command: cmd: | {{ devture_systemd_docker_base_host_command_docker }} run --rm - --name={{ matrix_hookshot_container_url }}-validate + --name={{ matrix_bridge_hookshot_container_url }}-validate --user={{ matrix_user_uid }}:{{ matrix_user_gid }} --cap-drop=ALL - --mount type=bind,src={{ matrix_hookshot_base_path }}/config.yml,dst=/config.yml,ro - {{ matrix_hookshot_container_image }} node config/Config.js /config.yml + --mount type=bind,src={{ matrix_bridge_hookshot_base_path }}/config.yml,dst=/config.yml,ro + {{ matrix_bridge_hookshot_container_image }} node config/Config.js /config.yml register: hookshot_config_validation_result changed_when: false @@ -119,57 +125,59 @@ - name: Ensure hookshot registration.yml installed if provided ansible.builtin.copy: - content: "{{ matrix_hookshot_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_hookshot_base_path }}/registration.yml" + content: "{{ matrix_bridge_hookshot_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_hookshot_base_path }}/registration.yml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_hookshot_registration_result + register: matrix_bridge_hookshot_registration_result - name: Ensure hookshot github private key file installed if github is enabled ansible.builtin.copy: - content: "{{ matrix_hookshot_github_private_key }}" - dest: "{{ matrix_hookshot_base_path }}/{{ matrix_hookshot_github_private_key_file }}" + content: "{{ matrix_bridge_hookshot_github_private_key }}" + dest: "{{ matrix_bridge_hookshot_base_path }}/{{ matrix_bridge_hookshot_github_private_key_file }}" mode: '0400' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - when: matrix_hookshot_github_enabled | bool and matrix_hookshot_github_private_key|length > 0 - register: matrix_hookshot_github_key_result + when: matrix_bridge_hookshot_github_enabled | bool and matrix_bridge_hookshot_github_private_key|length > 0 + register: matrix_bridge_hookshot_github_key_result - name: Ensure matrix-hookshot container network is created + when: matrix_bridge_hookshot_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_hookshot_container_network }}" + name: "{{ matrix_bridge_hookshot_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" -- name: Ensure mautrix-hookshot support files installed +- name: Ensure hookshot support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_hookshot_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_hookshot_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_hookshot_support_files_result + register: matrix_bridge_hookshot_support_files_result - name: Ensure matrix-hookshot.service installed ansible.builtin.template: src: "{{ role_path }}/templates/systemd/matrix-hookshot.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-hookshot.service" mode: '0644' - register: matrix_hookshot_systemd_service_result + register: matrix_bridge_hookshot_systemd_service_result - name: Determine whether matrix-hookshot needs a restart ansible.builtin.set_fact: - matrix_hookshot_restart_necessary: >- + matrix_bridge_hookshot_restart_necessary: >- {{ - matrix_hookshot_config_result.changed | default(false) - or matrix_hookshot_registration_result.changed | default(false) - or matrix_hookshot_github_key_result.changed | default(false) - or matrix_hookshot_passkey_result.changed | default(false) - or matrix_hookshot_support_files_result.changed | default(false) - or matrix_hookshot_systemd_service_result.changed | default(false) - or matrix_hookshot_container_image_pull_result.changed | default(false) + matrix_bridge_hookshot_config_result.changed | default(false) + or matrix_bridge_hookshot_registration_result.changed | default(false) + or matrix_bridge_hookshot_github_key_result.changed | default(false) + or matrix_bridge_hookshot_passkey_result.changed | default(false) + or matrix_bridge_hookshot_support_files_result.changed | default(false) + or matrix_bridge_hookshot_systemd_service_result.changed | default(false) + or matrix_bridge_hookshot_container_image_pull_result.changed | default(false) + or matrix_bridge_hookshot_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-bridge-hookshot/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-hookshot/tasks/setup_uninstall.yml index 253bba45a..ce6968603 100644 --- a/roles/custom/matrix-bridge-hookshot/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-hookshot/tasks/setup_uninstall.yml @@ -9,9 +9,9 @@ - name: Check existence of matrix-hookshot service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-hookshot.service" - register: matrix_hookshot_service_stat + register: matrix_bridge_hookshot_service_stat -- when: matrix_hookshot_service_stat.stat.exists | bool +- when: matrix_bridge_hookshot_service_stat.stat.exists | bool block: - name: Ensure matrix-hookshot is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-hookshot/tasks/validate_config.yml b/roles/custom/matrix-bridge-hookshot/tasks/validate_config.yml index f9eec2dc3..86c3ad7bd 100644 --- a/roles/custom/matrix-bridge-hookshot/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-hookshot/tasks/validate_config.yml @@ -13,45 +13,46 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_hookshot_feeds_interval', 'new': 'matrix_hookshot_feeds_pollIntervalSeconds'} - - {'old': 'matrix_hookshot_generic_urlprefix', 'new': 'matrix_hookshot_generic_urlPrefix'} - - {'old': 'matrix_hookshot_generic_allow_js_transformation_functions', 'new': 'matrix_hookshot_generic_allowJsTransformationFunctions'} - - {'old': 'matrix_hookshot_generic_user_id_prefix', 'new': 'matrix_hookshot_generic_userIdPrefix'} - - {'old': 'matrix_hookshot_github_secret', 'new': 'matrix_hookshot_github_webhook_secret'} - - {'old': 'matrix_hookshot_github_appid', 'new': 'matrix_hookshot_github_auth_id'} - - {'old': 'matrix_hookshot_github_oauth_id', 'new': 'matrix_hookshot_github_oauth_client_id'} - - {'old': 'matrix_hookshot_github_oauth_secret', 'new': 'matrix_hookshot_github_oauth_client_secret'} - - {'old': 'matrix_hookshot_github_oauth_uri', 'new': 'matrix_hookshot_github_oauth_redirect_uri'} - - {'old': 'matrix_hookshot_github_ignore_hooks', 'new': 'matrix_hookshot_github_defaultOptions_ignoreHooks'} - - {'old': 'matrix_hookshot_github_command_prefix', 'new': 'matrix_hookshot_github_defaultOptions_commandPrefix'} - - {'old': 'matrix_hookshot_github_showIssueRoomLink', 'new': 'matrix_hookshot_github_defaultOptions_showIssueRoomLink'} - - {'old': 'matrix_hookshot_github_pr_diff', 'new': 'matrix_hookshot_github_defaultOptions_prDiff'} - - {'old': 'matrix_hookshot_github_including_labels', 'new': 'matrix_hookshot_github_defaultOptions_includingLabels'} - - {'old': 'matrix_hookshot_github_excluding_labels', 'new': 'matrix_hookshot_github_defaultOptions_excludingLabels'} - - {'old': 'matrix_hookshot_github_hotlink_prefix', 'new': 'matrix_hookshot_github_defaultOptions_hotlinkIssues_prefix'} - - {'old': 'matrix_hookshot_jira_secret', 'new': 'matrix_hookshot_jira_webhook_secret'} - - {'old': 'matrix_hookshot_jira_oauth_id', 'new': 'matrix_hookshot_jira_oauth_client_id'} - - {'old': 'matrix_hookshot_jira_oauth_secret', 'new': 'matrix_hookshot_jira_oauth_client_secret'} - - {'old': 'matrix_hookshot_jira_oauth_uri', 'new': 'matrix_hookshot_jira_oauth_client_secret'} - - {'old': 'matrix_hookshot_gitlab_secret', 'new': 'matrix_hookshot_gitlab_webhook_secret'} - - {'old': 'matrix_hookshot_ident', 'new': 'matrix_hookshot_identifier'} - - {'old': 'matrix_hookshot_queue_host', 'new': 'matrix_hookshot_cache_redis_host'} - - {'old': 'matrix_hookshot_queue_port', 'new': 'matrix_hookshot_cache_redis_port'} - - {'old': 'matrix_hookshot_experimental_encryption_enabled', 'new': 'matrix_hookshot_encryption_enabled'} - - {'old': 'matrix_hookshot_docker_image_name_prefix', 'new': 'matrix_hookshot_container_image_registry_prefix'} - - {'old': 'matrix_hookshot_provisioning_enabled', 'new': ''} - - {'old': 'matrix_hookshot_provisioning_port', 'new': ''} - - {'old': 'matrix_hookshot_provisioning_secret', 'new': ''} - - {'old': 'matrix_hookshot_provisioning_internal', 'new': ''} - - {'old': 'matrix_hookshot_provisioning_hostname', 'new': ''} - - {'old': 'matrix_hookshot_provisioning_endpoint', 'new': ''} - - {'old': 'matrix_hookshot_container_labels_provisioning_enabled', 'new': ''} - - {'old': 'matrix_hookshot_docker_image', 'new': 'matrix_hookshot_container_image'} - - {'old': 'matrix_hookshot_docker_image_force_pull', 'new': 'matrix_hookshot_container_image_force_pull'} - - {'old': 'matrix_hookshot_docker_image_registry_prefix', 'new': 'matrix_hookshot_container_image_registry_prefix'} - - {'old': 'matrix_hookshot_docker_image_registry_prefix_upstream', 'new': 'matrix_hookshot_container_image_registry_prefix_upstream'} - - {'old': 'matrix_hookshot_docker_image_registry_prefix_upstream_default', 'new': 'matrix_hookshot_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_hookshot_docker_src_files_path', 'new': 'matrix_hookshot_container_src_files_path'} + - {'old': 'matrix_bridge_hookshot_feeds_interval', 'new': 'matrix_bridge_hookshot_feeds_pollIntervalSeconds'} + - {'old': 'matrix_bridge_hookshot_generic_urlprefix', 'new': 'matrix_bridge_hookshot_generic_urlPrefix'} + - {'old': 'matrix_bridge_hookshot_generic_allow_js_transformation_functions', 'new': 'matrix_bridge_hookshot_generic_allowJsTransformationFunctions'} + - {'old': 'matrix_bridge_hookshot_generic_user_id_prefix', 'new': 'matrix_bridge_hookshot_generic_userIdPrefix'} + - {'old': 'matrix_bridge_hookshot_github_secret', 'new': 'matrix_bridge_hookshot_github_webhook_secret'} + - {'old': 'matrix_bridge_hookshot_github_appid', 'new': 'matrix_bridge_hookshot_github_auth_id'} + - {'old': 'matrix_bridge_hookshot_github_oauth_id', 'new': 'matrix_bridge_hookshot_github_oauth_client_id'} + - {'old': 'matrix_bridge_hookshot_github_oauth_secret', 'new': 'matrix_bridge_hookshot_github_oauth_client_secret'} + - {'old': 'matrix_bridge_hookshot_github_oauth_uri', 'new': 'matrix_bridge_hookshot_github_oauth_redirect_uri'} + - {'old': 'matrix_bridge_hookshot_github_ignore_hooks', 'new': 'matrix_bridge_hookshot_github_defaultOptions_ignoreHooks'} + - {'old': 'matrix_bridge_hookshot_github_command_prefix', 'new': 'matrix_bridge_hookshot_github_defaultOptions_commandPrefix'} + - {'old': 'matrix_bridge_hookshot_github_showIssueRoomLink', 'new': 'matrix_bridge_hookshot_github_defaultOptions_showIssueRoomLink'} + - {'old': 'matrix_bridge_hookshot_github_pr_diff', 'new': 'matrix_bridge_hookshot_github_defaultOptions_prDiff'} + - {'old': 'matrix_bridge_hookshot_github_including_labels', 'new': 'matrix_bridge_hookshot_github_defaultOptions_includingLabels'} + - {'old': 'matrix_bridge_hookshot_github_excluding_labels', 'new': 'matrix_bridge_hookshot_github_defaultOptions_excludingLabels'} + - {'old': 'matrix_bridge_hookshot_github_hotlink_prefix', 'new': 'matrix_bridge_hookshot_github_defaultOptions_hotlinkIssues_prefix'} + - {'old': 'matrix_bridge_hookshot_jira_secret', 'new': 'matrix_bridge_hookshot_jira_webhook_secret'} + - {'old': 'matrix_bridge_hookshot_jira_oauth_id', 'new': 'matrix_bridge_hookshot_jira_oauth_client_id'} + - {'old': 'matrix_bridge_hookshot_jira_oauth_secret', 'new': 'matrix_bridge_hookshot_jira_oauth_client_secret'} + - {'old': 'matrix_bridge_hookshot_jira_oauth_uri', 'new': 'matrix_bridge_hookshot_jira_oauth_redirect_uri'} + - {'old': 'matrix_bridge_hookshot_gitlab_secret', 'new': 'matrix_bridge_hookshot_gitlab_webhook_secret'} + - {'old': 'matrix_bridge_hookshot_ident', 'new': 'matrix_bridge_hookshot_identifier'} + - {'old': 'matrix_bridge_hookshot_queue_host', 'new': 'matrix_bridge_hookshot_cache_redis_host'} + - {'old': 'matrix_bridge_hookshot_queue_port', 'new': 'matrix_bridge_hookshot_cache_redis_port'} + - {'old': 'matrix_bridge_hookshot_experimental_encryption_enabled', 'new': 'matrix_bridge_hookshot_encryption_enabled'} + - {'old': 'matrix_bridge_hookshot_docker_image_name_prefix', 'new': 'matrix_bridge_hookshot_container_image_registry_prefix'} + - {'old': 'matrix_bridge_hookshot_provisioning_enabled', 'new': ''} + - {'old': 'matrix_bridge_hookshot_provisioning_port', 'new': ''} + - {'old': 'matrix_bridge_hookshot_provisioning_secret', 'new': ''} + - {'old': 'matrix_bridge_hookshot_provisioning_internal', 'new': ''} + - {'old': 'matrix_bridge_hookshot_provisioning_hostname', 'new': ''} + - {'old': 'matrix_bridge_hookshot_provisioning_endpoint', 'new': ''} + - {'old': 'matrix_bridge_hookshot_container_labels_provisioning_enabled', 'new': ''} + - {'old': 'matrix_bridge_hookshot_docker_image', 'new': 'matrix_bridge_hookshot_container_image'} + - {'old': 'matrix_bridge_hookshot_docker_image_force_pull', 'new': 'matrix_bridge_hookshot_container_image_force_pull'} + - {'old': 'matrix_bridge_hookshot_docker_image_registry_prefix', 'new': 'matrix_bridge_hookshot_container_image_registry_prefix'} + - {'old': 'matrix_bridge_hookshot_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_hookshot_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_hookshot_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_hookshot_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_hookshot_docker_src_files_path', 'new': 'matrix_bridge_hookshot_container_src_files_path'} + - {'old': 'matrix_bridge_hookshot_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required Hookshot settings not defined ansible.builtin.fail: @@ -59,57 +60,57 @@ You need to define a required configuration setting (`{{ item }}`). when: "lookup('vars', item, default='') == ''" with_items: - - "matrix_hookshot_appservice_token" - - "matrix_hookshot_homeserver_address" - - "matrix_hookshot_homeserver_token" - - "matrix_hookshot_container_network" + - "matrix_bridge_hookshot_appservice_token" + - "matrix_bridge_hookshot_homeserver_address" + - "matrix_bridge_hookshot_homeserver_token" + - "matrix_bridge_hookshot_container_network" - name: Fail if required GitHub settings not defined ansible.builtin.fail: msg: >- You need to define a required configuration setting (`{{ item }}`) to enable GitHub. - when: "matrix_hookshot_github_enabled and lookup('vars', item, default='') == ''" + when: "matrix_bridge_hookshot_github_enabled and lookup('vars', item, default='') == ''" with_items: - - "matrix_hookshot_github_auth_id" - - "matrix_hookshot_github_webhook_secret" + - "matrix_bridge_hookshot_github_auth_id" + - "matrix_bridge_hookshot_github_webhook_secret" - name: Fail if required GitHub OAuth settings not defined ansible.builtin.fail: msg: >- You need to define a required configuration setting (`{{ item }}`) to enable GitHub OAuth. - when: "matrix_hookshot_github_oauth_enabled and lookup('vars', item, default='') == ''" + when: "matrix_bridge_hookshot_github_oauth_enabled and lookup('vars', item, default='') == ''" with_items: - - "matrix_hookshot_github_oauth_client_id" - - "matrix_hookshot_github_oauth_client_secret" + - "matrix_bridge_hookshot_github_oauth_client_id" + - "matrix_bridge_hookshot_github_oauth_client_secret" - name: Fail if required Jira settings not defined ansible.builtin.fail: msg: >- You need to define a required configuration setting (`{{ item }}`) to enable Jira. - when: "matrix_hookshot_jira_enabled and lookup('vars', item, default='') == ''" + when: "matrix_bridge_hookshot_jira_enabled and lookup('vars', item, default='') == ''" with_items: - - "matrix_hookshot_jira_webhook_secret" + - "matrix_bridge_hookshot_jira_webhook_secret" - name: Fail if required Jira OAuth settings not defined ansible.builtin.fail: msg: >- You need to define a required configuration setting (`{{ item }}`) to enable Jira OAuth. - when: "matrix_hookshot_jira_oauth_enabled and lookup('vars', item, default='') == ''" + when: "matrix_bridge_hookshot_jira_oauth_enabled and lookup('vars', item, default='') == ''" with_items: - - "matrix_hookshot_jira_oauth_client_id" - - "matrix_hookshot_jira_oauth_client_secret" + - "matrix_bridge_hookshot_jira_oauth_client_id" + - "matrix_bridge_hookshot_jira_oauth_client_secret" - name: Fail if required Figma settings not defined ansible.builtin.fail: msg: >- - You need to define at least one Figma instance in `matrix_hookshot_figma_instances` to enable Figma. - when: "matrix_hookshot_figma_enabled and matrix_hookshot_figma_instances | length == 0" + You need to define at least one Figma instance in `matrix_bridge_hookshot_figma_instances` to enable Figma. + when: "matrix_bridge_hookshot_figma_enabled and matrix_bridge_hookshot_figma_instances | length == 0" - name: Fail if no Redis queue enabled when Hookshot encryption is enabled ansible.builtin.fail: msg: >- - You need to define a required configuration setting (`matrix_hookshot_cache_redis*`) to enable Hookshot encryption. - when: "matrix_hookshot_encryption_enabled and matrix_hookshot_cache_redisUri == ''" + You need to define a required configuration setting (`matrix_bridge_hookshot_cache_redis*`) to enable Hookshot encryption. + when: "matrix_bridge_hookshot_encryption_enabled and matrix_bridge_hookshot_cache_redisUri == ''" - name: (Deprecation) Catch and report old metrics usage ansible.builtin.fail: @@ -120,6 +121,6 @@ We now recommend exposing Hookshot metrics in another way, from another URL. Refer to the changelog for more details: https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md#2022-06-22 with_items: - - matrix_hookshot_proxy_metrics - - matrix_hookshot_metrics_endpoint + - matrix_bridge_hookshot_proxy_metrics + - matrix_bridge_hookshot_metrics_endpoint when: "lookup('ansible.builtin.varnames', ('^' + item + '$'), wantlist=True) | length > 0" diff --git a/roles/custom/matrix-bridge-hookshot/templates/config.yaml.j2 b/roles/custom/matrix-bridge-hookshot/templates/config.yaml.j2 index 4fe504d7e..58b6657d0 100644 --- a/roles/custom/matrix-bridge-hookshot/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-hookshot/templates/config.yaml.j2 @@ -3,94 +3,94 @@ bridge: # Basic homeserver configuration # domain: {{ matrix_domain }} - url: {{ matrix_hookshot_homeserver_address }} - mediaUrl: {{ matrix_hookshot_homeserver_address }} - port: {{ matrix_hookshot_appservice_port }} + url: {{ matrix_bridge_hookshot_homeserver_address }} + mediaUrl: {{ matrix_bridge_hookshot_homeserver_address }} + port: {{ matrix_bridge_hookshot_appservice_port }} bindAddress: 0.0.0.0 -{% if matrix_hookshot_github_enabled %} +{% if matrix_bridge_hookshot_github_enabled %} github: # (Optional) Configure this to enable GitHub support # auth: # Authentication for the GitHub App. # - id: {{ matrix_hookshot_github_auth_id | to_json }} - privateKeyFile: /data/{{ matrix_hookshot_github_private_key_file }} + id: {{ matrix_bridge_hookshot_github_auth_id | to_json }} + privateKeyFile: /data/{{ matrix_bridge_hookshot_github_private_key_file }} webhook: # Webhook settings for the GitHub app. # - secret: {{ matrix_hookshot_github_webhook_secret | to_json }} -{% if matrix_hookshot_github_oauth_enabled %} + secret: {{ matrix_bridge_hookshot_github_webhook_secret | to_json }} +{% if matrix_bridge_hookshot_github_oauth_enabled %} oauth: # (Optional) Settings for allowing users to sign in via OAuth. # - client_id: {{ matrix_hookshot_github_oauth_client_id | to_json }} - client_secret: {{ matrix_hookshot_github_oauth_client_secret | to_json }} - redirect_uri: {{ matrix_hookshot_github_oauth_redirect_uri | to_json }} + client_id: {{ matrix_bridge_hookshot_github_oauth_client_id | to_json }} + client_secret: {{ matrix_bridge_hookshot_github_oauth_client_secret | to_json }} + redirect_uri: {{ matrix_bridge_hookshot_github_oauth_redirect_uri | to_json }} {% endif %} defaultOptions: # (Optional) Default options for GitHub connections. # - ignoreHooks: {{ matrix_hookshot_github_defaultOptions_ignoreHooks | to_json }} - commandPrefix: {{ matrix_hookshot_github_defaultOptions_commandPrefix | to_json }} - showIssueRoomLink: {{ matrix_hookshot_github_defaultOptions_showIssueRoomLink | to_json }} - prDiff: {{ matrix_hookshot_github_defaultOptions_prDiff | to_json }} - includingLabels: {{ matrix_hookshot_github_defaultOptions_includingLabels | to_json }} - excludingLabels: {{ matrix_hookshot_github_defaultOptions_excludingLabels | to_json }} + ignoreHooks: {{ matrix_bridge_hookshot_github_defaultOptions_ignoreHooks | to_json }} + commandPrefix: {{ matrix_bridge_hookshot_github_defaultOptions_commandPrefix | to_json }} + showIssueRoomLink: {{ matrix_bridge_hookshot_github_defaultOptions_showIssueRoomLink | to_json }} + prDiff: {{ matrix_bridge_hookshot_github_defaultOptions_prDiff | to_json }} + includingLabels: {{ matrix_bridge_hookshot_github_defaultOptions_includingLabels | to_json }} + excludingLabels: {{ matrix_bridge_hookshot_github_defaultOptions_excludingLabels | to_json }} hotlinkIssues: - prefix: {{ matrix_hookshot_github_defaultOptions_hotlinkIssues_prefix | to_json }} + prefix: {{ matrix_bridge_hookshot_github_defaultOptions_hotlinkIssues_prefix | to_json }} {% endif %} -{% if matrix_hookshot_gitlab_enabled %} +{% if matrix_bridge_hookshot_gitlab_enabled %} gitlab: # (Optional) Configure this to enable GitLab support # - instances: {{ matrix_hookshot_gitlab_instances | to_json }} + instances: {{ matrix_bridge_hookshot_gitlab_instances | to_json }} webhook: - secret: {{ matrix_hookshot_gitlab_webhook_secret | to_json }} - publicUrl: {{ matrix_hookshot_gitlab_webhook_publicUrl | to_json }} + secret: {{ matrix_bridge_hookshot_gitlab_webhook_secret | to_json }} + publicUrl: {{ matrix_bridge_hookshot_gitlab_webhook_publicUrl | to_json }} {% endif %} -{% if matrix_hookshot_figma_enabled %} +{% if matrix_bridge_hookshot_figma_enabled %} figma: # (Optional) Configure this to enable Figma support # - publicUrl: {{ matrix_hookshot_figma_publicUrl | to_json }} - instances: {{ matrix_hookshot_figma_instances | to_json }} + publicUrl: {{ matrix_bridge_hookshot_figma_publicUrl | to_json }} + instances: {{ matrix_bridge_hookshot_figma_instances | to_json }} {% endif %} -{% if matrix_hookshot_jira_enabled %} +{% if matrix_bridge_hookshot_jira_enabled %} jira: # (Optional) Configure this to enable Jira support # webhook: - secret: {{ matrix_hookshot_jira_webhook_secret | to_json }} -{% if matrix_hookshot_jira_oauth_enabled %} + secret: {{ matrix_bridge_hookshot_jira_webhook_secret | to_json }} +{% if matrix_bridge_hookshot_jira_oauth_enabled %} oauth: - client_id: {{ matrix_hookshot_jira_oauth_client_id | to_json }} - client_secret: {{ matrix_hookshot_jira_oauth_client_secret | to_json }} - redirect_uri: {{ matrix_hookshot_jira_oauth_redirect_uri | to_json }} + client_id: {{ matrix_bridge_hookshot_jira_oauth_client_id | to_json }} + client_secret: {{ matrix_bridge_hookshot_jira_oauth_client_secret | to_json }} + redirect_uri: {{ matrix_bridge_hookshot_jira_oauth_redirect_uri | to_json }} {% endif %} {% endif %} -{% if matrix_hookshot_generic_enabled %} +{% if matrix_bridge_hookshot_generic_enabled %} generic: # (Optional) Support for generic webhook events. `allowJsTransformationFunctions` will allow users to write short transformation snippets in code, and thus is unsafe in untrusted environments # - enabled: {{ matrix_hookshot_generic_enabled | to_json }} - outbound: {{ matrix_hookshot_generic_outbound | to_json }} - enableHttpGet: {{ matrix_hookshot_generic_enableHttpGet | to_json }} - urlPrefix: {{ matrix_hookshot_generic_urlPrefix | to_json }} - userIdPrefix: {{ matrix_hookshot_generic_userIdPrefix | to_json }} - allowJsTransformationFunctions: {{ matrix_hookshot_generic_allowJsTransformationFunctions | to_json }} - waitForComplete: {{ matrix_hookshot_generic_waitForComplete | to_json }} - sendExpiryNotice: {{ matrix_hookshot_generic_sendExpiryNotice | to_json }} - requireExpiryTime: {{ matrix_hookshot_generic_requireExpiryTime | to_json }} - maxExpiryTime: {{ matrix_hookshot_generic_maxExpiryTime | to_json }} -{% endif %} -{% if matrix_hookshot_feeds_enabled %} + enabled: {{ matrix_bridge_hookshot_generic_enabled | to_json }} + outbound: {{ matrix_bridge_hookshot_generic_outbound | to_json }} + enableHttpGet: {{ matrix_bridge_hookshot_generic_enableHttpGet | to_json }} + urlPrefix: {{ matrix_bridge_hookshot_generic_urlPrefix | to_json }} + userIdPrefix: {{ matrix_bridge_hookshot_generic_userIdPrefix | to_json }} + allowJsTransformationFunctions: {{ matrix_bridge_hookshot_generic_allowJsTransformationFunctions | to_json }} + waitForComplete: {{ matrix_bridge_hookshot_generic_waitForComplete | to_json }} + sendExpiryNotice: {{ matrix_bridge_hookshot_generic_sendExpiryNotice | to_json }} + requireExpiryTime: {{ matrix_bridge_hookshot_generic_requireExpiryTime | to_json }} + maxExpiryTime: {{ matrix_bridge_hookshot_generic_maxExpiryTime | to_json }} +{% endif %} +{% if matrix_bridge_hookshot_feeds_enabled %} feeds: # (Optional) Configure this to enable RSS/Atom feed support # - enabled: {{ matrix_hookshot_feeds_enabled | to_json }} - pollIntervalSeconds: {{ matrix_hookshot_feeds_pollIntervalSeconds | to_json }} - pollTimeoutSeconds: {{ matrix_hookshot_feeds_pollTimeoutSeconds | to_json }} + enabled: {{ matrix_bridge_hookshot_feeds_enabled | to_json }} + pollIntervalSeconds: {{ matrix_bridge_hookshot_feeds_pollIntervalSeconds | to_json }} + pollTimeoutSeconds: {{ matrix_bridge_hookshot_feeds_pollTimeoutSeconds | to_json }} {% endif %} passFile: # A passkey used to encrypt tokens stored inside the bridge. @@ -100,62 +100,62 @@ passFile: bot: # (Optional) Define profile information for the bot user # - displayname: {{ matrix_hookshot_bot_displayname | to_json(ensure_ascii=False) }} - avatar: {{ matrix_hookshot_bot_avatar | to_json }} + displayname: {{ matrix_bridge_hookshot_bot_displayname | to_json(ensure_ascii=False) }} + avatar: {{ matrix_bridge_hookshot_bot_avatar | to_json }} metrics: # (Optional) Prometheus metrics support # - enabled: {{ matrix_hookshot_metrics_enabled | to_json }} -{% if matrix_hookshot_cache_redisUri %} + enabled: {{ matrix_bridge_hookshot_metrics_enabled | to_json }} +{% if matrix_bridge_hookshot_cache_redisUri %} cache: - redisUri: {{ matrix_hookshot_cache_redisUri | to_json }} + redisUri: {{ matrix_bridge_hookshot_cache_redisUri | to_json }} {% endif %} -{% if matrix_hookshot_encryption_enabled %} +{% if matrix_bridge_hookshot_encryption_enabled %} encryption: storagePath: /data/encryption {% endif %} logging: # (Optional) Logging settings. You can have a severity debug,info,warn,error # - level: {{ matrix_hookshot_logging_level | to_json }} -{% if matrix_hookshot_widgets_enabled %} + level: {{ matrix_bridge_hookshot_logging_level | to_json }} +{% if matrix_bridge_hookshot_widgets_enabled %} widgets: # (Optional) EXPERIMENTAL support for complimentary widgets # - addToAdminRooms: {{ matrix_hookshot_widgets_addToAdminRooms | to_json }} -{% if matrix_hookshot_widgets_roomSetupWidget_enabled %} + addToAdminRooms: {{ matrix_bridge_hookshot_widgets_addToAdminRooms | to_json }} +{% if matrix_bridge_hookshot_widgets_roomSetupWidget_enabled %} roomSetupWidget: - addOnInvite: {{ matrix_hookshot_widgets_roomSetupWidget_addOnInvite | to_json }} + addOnInvite: {{ matrix_bridge_hookshot_widgets_roomSetupWidget_addOnInvite | to_json }} {% endif %} -{% if not matrix_hookshot_widgets_disallowedIpRanges is in [None, ''] %} - disallowedIpRanges: {{ matrix_hookshot_widgets_disallowedIpRanges | to_json }} +{% if not matrix_bridge_hookshot_widgets_disallowedIpRanges is in [None, ''] %} + disallowedIpRanges: {{ matrix_bridge_hookshot_widgets_disallowedIpRanges | to_json }} {% endif %} - publicUrl: {{ matrix_hookshot_widgets_publicUrl | to_json }} + publicUrl: {{ matrix_bridge_hookshot_widgets_publicUrl | to_json }} branding: - widgetTitle: {{ matrix_hookshot_widgets_branding_widgetTitle | to_json }} + widgetTitle: {{ matrix_bridge_hookshot_widgets_branding_widgetTitle | to_json }} {% endif %} -{% if matrix_hookshot_permissions %} -permissions: {{ matrix_hookshot_permissions | to_json }} +{% if matrix_bridge_hookshot_permissions %} +permissions: {{ matrix_bridge_hookshot_permissions | to_json }} {% endif %} -connections: {{ matrix_hookshot_connections | to_json }} +connections: {{ matrix_bridge_hookshot_connections | to_json }} listeners: # (Optional) HTTP Listener configuration. # Bind resource endpoints to ports and addresses. # 'resources' may be any of webhooks, widgets, metrics # {# always enabled since all services need it #} - - port: {{ matrix_hookshot_webhook_port }} + - port: {{ matrix_bridge_hookshot_webhook_port }} bindAddress: 0.0.0.0 resources: - webhooks -{% if matrix_hookshot_metrics_enabled %} - - port: {{ matrix_hookshot_metrics_port }} +{% if matrix_bridge_hookshot_metrics_enabled %} + - port: {{ matrix_bridge_hookshot_metrics_port }} bindAddress: 0.0.0.0 resources: - metrics {% endif %} -{% if matrix_hookshot_widgets_enabled %} - - port: {{ matrix_hookshot_widgets_port }} +{% if matrix_bridge_hookshot_widgets_enabled %} + - port: {{ matrix_bridge_hookshot_widgets_port }} bindAddress: 0.0.0.0 resources: - widgets diff --git a/roles/custom/matrix-bridge-hookshot/templates/labels.j2 b/roles/custom/matrix-bridge-hookshot/templates/labels.j2 index 68dfaa906..5ee8dbf7b 100644 --- a/roles/custom/matrix-bridge-hookshot/templates/labels.j2 +++ b/roles/custom/matrix-bridge-hookshot/templates/labels.j2 @@ -4,41 +4,41 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_hookshot_container_labels_traefik_enabled %} +{% if matrix_bridge_hookshot_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_hookshot_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_hookshot_container_labels_traefik_docker_network }} +{% if matrix_bridge_hookshot_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_hookshot_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.matrix-hookshot-webhooks.loadbalancer.server.port={{ matrix_hookshot_webhook_port }} -traefik.http.services.matrix-hookshot-appservice.loadbalancer.server.port={{ matrix_hookshot_appservice_port }} -traefik.http.services.matrix-hookshot-widgets.loadbalancer.server.port={{ matrix_hookshot_widgets_port }} -traefik.http.services.matrix-hookshot-metrics.loadbalancer.server.port={{ matrix_hookshot_metrics_port }} +traefik.http.services.matrix-hookshot-webhooks.loadbalancer.server.port={{ matrix_bridge_hookshot_webhook_port }} +traefik.http.services.matrix-hookshot-appservice.loadbalancer.server.port={{ matrix_bridge_hookshot_appservice_port }} +traefik.http.services.matrix-hookshot-widgets.loadbalancer.server.port={{ matrix_bridge_hookshot_widgets_port }} +traefik.http.services.matrix-hookshot-metrics.loadbalancer.server.port={{ matrix_bridge_hookshot_metrics_port }} -{% if matrix_hookshot_container_labels_webhooks_enabled %} +{% if matrix_bridge_hookshot_container_labels_webhooks_enabled %} ############################################################ # # # Webhooks # # # ############################################################ -traefik.http.middlewares.matrix-hookshot-webhooks-strip-prefix.stripprefix.prefixes={{ matrix_hookshot_webhook_endpoint }} +traefik.http.middlewares.matrix-hookshot-webhooks-strip-prefix.stripprefix.prefixes={{ matrix_bridge_hookshot_webhook_endpoint }} -traefik.http.routers.matrix-hookshot-webhooks.rule={{ matrix_hookshot_container_labels_webhooks_traefik_rule }} +traefik.http.routers.matrix-hookshot-webhooks.rule={{ matrix_bridge_hookshot_container_labels_webhooks_traefik_rule }} traefik.http.routers.matrix-hookshot-webhooks.middlewares=matrix-hookshot-webhooks-strip-prefix -{% if matrix_hookshot_container_labels_webhooks_traefik_priority | int > 0 %} -traefik.http.routers.matrix-hookshot-webhooks.priority={{ matrix_hookshot_container_labels_webhooks_traefik_priority }} +{% if matrix_bridge_hookshot_container_labels_webhooks_traefik_priority | int > 0 %} +traefik.http.routers.matrix-hookshot-webhooks.priority={{ matrix_bridge_hookshot_container_labels_webhooks_traefik_priority }} {% endif %} traefik.http.routers.matrix-hookshot-webhooks.service=matrix-hookshot-webhooks -traefik.http.routers.matrix-hookshot-webhooks.entrypoints={{ matrix_hookshot_container_labels_webhooks_traefik_entrypoints }} +traefik.http.routers.matrix-hookshot-webhooks.entrypoints={{ matrix_bridge_hookshot_container_labels_webhooks_traefik_entrypoints }} -traefik.http.routers.matrix-hookshot-webhooks.tls={{ matrix_hookshot_container_labels_webhooks_traefik_tls | to_json }} -{% if matrix_hookshot_container_labels_webhooks_traefik_tls %} -traefik.http.routers.matrix-hookshot-webhooks.tls.certResolver={{ matrix_hookshot_container_labels_webhooks_traefik_tls_certResolver }} +traefik.http.routers.matrix-hookshot-webhooks.tls={{ matrix_bridge_hookshot_container_labels_webhooks_traefik_tls | to_json }} +{% if matrix_bridge_hookshot_container_labels_webhooks_traefik_tls %} +traefik.http.routers.matrix-hookshot-webhooks.tls.certResolver={{ matrix_bridge_hookshot_container_labels_webhooks_traefik_tls_certResolver }} {% endif %} ############################################################ @@ -49,28 +49,28 @@ traefik.http.routers.matrix-hookshot-webhooks.tls.certResolver={{ matrix_hooksho {% endif %} -{% if matrix_hookshot_container_labels_appservice_enabled %} +{% if matrix_bridge_hookshot_container_labels_appservice_enabled %} ############################################################ # # # Appservice # # # ############################################################ -traefik.http.middlewares.matrix-hookshot-appservice-strip-prefix.stripprefix.prefixes={{ matrix_hookshot_appservice_endpoint }} +traefik.http.middlewares.matrix-hookshot-appservice-strip-prefix.stripprefix.prefixes={{ matrix_bridge_hookshot_appservice_endpoint }} -traefik.http.routers.matrix-hookshot-appservice.rule={{ matrix_hookshot_container_labels_appservice_traefik_rule }} +traefik.http.routers.matrix-hookshot-appservice.rule={{ matrix_bridge_hookshot_container_labels_appservice_traefik_rule }} traefik.http.routers.matrix-hookshot-appservice.middlewares=matrix-hookshot-appservice-strip-prefix -{% if matrix_hookshot_container_labels_appservice_traefik_priority | int > 0 %} -traefik.http.routers.matrix-hookshot-appservice.priority={{ matrix_hookshot_container_labels_appservice_traefik_priority }} +{% if matrix_bridge_hookshot_container_labels_appservice_traefik_priority | int > 0 %} +traefik.http.routers.matrix-hookshot-appservice.priority={{ matrix_bridge_hookshot_container_labels_appservice_traefik_priority }} {% endif %} traefik.http.routers.matrix-hookshot-appservice.service=matrix-hookshot-appservice -traefik.http.routers.matrix-hookshot-appservice.entrypoints={{ matrix_hookshot_container_labels_appservice_traefik_entrypoints }} +traefik.http.routers.matrix-hookshot-appservice.entrypoints={{ matrix_bridge_hookshot_container_labels_appservice_traefik_entrypoints }} -traefik.http.routers.matrix-hookshot-appservice.tls={{ matrix_hookshot_container_labels_appservice_traefik_tls | to_json }} -{% if matrix_hookshot_container_labels_appservice_traefik_tls %} -traefik.http.routers.matrix-hookshot-appservice.tls.certResolver={{ matrix_hookshot_container_labels_appservice_traefik_tls_certResolver }} +traefik.http.routers.matrix-hookshot-appservice.tls={{ matrix_bridge_hookshot_container_labels_appservice_traefik_tls | to_json }} +{% if matrix_bridge_hookshot_container_labels_appservice_traefik_tls %} +traefik.http.routers.matrix-hookshot-appservice.tls.certResolver={{ matrix_bridge_hookshot_container_labels_appservice_traefik_tls_certResolver }} {% endif %} ############################################################ @@ -81,7 +81,7 @@ traefik.http.routers.matrix-hookshot-appservice.tls.certResolver={{ matrix_hooks {% endif %} -{% if matrix_hookshot_container_labels_widgets_enabled %} +{% if matrix_bridge_hookshot_container_labels_widgets_enabled %} ############################################################ # # # Widgets # @@ -90,24 +90,24 @@ traefik.http.routers.matrix-hookshot-appservice.tls.certResolver={{ matrix_hooks # Redirect `{PREFIX}/widgetapi/v1/static` to `{PREFIX}/widgetapi/v1/static/`. # Hookshot does it too, but does not obey the prefix, which leads people elsewhere. -traefik.http.middlewares.matrix-hookshot-widgets-slashless-redirect.redirectregex.regex=({{ matrix_hookshot_widgets_endpoint | quote }}/v1/static)$ +traefik.http.middlewares.matrix-hookshot-widgets-slashless-redirect.redirectregex.regex=({{ matrix_bridge_hookshot_widgets_endpoint | quote }}/v1/static)$ traefik.http.middlewares.matrix-hookshot-widgets-slashless-redirect.redirectregex.replacement=${1}/ -traefik.http.middlewares.matrix-hookshot-widgets-strip-prefix.stripprefix.prefixes={{ matrix_hookshot_public_endpoint }} +traefik.http.middlewares.matrix-hookshot-widgets-strip-prefix.stripprefix.prefixes={{ matrix_bridge_hookshot_public_endpoint }} -traefik.http.routers.matrix-hookshot-widgets.rule={{ matrix_hookshot_container_labels_widgets_traefik_rule }} +traefik.http.routers.matrix-hookshot-widgets.rule={{ matrix_bridge_hookshot_container_labels_widgets_traefik_rule }} traefik.http.routers.matrix-hookshot-widgets.middlewares=matrix-hookshot-widgets-slashless-redirect,matrix-hookshot-widgets-strip-prefix -{% if matrix_hookshot_container_labels_widgets_traefik_priority | int > 0 %} -traefik.http.routers.matrix-hookshot-widgets.priority={{ matrix_hookshot_container_labels_widgets_traefik_priority }} +{% if matrix_bridge_hookshot_container_labels_widgets_traefik_priority | int > 0 %} +traefik.http.routers.matrix-hookshot-widgets.priority={{ matrix_bridge_hookshot_container_labels_widgets_traefik_priority }} {% endif %} traefik.http.routers.matrix-hookshot-widgets.service=matrix-hookshot-widgets -traefik.http.routers.matrix-hookshot-widgets.entrypoints={{ matrix_hookshot_container_labels_widgets_traefik_entrypoints }} +traefik.http.routers.matrix-hookshot-widgets.entrypoints={{ matrix_bridge_hookshot_container_labels_widgets_traefik_entrypoints }} -traefik.http.routers.matrix-hookshot-widgets.tls={{ matrix_hookshot_container_labels_widgets_traefik_tls | to_json }} -{% if matrix_hookshot_container_labels_widgets_traefik_tls %} -traefik.http.routers.matrix-hookshot-widgets.tls.certResolver={{ matrix_hookshot_container_labels_widgets_traefik_tls_certResolver }} +traefik.http.routers.matrix-hookshot-widgets.tls={{ matrix_bridge_hookshot_container_labels_widgets_traefik_tls | to_json }} +{% if matrix_bridge_hookshot_container_labels_widgets_traefik_tls %} +traefik.http.routers.matrix-hookshot-widgets.tls.certResolver={{ matrix_bridge_hookshot_container_labels_widgets_traefik_tls_certResolver }} {% endif %} ############################################################ @@ -118,7 +118,7 @@ traefik.http.routers.matrix-hookshot-widgets.tls.certResolver={{ matrix_hookshot {% endif %} -{% if matrix_hookshot_container_labels_metrics_enabled %} +{% if matrix_bridge_hookshot_container_labels_metrics_enabled %} ############################################################ # # # Metrics # @@ -128,24 +128,24 @@ traefik.http.routers.matrix-hookshot-widgets.tls.certResolver={{ matrix_hookshot {% set metricsMiddlewares = ['matrix-hookshot-metrics-replace-path'] %} traefik.http.middlewares.matrix-hookshot-metrics-replace-path.replacepath.path=/metrics -{% if matrix_hookshot_container_labels_metrics_middleware_basic_auth_enabled %} +{% if matrix_bridge_hookshot_container_labels_metrics_middleware_basic_auth_enabled %} {% set metricsMiddlewares = metricsMiddlewares + ['matrix-hookshot-metrics-basic-auth'] %} -traefik.http.middlewares.matrix-hookshot-metrics-basic-auth.basicauth.users={{ matrix_hookshot_container_labels_metrics_middleware_basic_auth_users }} +traefik.http.middlewares.matrix-hookshot-metrics-basic-auth.basicauth.users={{ matrix_bridge_hookshot_container_labels_metrics_middleware_basic_auth_users }} {% endif %} -traefik.http.routers.matrix-hookshot-metrics.rule={{ matrix_hookshot_container_labels_metrics_traefik_rule }} +traefik.http.routers.matrix-hookshot-metrics.rule={{ matrix_bridge_hookshot_container_labels_metrics_traefik_rule }} traefik.http.routers.matrix-hookshot-metrics.middlewares={{ metricsMiddlewares | join(',') }} -{% if matrix_hookshot_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.matrix-hookshot-metrics.priority={{ matrix_hookshot_container_labels_metrics_traefik_priority }} +{% if matrix_bridge_hookshot_container_labels_metrics_traefik_priority | int > 0 %} +traefik.http.routers.matrix-hookshot-metrics.priority={{ matrix_bridge_hookshot_container_labels_metrics_traefik_priority }} {% endif %} traefik.http.routers.matrix-hookshot-metrics.service=matrix-hookshot-metrics -traefik.http.routers.matrix-hookshot-metrics.entrypoints={{ matrix_hookshot_container_labels_metrics_traefik_entrypoints }} +traefik.http.routers.matrix-hookshot-metrics.entrypoints={{ matrix_bridge_hookshot_container_labels_metrics_traefik_entrypoints }} -traefik.http.routers.matrix-hookshot-metrics.tls={{ matrix_hookshot_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_hookshot_container_labels_metrics_traefik_tls %} -traefik.http.routers.matrix-hookshot-metrics.tls.certResolver={{ matrix_hookshot_container_labels_metrics_traefik_tls_certResolver }} +traefik.http.routers.matrix-hookshot-metrics.tls={{ matrix_bridge_hookshot_container_labels_metrics_traefik_tls | to_json }} +{% if matrix_bridge_hookshot_container_labels_metrics_traefik_tls %} +traefik.http.routers.matrix-hookshot-metrics.tls.certResolver={{ matrix_bridge_hookshot_container_labels_metrics_traefik_tls_certResolver }} {% endif %} ############################################################ @@ -158,4 +158,4 @@ traefik.http.routers.matrix-hookshot-metrics.tls.certResolver={{ matrix_hookshot {% endif %} -{{ matrix_hookshot_container_labels_additional_labels }} +{{ matrix_bridge_hookshot_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-hookshot/templates/registration.yml.j2 b/roles/custom/matrix-bridge-hookshot/templates/registration.yml.j2 index 92eda8e4d..2b1fa0574 100644 --- a/roles/custom/matrix-bridge-hookshot/templates/registration.yml.j2 +++ b/roles/custom/matrix-bridge-hookshot/templates/registration.yml.j2 @@ -1,35 +1,35 @@ #jinja2: lstrip_blocks: True id: matrix-hookshot # This can be anything, but must be unique within your homeserver -as_token: {{ matrix_hookshot_appservice_token|to_json }} # This again can be a random string -hs_token: {{ matrix_hookshot_homeserver_token|to_json }} # ..as can this +as_token: {{ matrix_bridge_hookshot_appservice_token|to_json }} # This again can be a random string +hs_token: {{ matrix_bridge_hookshot_homeserver_token|to_json }} # ..as can this namespaces: rooms: [] users: -{% if matrix_hookshot_github_enabled %} +{% if matrix_bridge_hookshot_github_enabled %} - regex: "@_github_.*:{{ matrix_domain }}" exclusive: true {% endif %} -{% if matrix_hookshot_gitlab_enabled %} +{% if matrix_bridge_hookshot_gitlab_enabled %} - regex: "@_gitlab_.*:{{ matrix_domain }}" # Where foobar is your homeserver's domain exclusive: true {% endif %} -{% if matrix_hookshot_jira_enabled %} +{% if matrix_bridge_hookshot_jira_enabled %} - regex: "@_jira_.*:{{ matrix_domain }}" # Where foobar is your homeserver's domain exclusive: true {% endif %} -{% if matrix_hookshot_generic_enabled %} - - regex: "@{{ matrix_hookshot_generic_userIdPrefix }}.*:{{ matrix_domain }}" # Where foobar is your homeserver's domain // depending on userIdPrefix setting in conf +{% if matrix_bridge_hookshot_generic_enabled %} + - regex: "@{{ matrix_bridge_hookshot_generic_userIdPrefix }}.*:{{ matrix_domain }}" # Where foobar is your homeserver's domain // depending on userIdPrefix setting in conf exclusive: true {% endif %} aliases: - regex: "#github_.+:{{ matrix_domain }}" exclusive: true -sender_localpart: {{ matrix_hookshot_bot_localpart | to_json }} -url: "http://{{ matrix_hookshot_container_url }}:{{ matrix_hookshot_appservice_port }}" # This should match the bridge.port in your config file +sender_localpart: {{ matrix_bridge_hookshot_bot_localpart | to_json }} +url: "http://{{ matrix_bridge_hookshot_container_url }}:{{ matrix_bridge_hookshot_appservice_port }}" # This should match the bridge.port in your config file rate_limited: false -{% if matrix_hookshot_encryption_enabled %} +{% if matrix_bridge_hookshot_encryption_enabled %} de.sorunome.msc2409.push_ephemeral: true push_ephemeral: true receive_ephemeral: true diff --git a/roles/custom/matrix-bridge-hookshot/templates/systemd/matrix-hookshot.service.j2 b/roles/custom/matrix-bridge-hookshot/templates/systemd/matrix-hookshot.service.j2 index 3e56816ba..cea9184eb 100644 --- a/roles/custom/matrix-bridge-hookshot/templates/systemd/matrix-hookshot.service.j2 +++ b/roles/custom/matrix-bridge-hookshot/templates/systemd/matrix-hookshot.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=A bridge between Matrix and multiple project management services, such as GitHub, GitLab and JIRA. -{% for service in matrix_hookshot_systemd_required_services_list %} +{% for service in matrix_bridge_hookshot_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_hookshot_systemd_wanted_services_list %} +{% for service in matrix_bridge_hookshot_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -13,35 +13,37 @@ DefaultDependencies=no [Service] Type=simple Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_hookshot_identifier }} -ExecStartPre=-{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_hookshot_identifier }} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create --rm --name {{ matrix_hookshot_identifier }} \ +ExecStartPre=-{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_bridge_hookshot_identifier }} +ExecStartPre=-{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_bridge_hookshot_identifier }} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create --rm --name {{ matrix_bridge_hookshot_identifier }} \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_hookshot_container_network }} \ - --mount type=bind,src={{ matrix_hookshot_base_path }},dst=/data \ - --label-file={{ matrix_hookshot_base_path }}/labels \ - {% for port in matrix_hookshot_container_http_host_bind_ports %} + --network={{ matrix_bridge_hookshot_container_network }} \ + --mount type=bind,src={{ matrix_bridge_hookshot_base_path }},dst=/data \ + --label-file={{ matrix_bridge_hookshot_base_path }}/labels \ + {% for port in matrix_bridge_hookshot_container_http_host_bind_ports %} -p {{ port }} \ {% endfor %} - {% for arg in matrix_hookshot_container_extra_arguments %} + {% for arg in matrix_bridge_hookshot_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_hookshot_container_image }} + {{ matrix_bridge_hookshot_container_image }} -{% for network in matrix_hookshot_container_additional_networks %} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_hookshot_identifier }} +{% if matrix_bridge_hookshot_container_network != 'host' %} +{% for network in matrix_bridge_hookshot_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_bridge_hookshot_identifier }} {% endfor %} +{% endif %} -ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_hookshot_identifier }} +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_bridge_hookshot_identifier }} -ExecStop=-{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_hookshot_identifier }} -ExecStop=-{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_hookshot_identifier }} +ExecStop=-{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_bridge_hookshot_identifier }} +ExecStop=-{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_bridge_hookshot_identifier }} Restart=always RestartSec=30 -SyslogIdentifier={{ matrix_hookshot_identifier }} +SyslogIdentifier={{ matrix_bridge_hookshot_identifier }} [Install] WantedBy=multi-user.target diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-bluesky/defaults/main.yml index 12dd8e639..2f141e943 100644 --- a/roles/custom/matrix-bridge-mautrix-bluesky/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-bluesky/defaults/main.yml @@ -7,210 +7,204 @@ # mautrix-bluesky is a Matrix <-> Bluesky bridge # Project source code URL: https://github.com/mautrix/bluesky -matrix_mautrix_bluesky_enabled: true +matrix_bridge_mautrix_bluesky_enabled: true -matrix_mautrix_bluesky_container_image_self_build: false -matrix_mautrix_bluesky_container_image_self_build_repo: "https://github.com/mautrix/bluesky.git" -matrix_mautrix_bluesky_container_image_self_build_repo_version: "{{ 'master' if matrix_mautrix_bluesky_version == 'latest' else matrix_mautrix_bluesky_version }}" +matrix_bridge_mautrix_bluesky_container_image_self_build: false +matrix_bridge_mautrix_bluesky_container_image_self_build_repo: "https://github.com/mautrix/bluesky.git" +matrix_bridge_mautrix_bluesky_container_image_self_build_repo_version: "{{ 'master' if matrix_bridge_mautrix_bluesky_version == 'latest' else matrix_bridge_mautrix_bluesky_version }}" # renovate: datasource=docker depName=dock.mau.dev/mautrix/bluesky -matrix_mautrix_bluesky_version: v0.2510.0 +matrix_bridge_mautrix_bluesky_version: v0.2510.0 # See: https://mau.dev/tulir/mautrix-bluesky/container_registry -matrix_mautrix_bluesky_container_image: "{{ matrix_mautrix_bluesky_container_image_registry_prefix }}mautrix/bluesky:{{ matrix_mautrix_bluesky_version }}" -matrix_mautrix_bluesky_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_bluesky_container_image_self_build else matrix_mautrix_bluesky_container_image_registry_prefix_upstream }}" -matrix_mautrix_bluesky_container_image_registry_prefix_upstream: "{{ matrix_mautrix_bluesky_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_bluesky_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_bluesky_container_image_force_pull: "{{ matrix_mautrix_bluesky_container_image.endswith(':latest') }}" - -matrix_mautrix_bluesky_base_path: "{{ matrix_base_data_path }}/mautrix-bluesky" -matrix_mautrix_bluesky_config_path: "{{ matrix_mautrix_bluesky_base_path }}/config" -matrix_mautrix_bluesky_data_path: "{{ matrix_mautrix_bluesky_base_path }}/data" -matrix_mautrix_bluesky_container_src_files_path: "{{ matrix_mautrix_bluesky_base_path }}/docker-src" - -matrix_mautrix_bluesky_homeserver_address: "" +matrix_bridge_mautrix_bluesky_container_image: "{{ matrix_bridge_mautrix_bluesky_container_image_registry_prefix }}mautrix/bluesky:{{ matrix_bridge_mautrix_bluesky_version }}" +matrix_bridge_mautrix_bluesky_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_bluesky_container_image_self_build else matrix_bridge_mautrix_bluesky_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_bluesky_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_bluesky_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_bluesky_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bridge_mautrix_bluesky_base_path: "{{ matrix_base_data_path }}/mautrix-bluesky" +matrix_bridge_mautrix_bluesky_config_path: "{{ matrix_bridge_mautrix_bluesky_base_path }}/config" +matrix_bridge_mautrix_bluesky_data_path: "{{ matrix_bridge_mautrix_bluesky_base_path }}/data" +matrix_bridge_mautrix_bluesky_container_src_files_path: "{{ matrix_bridge_mautrix_bluesky_base_path }}/docker-src" + +matrix_bridge_mautrix_bluesky_homeserver_address: "" # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_mautrix_bluesky_homeserver_async_media: false -matrix_mautrix_bluesky_homeserver_domain: '{{ matrix_domain }}' -matrix_mautrix_bluesky_appservice_address: 'http://matrix-mautrix-bluesky:29340' +matrix_bridge_mautrix_bluesky_homeserver_async_media: false +matrix_bridge_mautrix_bluesky_homeserver_domain: '{{ matrix_domain }}' +matrix_bridge_mautrix_bluesky_appservice_address: 'http://matrix-mautrix-bluesky:29340' -matrix_mautrix_bluesky_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" -matrix_mautrix_bluesky_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" +matrix_bridge_mautrix_bluesky_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_bluesky_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" -# A public address that external services can use to reach this appservice. -matrix_mautrix_bluesky_appservice_public_address: '' +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_bluesky_appservice_public_address`). +matrix_bridge_mautrix_bluesky_scheme: https + +# A public address that external services can use to reach this appservice (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_bluesky_appservice_public_address: "{{ (matrix_bridge_mautrix_bluesky_scheme + '://' + matrix_bridge_mautrix_bluesky_exposure_hostname + matrix_bridge_mautrix_bluesky_exposure_path_prefix) if matrix_bridge_mautrix_bluesky_exposure_enabled else '' }}" # Displayname template for Bluesky users. # {{ .DisplayName }} is replaced with the display name of the Bluesky user. # {{ .Username }} is replaced with the username of the Bluesky user. -matrix_mautrix_bluesky_network_displayname_template: "{% raw %}{{ .DisplayName }}{% endraw %} (Bluesky)" +matrix_bridge_mautrix_bluesky_network_displayname_template: "{% raw %}{{ .DisplayName }}{% endraw %} (Bluesky)" -matrix_mautrix_bluesky_bridge_command_prefix: "!bs" +matrix_bridge_mautrix_bluesky_bridge_command_prefix: "!bs" -matrix_mautrix_bluesky_bridge_permissions: | +matrix_bridge_mautrix_bluesky_bridge_permissions: | {{ - {matrix_mautrix_bluesky_homeserver_domain: 'user'} + {matrix_bridge_mautrix_bluesky_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} -matrix_mautrix_bluesky_container_network: "" +matrix_bridge_mautrix_bluesky_container_network: "" -matrix_mautrix_bluesky_container_additional_networks: "{{ matrix_mautrix_bluesky_container_additional_networks_auto + matrix_mautrix_bluesky_container_additional_networks_custom }}" -matrix_mautrix_bluesky_container_additional_networks_auto: [] -matrix_mautrix_bluesky_container_additional_networks_custom: [] +matrix_bridge_mautrix_bluesky_container_additional_networks: "{{ matrix_bridge_mautrix_bluesky_container_additional_networks_auto + matrix_bridge_mautrix_bluesky_container_additional_networks_custom }}" +matrix_bridge_mautrix_bluesky_container_additional_networks_auto: [] +matrix_bridge_mautrix_bluesky_container_additional_networks_custom: [] -# matrix_mautrix_bluesky_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_mautrix_bluesky_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_bluesky_container_labels_additional_labels`. -matrix_mautrix_bluesky_container_labels_traefik_enabled: true -matrix_mautrix_bluesky_container_labels_traefik_docker_network: "{{ matrix_mautrix_bluesky_container_network }}" -matrix_mautrix_bluesky_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_bluesky_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose mautrix-instagram's metrics -matrix_mautrix_bluesky_container_labels_metrics_enabled: "{{ matrix_mautrix_bluesky_metrics_enabled and matrix_mautrix_bluesky_metrics_proxying_enabled }}" -matrix_mautrix_bluesky_container_labels_metrics_traefik_rule: "Host(`{{ matrix_mautrix_bluesky_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_mautrix_bluesky_metrics_proxying_path_prefix }}`)" -matrix_mautrix_bluesky_container_labels_metrics_traefik_priority: 0 -matrix_mautrix_bluesky_container_labels_metrics_traefik_entrypoints: "{{ matrix_mautrix_bluesky_container_labels_traefik_entrypoints }}" -matrix_mautrix_bluesky_container_labels_metrics_traefik_tls: "{{ matrix_mautrix_bluesky_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_mautrix_bluesky_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_mautrix_bluesky_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_mautrix_bluesky_container_labels_metrics_middleware_basic_auth_enabled: false -# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_mautrix_bluesky_container_labels_metrics_middleware_basic_auth_users: '' - -# matrix_mautrix_bluesky_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# To inject your own other container labels, see `matrix_bridge_mautrix_bluesky_container_labels_additional_labels`. +matrix_bridge_mautrix_bluesky_container_labels_traefik_enabled: true +matrix_bridge_mautrix_bluesky_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_bluesky_container_network }}" +matrix_bridge_mautrix_bluesky_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_bluesky_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-bluesky's HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_bluesky_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_bluesky_exposure_enabled }}" +matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_bluesky_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_bluesky_exposure_path_prefix }}`)" +matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_bluesky_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_bluesky_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_bluesky_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_bluesky_container_labels_additional_labels: | +# matrix_bridge_mautrix_bluesky_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_bluesky_container_labels_additional_labels: '' +matrix_bridge_mautrix_bluesky_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_bluesky_container_extra_arguments: [] +matrix_bridge_mautrix_bluesky_container_extra_arguments: [] # List of systemd services that matrix-mautrix-bluesky.service depends on. -matrix_mautrix_bluesky_systemd_required_services_list: "{{ matrix_mautrix_bluesky_systemd_required_services_list_default + matrix_mautrix_bluesky_systemd_required_services_list_auto + matrix_mautrix_bluesky_systemd_required_services_list_custom }}" -matrix_mautrix_bluesky_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_bluesky_systemd_required_services_list_auto: [] -matrix_mautrix_bluesky_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_bluesky_systemd_required_services_list: "{{ matrix_bridge_mautrix_bluesky_systemd_required_services_list_default + matrix_bridge_mautrix_bluesky_systemd_required_services_list_auto + matrix_bridge_mautrix_bluesky_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_bluesky_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_bluesky_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_bluesky_systemd_required_services_list_custom: [] # List of systemd services that matrix-mautrix-bluesky.service wants -matrix_mautrix_bluesky_systemd_wanted_services_list: [] +matrix_bridge_mautrix_bluesky_systemd_wanted_services_list: [] -matrix_mautrix_bluesky_appservice_token: '' -matrix_mautrix_bluesky_homeserver_token: '' +matrix_bridge_mautrix_bluesky_appservice_token: '' +matrix_bridge_mautrix_bluesky_homeserver_token: '' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_mautrix_bluesky_matrix_federate_rooms: true +matrix_bridge_mautrix_bluesky_matrix_federate_rooms: true # Database-related configuration fields. # # To use Postgres: -# - adjust your database credentials via the `matrix_mautrix_bluesky_postgres_*` variables -matrix_mautrix_bluesky_database_engine: 'postgres' +# - adjust your database credentials via the `matrix_bridge_mautrix_bluesky_postgres_*` variables +matrix_bridge_mautrix_bluesky_database_engine: 'postgres' -matrix_mautrix_bluesky_database_username: 'matrix_mautrix_bluesky' -matrix_mautrix_bluesky_database_password: 'some-password' -matrix_mautrix_bluesky_database_hostname: '' -matrix_mautrix_bluesky_database_port: 5432 -matrix_mautrix_bluesky_database_name: 'matrix_mautrix_bluesky' -matrix_mautrix_bluesky_database_sslmode: disable +matrix_bridge_mautrix_bluesky_database_username: 'matrix_mautrix_bluesky' +matrix_bridge_mautrix_bluesky_database_password: 'some-password' +matrix_bridge_mautrix_bluesky_database_hostname: '' +matrix_bridge_mautrix_bluesky_database_port: 5432 +matrix_bridge_mautrix_bluesky_database_name: 'matrix_mautrix_bluesky' +matrix_bridge_mautrix_bluesky_database_sslmode: disable -matrix_mautrix_bluesky_database_connection_string: 'postgres://{{ matrix_mautrix_bluesky_database_username }}:{{ matrix_mautrix_bluesky_database_password }}@{{ matrix_mautrix_bluesky_database_hostname }}:{{ matrix_mautrix_bluesky_database_port }}/{{ matrix_mautrix_bluesky_database_name }}?sslmode={{ matrix_mautrix_bluesky_database_sslmode }}' +matrix_bridge_mautrix_bluesky_database_connection_string: 'postgres://{{ matrix_bridge_mautrix_bluesky_database_username }}:{{ matrix_bridge_mautrix_bluesky_database_password }}@{{ matrix_bridge_mautrix_bluesky_database_hostname }}:{{ matrix_bridge_mautrix_bluesky_database_port }}/{{ matrix_bridge_mautrix_bluesky_database_name }}?sslmode={{ matrix_bridge_mautrix_bluesky_database_sslmode }}' -matrix_mautrix_bluesky_database_uri: "{{ - { - 'postgres': matrix_mautrix_bluesky_database_connection_string, - }[matrix_mautrix_bluesky_database_engine] -}}" +matrix_bridge_mautrix_bluesky_database_uri: "{{ { + 'postgres': matrix_bridge_mautrix_bluesky_database_connection_string, +}[matrix_bridge_mautrix_bluesky_database_engine] }}" -matrix_mautrix_bluesky_double_puppet_secrets: "{{ matrix_mautrix_bluesky_double_puppet_secrets_auto | combine(matrix_mautrix_bluesky_double_puppet_secrets_custom) }}" -matrix_mautrix_bluesky_double_puppet_secrets_auto: {} -matrix_mautrix_bluesky_double_puppet_secrets_custom: {} +matrix_bridge_mautrix_bluesky_double_puppet_secrets: "{{ matrix_bridge_mautrix_bluesky_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_bluesky_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_bluesky_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_bluesky_double_puppet_secrets_custom: {} -matrix_mautrix_bluesky_appservice_bot_username: blueskybot -matrix_mautrix_bluesky_appservice_bot_displayname: Bluesky bridge bot -matrix_mautrix_bluesky_appservice_bot_avatar: mxc://maunium.net/ezAjjDxhiJWGEohmhkpfeHYf +matrix_bridge_mautrix_bluesky_appservice_bot_username: blueskybot +matrix_bridge_mautrix_bluesky_appservice_bot_displayname: Bluesky bridge bot +matrix_bridge_mautrix_bluesky_appservice_bot_avatar: mxc://maunium.net/ezAjjDxhiJWGEohmhkpfeHYf -matrix_mautrix_bluesky_backfill_enabled: true +matrix_bridge_mautrix_bluesky_backfill_enabled: true # Maximum number of messages to backfill in empty rooms -matrix_mautrix_bluesky_backfill_max_initial_messages: 50 +matrix_bridge_mautrix_bluesky_backfill_max_initial_messages: 50 # Maximum number of missed messages to backfill after bridge restarts -matrix_mautrix_bluesky_backfill_max_catchup_messages: 500 +matrix_bridge_mautrix_bluesky_backfill_max_catchup_messages: 500 # Shared secret for authentication of provisioning API requests. # If set to "disable", the provisioning API will be disabled. -matrix_mautrix_bluesky_provisioning_shared_secret: disable +matrix_bridge_mautrix_bluesky_provisioning_shared_secret: disable # Minimum severity of journal log messages. # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_bluesky_logging_level: 'warn' - -# Whether or not metrics endpoint should be enabled. -# Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_mautrix_bluesky_metrics_proxying_enabled`. -matrix_mautrix_bluesky_metrics_enabled: false +matrix_bridge_mautrix_bluesky_logging_level: 'warn' -# Controls whether metrics should be exposed on a public URL. -matrix_mautrix_bluesky_metrics_proxying_enabled: false -matrix_mautrix_bluesky_metrics_proxying_hostname: '' -matrix_mautrix_bluesky_metrics_proxying_path_prefix: '' +# Controls whether mautrix-bluesky's HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_bluesky_exposure_enabled: false +matrix_bridge_mautrix_bluesky_exposure_hostname: '' +matrix_bridge_mautrix_bluesky_exposure_path_prefix: '' # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_bluesky_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_bluesky_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_bluesky_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_bluesky_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_bluesky_configuration_extension_yaml: | +matrix_bridge_mautrix_bluesky_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_bluesky_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_bluesky_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_bluesky_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_bluesky_configuration_yaml`. -matrix_mautrix_bluesky_configuration_extension: "{{ matrix_mautrix_bluesky_configuration_extension_yaml | from_yaml if matrix_mautrix_bluesky_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_bluesky_configuration_extension: "{{ matrix_bridge_mautrix_bluesky_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_bluesky_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_bluesky_configuration_yaml`. -matrix_mautrix_bluesky_configuration: "{{ matrix_mautrix_bluesky_configuration_yaml | from_yaml | combine(matrix_mautrix_bluesky_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_bluesky_configuration_yaml`. +matrix_bridge_mautrix_bluesky_configuration: "{{ matrix_bridge_mautrix_bluesky_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_bluesky_configuration_extension, recursive=True) }}" -matrix_mautrix_bluesky_registration_yaml: | +matrix_bridge_mautrix_bluesky_registration_yaml: | id: bluesky - as_token: "{{ matrix_mautrix_bluesky_appservice_token }}" - hs_token: "{{ matrix_mautrix_bluesky_homeserver_token }}" + as_token: "{{ matrix_bridge_mautrix_bluesky_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_bluesky_homeserver_token }}" namespaces: users: - exclusive: true - regex: '^@bluesky_.+:{{ matrix_mautrix_bluesky_homeserver_domain | regex_escape }}$' + regex: '^@bluesky_.+:{{ matrix_bridge_mautrix_bluesky_homeserver_domain | regex_escape }}$' - exclusive: true - regex: '^@{{ matrix_mautrix_bluesky_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_bluesky_homeserver_domain | regex_escape }}$' - url: {{ matrix_mautrix_bluesky_appservice_address }} - sender_localpart: _bot_{{ matrix_mautrix_bluesky_appservice_bot_username }} + regex: '^@{{ matrix_bridge_mautrix_bluesky_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_bluesky_homeserver_domain | regex_escape }}$' + url: {{ matrix_bridge_mautrix_bluesky_appservice_address }} + sender_localpart: _bot_{{ matrix_bridge_mautrix_bluesky_appservice_bot_username }} rate_limited: false de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_mautrix_bluesky_msc4190_enabled | to_json }} + io.element.msc4190: {{ matrix_bridge_mautrix_bluesky_msc4190_enabled | to_json }} -matrix_mautrix_bluesky_registration: "{{ matrix_mautrix_bluesky_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_bluesky_registration: "{{ matrix_bridge_mautrix_bluesky_registration_yaml | from_yaml }}" # Enable End-to-bridge encryption -matrix_mautrix_bluesky_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_bluesky_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_mautrix_bluesky_bridge_encryption_require: false -matrix_mautrix_bluesky_bridge_encryption_appservice: false -matrix_mautrix_bluesky_bridge_encryption_key_sharing_allow: "{{ matrix_mautrix_bluesky_bridge_encryption_allow }}" -matrix_mautrix_bluesky_bridge_encryption_pickle_key: mautrix.bridge.e2ee - -# matrix_mautrix_bluesky_restart_necessary controls whether the service +matrix_bridge_mautrix_bluesky_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_bluesky_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_bluesky_bridge_encryption_require: false +matrix_bridge_mautrix_bluesky_bridge_encryption_appservice: false +matrix_bridge_mautrix_bluesky_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_mautrix_bluesky_bridge_encryption_allow }}" +matrix_bridge_mautrix_bluesky_bridge_encryption_pickle_key: mautrix.bridge.e2ee + +# matrix_bridge_mautrix_bluesky_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -218,4 +212,4 @@ matrix_mautrix_bluesky_bridge_encryption_pickle_key: mautrix.bridge.e2ee # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_bluesky_restart_necessary: false +matrix_bridge_mautrix_bluesky_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/converge.yml new file mode 100644 index 000000000..cb1dae2d7 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-bluesky Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-bluesky Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-bluesky is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-bluesky systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-bluesky.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/molecule.yml new file mode 100644 index 000000000..f0a335c5e --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/molecule.yml @@ -0,0 +1,95 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-bluesky-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_bluesky_container_network: mautrix-bluesky-molecule + + # The stub is not a real homeserver, and the scenario carries no Bluesky account or + # credentials. An idle, logged-out bridge is the intended third-party boundary. + matrix_bridge_mautrix_bluesky_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_bluesky_homeserver_domain: molecule.local + + # Postgres is this role's only database engine. The non-default identity makes schema + # creation evidence that the role composed and delivered the scenario connection URI. + matrix_bridge_mautrix_bluesky_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_bluesky_database_name: molecule_bluesky + matrix_bridge_mautrix_bluesky_database_username: molecule_bluesky + matrix_bridge_mautrix_bluesky_database_password: molecule_pg_password_74b0e2 + + # Test-only fixtures which must reach config.yaml and registration.yaml. + matrix_bridge_mautrix_bluesky_appservice_token: molecule_bluesky_as_token_1f27ac + matrix_bridge_mautrix_bluesky_homeserver_token: molecule_bluesky_hs_token_91c0d8 + + # Each value differs from the role default, allowing parsed checks to prove rendering. + matrix_bridge_mautrix_bluesky_appservice_bot_username: molecule-blueskybot + matrix_bridge_mautrix_bluesky_appservice_bot_displayname: Molecule Bluesky Bot + matrix_bridge_mautrix_bluesky_appservice_bot_avatar: mxc://molecule.local/blueskyAvatarFixture + matrix_bridge_mautrix_bluesky_network_displayname_template: "{% raw %}{{ .Username }}{% endraw %} via Molecule" + matrix_bridge_mautrix_bluesky_bridge_command_prefix: "!molecule-bluesky" + matrix_bridge_mautrix_bluesky_bridge_permissions: + "*": relay + molecule.local: admin + matrix_bridge_mautrix_bluesky_matrix_federate_rooms: false + matrix_bridge_mautrix_bluesky_backfill_enabled: false + matrix_bridge_mautrix_bluesky_backfill_max_initial_messages: 23 + matrix_bridge_mautrix_bluesky_backfill_max_catchup_messages: 37 + matrix_bridge_mautrix_bluesky_provisioning_shared_secret: molecule_provisioning_secret_2f018a + matrix_bridge_mautrix_bluesky_logging_level: info + + # Traefik is not started. These settings exercise the public address consumed by the + # bridge and the route labels consumed by Docker. + matrix_bridge_mautrix_bluesky_exposure_enabled: true + matrix_bridge_mautrix_bluesky_exposure_hostname: bluesky-api.molecule.local + matrix_bridge_mautrix_bluesky_exposure_path_prefix: /bridges/bluesky-api + matrix_bridge_mautrix_bluesky_scheme: http + matrix_bridge_mautrix_bluesky_container_labels_traefik_entrypoints: web + matrix_bridge_mautrix_bluesky_container_labels_additional_labels: | + molecule.bluesky.coverage=enabled + + # verify.yml is a separate play, where role defaults are out of scope. + matrix_bridge_mautrix_bluesky_base_path: /matrix/mautrix-bluesky + matrix_bridge_mautrix_bluesky_config_path: /matrix/mautrix-bluesky/config + matrix_bridge_mautrix_bluesky_data_path: /matrix/mautrix-bluesky/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/prepare.yml new file mode 100644 index 000000000..24eff7cdb --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/prepare.yml @@ -0,0 +1,87 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-bluesky Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role creates this during converge, but the two dependencies need it first. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_bluesky_container_network }}" + register: mautrix_bluesky_molecule_network + changed_when: mautrix_bluesky_molecule_network.rc == 0 + failed_when: + - mautrix_bluesky_molecule_network.rc != 0 + - "'already exists' not in mautrix_bluesky_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_bluesky_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_bluesky_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_bluesky_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_bluesky_database_password }}" + + # The logged-out bridge still authenticates its appservice bot during startup. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_bluesky_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_bluesky_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_bluesky_appservice_bot_username }}:{{ matrix_bridge_mautrix_bluesky_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/verify.yml new file mode 100644 index 000000000..07c88ed67 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-bluesky/molecule/default/verify.yml @@ -0,0 +1,387 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the logged-out bridge starts, accepts the role-rendered configuration and +# registration, migrates real Postgres, and opens its appservice listener. A Bluesky +# login is deliberately outside this scenario's third-party boundary. +- name: Verify mautrix-bluesky + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + mautrix_bluesky_config: "{{ mautrix_bluesky_config_file.content | b64decode | from_yaml }}" + mautrix_bluesky_registration: "{{ mautrix_bluesky_registration_file.content | b64decode | from_yaml }}" + mautrix_bluesky_labels_rendered: "{{ mautrix_bluesky_labels_file.content | b64decode }}" + mautrix_bluesky_expected_public_address: http://bluesky-api.molecule.local/bridges/bluesky-api + gather_facts: false + + tasks: + # A Renovate bump changes this source of truth and therefore the image expectation. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_bluesky_role_defaults + + - name: Wait for the mautrix-bluesky service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-bluesky.service + register: mautrix_bluesky_service + until: mautrix_bluesky_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes ActiveState insufficient for detecting a crash loop. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_bluesky_service.status.ActiveState == 'active' + - mautrix_bluesky_service.status.NRestarts is defined + - mautrix_bluesky_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-bluesky.service is + {{ mautrix_bluesky_service.status.ActiveState | default('unknown') }} after + {{ mautrix_bluesky_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-mautrix-bluesky.service is active and has not restarted" + + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_bluesky_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-bluesky:29340/_matrix/mau/live + register: mautrix_bluesky_live + changed_when: false + until: mautrix_bluesky_live.rc == 0 and mautrix_bluesky_live.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_bluesky_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-bluesky:29340/_matrix/mau/ready + register: mautrix_bluesky_ready + changed_when: false + until: mautrix_bluesky_ready.rc == 0 and mautrix_bluesky_ready.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on the configured appservice port + ansible.builtin.assert: + that: + - mautrix_bluesky_live.rc == 0 + - mautrix_bluesky_live.stdout == 'HTTP_STATUS=200' + - mautrix_bluesky_ready.rc == 0 + - mautrix_bluesky_ready.stdout == 'HTTP_STATUS=200' + fail_msg: >- + Health probes returned live={{ mautrix_bluesky_live.stdout | default('none') }} + (rc={{ mautrix_bluesky_live.rc | default('?') }}) and + ready={{ mautrix_bluesky_ready.stdout | default('none') }} + (rc={{ mautrix_bluesky_ready.rc | default('?') }}) + success_msg: "The bridge is live and ready on the configured appservice port" + + # This authenticated endpoint exercises the provisioning middleware and the network + # connector's login-flow API without starting a Bluesky login or carrying credentials. + - name: Query the authenticated provisioning login flows + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_bluesky_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --fail-with-body + - --header + - "Authorization: Bearer {{ matrix_bridge_mautrix_bluesky_provisioning_shared_secret }}" + - "http://matrix-mautrix-bluesky:29340/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_bluesky_login_flows + changed_when: false + + - name: Query the provisioning API with an invalid secret + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_bluesky_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - --header + - "Authorization: Bearer definitely-wrong-molecule-secret" + - "http://matrix-mautrix-bluesky:29340/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_bluesky_login_flows_unauthorized + changed_when: false + failed_when: false + + - name: Assert the live provisioning API enforces auth and advertises login flows + ansible.builtin.assert: + that: + - mautrix_bluesky_login_flows.rc == 0 + - (mautrix_bluesky_login_flows.stdout | from_json).flows is sequence + - (mautrix_bluesky_login_flows.stdout | from_json).flows | length > 0 + - (mautrix_bluesky_login_flows.stdout | from_json).flows | map(attribute='id') | list == ['password'] + - mautrix_bluesky_login_flows_unauthorized.rc == 0 + - mautrix_bluesky_login_flows_unauthorized.stdout == 'HTTP_STATUS=401' + fail_msg: "The provisioning API did not enforce its secret or return Bluesky login flows" + success_msg: "The provisioning API enforces its secret and returns Bluesky login flows" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_bluesky_config_path }}/config.yaml" + register: mautrix_bluesky_config_file + + - name: Assert the rendered configuration carries the appservice identity + ansible.builtin.assert: + that: + - mautrix_bluesky_config.homeserver.address == matrix_bridge_mautrix_bluesky_homeserver_address + - mautrix_bluesky_config.homeserver.domain == matrix_bridge_mautrix_bluesky_homeserver_domain + - mautrix_bluesky_config.appservice.id == 'bluesky' + - mautrix_bluesky_config.appservice.address == 'http://matrix-mautrix-bluesky:29340' + - mautrix_bluesky_config.appservice.public_address == mautrix_bluesky_expected_public_address + - mautrix_bluesky_config.appservice.bot.username == matrix_bridge_mautrix_bluesky_appservice_bot_username + - mautrix_bluesky_config.appservice.bot.displayname == matrix_bridge_mautrix_bluesky_appservice_bot_displayname + - mautrix_bluesky_config.appservice.bot.avatar == matrix_bridge_mautrix_bluesky_appservice_bot_avatar + - mautrix_bluesky_config.appservice.as_token == matrix_bridge_mautrix_bluesky_appservice_token + - mautrix_bluesky_config.appservice.hs_token == matrix_bridge_mautrix_bluesky_homeserver_token + fail_msg: "The rendered configuration does not carry the scenario's appservice identity" + success_msg: "The rendered configuration carries the scenario's appservice identity" + + - name: Assert the rendered configuration carries non-default bridge behavior + ansible.builtin.assert: + that: + - mautrix_bluesky_config.network.displayname_template == matrix_bridge_mautrix_bluesky_network_displayname_template + - mautrix_bluesky_config.bridge.command_prefix == matrix_bridge_mautrix_bluesky_bridge_command_prefix + - mautrix_bluesky_config.bridge.permissions['*'] == 'relay' + - mautrix_bluesky_config.bridge.permissions[matrix_bridge_mautrix_bluesky_homeserver_domain] == 'admin' + - not mautrix_bluesky_config.matrix.federate_rooms + - mautrix_bluesky_config.provisioning.shared_secret == matrix_bridge_mautrix_bluesky_provisioning_shared_secret + - mautrix_bluesky_config.logging.min_level == matrix_bridge_mautrix_bluesky_logging_level + fail_msg: "The rendered configuration does not carry the scenario's bridge behavior" + success_msg: "The rendered configuration carries the scenario's bridge behavior" + + - name: Assert the rendered configuration carries the non-default backfill policy + ansible.builtin.assert: + that: + - not mautrix_bluesky_config.backfill.enabled + - mautrix_bluesky_config.backfill.max_initial_messages == 23 + - mautrix_bluesky_config.backfill.max_catchup_messages == 37 + fail_msg: "The rendered configuration does not carry the scenario's backfill policy" + success_msg: "The rendered configuration carries the scenario's backfill policy" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - mautrix_bluesky_config.database.type == 'postgres' + - matrix_bridge_mautrix_bluesky_database_username in mautrix_bluesky_config.database.uri + - matrix_bridge_mautrix_bluesky_database_hostname in mautrix_bluesky_config.database.uri + - matrix_bridge_mautrix_bluesky_database_name in mautrix_bluesky_config.database.uri + fail_msg: >- + database.uri is {{ mautrix_bluesky_config.database.uri | default('unset') }}, which + was not composed from the scenario's connection settings + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_bluesky_config_path }}/registration.yaml" + register: mautrix_bluesky_registration_file + + - name: Assert the registration carries the configured handshake values + ansible.builtin.assert: + that: + - mautrix_bluesky_registration.id == 'bluesky' + - mautrix_bluesky_registration.as_token == matrix_bridge_mautrix_bluesky_appservice_token + - mautrix_bluesky_registration.hs_token == matrix_bridge_mautrix_bluesky_homeserver_token + - mautrix_bluesky_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_bluesky_appservice_bot_username + - mautrix_bluesky_registration.url == 'http://matrix-mautrix-bluesky:29340' + fail_msg: "The registration does not carry the configured handshake values" + success_msg: "The registration carries the configured handshake values" + + - name: Assert the registration namespaces cover only Bluesky ghosts and the bridge bot + ansible.builtin.assert: + that: + - mautrix_bluesky_ghost_regex | length > 0 + - mautrix_bluesky_bot_regex | length > 0 + - mautrix_bluesky_ghost_mxid is match(mautrix_bluesky_ghost_regex) + - mautrix_bluesky_wrong_ghost_mxid is not match(mautrix_bluesky_ghost_regex) + - mautrix_bluesky_bot_mxid is match(mautrix_bluesky_bot_regex) + fail_msg: "The registration namespaces do not cover only Bluesky ghosts and the bot" + success_msg: "The registration namespaces cover only Bluesky ghosts and the bot" + vars: + mautrix_bluesky_user_regexes: "{{ mautrix_bluesky_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_bluesky_ghost_regex: "{{ mautrix_bluesky_user_regexes | select('search', 'bluesky_') | first | default('') }}" + mautrix_bluesky_bot_regex: "{{ mautrix_bluesky_user_regexes | reject('search', 'bluesky_') | first | default('') }}" + mautrix_bluesky_ghost_mxid: "@bluesky_did_plc_moleculefixture:{{ matrix_bridge_mautrix_bluesky_homeserver_domain }}" + mautrix_bluesky_wrong_ghost_mxid: "@twitter_did_plc_moleculefixture:{{ matrix_bridge_mautrix_bluesky_homeserver_domain }}" + mautrix_bluesky_bot_mxid: "@{{ matrix_bridge_mautrix_bluesky_appservice_bot_username }}:{{ matrix_bridge_mautrix_bluesky_homeserver_domain }}" + + # Tables can appear only after hostname resolution, authentication, and real migrations. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_bluesky_database_username }} + - --dbname={{ matrix_bridge_mautrix_bluesky_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: mautrix_bluesky_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - mautrix_bluesky_tables.rc == 0 + - "'version' in mautrix_bluesky_table_names" + - "'portal' in mautrix_bluesky_table_names" + - "'user_login' in mautrix_bluesky_table_names" + - "'message' in mautrix_bluesky_table_names" + - mautrix_bluesky_table_names | length > 10 + fail_msg: >- + The bridge did not migrate its schema into {{ matrix_bridge_mautrix_bluesky_database_name }} + (found {{ mautrix_bluesky_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + mautrix_bluesky_table_names: "{{ mautrix_bluesky_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_bluesky_base_path }}/labels" + register: mautrix_bluesky_labels_file + + - name: Assert the labels route the public endpoint to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_bluesky_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_bluesky_container_network in mautrix_bluesky_labels_rendered" + - "'traefik.http.services.matrix-mautrix-bluesky-exposure.loadbalancer.server.port=29340' in mautrix_bluesky_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-bluesky-exposure.rule=Host(`bluesky-api.molecule.local`) && PathPrefix(`/bridges/bluesky-api`)' in mautrix_bluesky_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-bluesky-exposure-strip-prefix.stripprefix.prefixes=/bridges/bluesky-api' in mautrix_bluesky_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-bluesky-exposure.entrypoints=web' in mautrix_bluesky_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-bluesky-exposure.tls=false' in mautrix_bluesky_labels_rendered" + - "'molecule.bluesky.coverage=enabled' in mautrix_bluesky_labels_rendered" + fail_msg: "The rendered labels do not carry the scenario's exposure configuration" + success_msg: "The rendered labels carry the scenario's exposure configuration" + + - name: Inspect the running bridge container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-bluesky + register: mautrix_bluesky_container_inspect + changed_when: false + + - name: Parse the running bridge container inspection + ansible.builtin.set_fact: + mautrix_bluesky_container: "{{ (mautrix_bluesky_container_inspect.stdout | from_json) | first }}" + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - mautrix_bluesky_container.Config.Image == mautrix_bluesky_expected_image + fail_msg: >- + The running container uses {{ mautrix_bluesky_container.Config.Image }}, expected + {{ mautrix_bluesky_expected_image }} + success_msg: "The running container uses the exact image pinned by the role" + vars: + mautrix_bluesky_expected_image: >- + {{ mautrix_bluesky_role_defaults.matrix_bridge_mautrix_bluesky_container_image_registry_prefix_upstream_default }}mautrix/bluesky:{{ mautrix_bluesky_role_defaults.matrix_bridge_mautrix_bluesky_version }} + + - name: Assert the running container uses the playbook-supplied runtime + ansible.builtin.assert: + that: + - mautrix_bluesky_container.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + - mautrix_bluesky_container.Config.WorkingDir == '/data' + - mautrix_bluesky_container.Config.Cmd == ['/usr/bin/mautrix-bluesky', '-c', '/config/config.yaml', '-r', '/config/registration.yaml', '--no-update'] + - mautrix_bluesky_container.HostConfig.RestartPolicy.Name == 'no' + - mautrix_bluesky_container.HostConfig.AutoRemove + - mautrix_bluesky_container.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container does not use the role's exact identity and command" + success_msg: "The running container uses the role's exact identity and command" + + - name: Assert the running container has the intended privilege isolation + ansible.builtin.assert: + that: + - "'ALL' in mautrix_bluesky_container.HostConfig.CapDrop" + - not mautrix_bluesky_container.HostConfig.Privileged + fail_msg: "The running container does not have the intended privilege isolation" + success_msg: "The running container drops all capabilities and is unprivileged" + + - name: Assert the running container carries the role's exact bind mounts + ansible.builtin.assert: + that: + - mautrix_bluesky_config_mount | length > 0 + - mautrix_bluesky_config_mount.Source == matrix_bridge_mautrix_bluesky_config_path + - not mautrix_bluesky_config_mount.RW + - mautrix_bluesky_data_mount | length > 0 + - mautrix_bluesky_data_mount.Source == matrix_bridge_mautrix_bluesky_data_path + - mautrix_bluesky_data_mount.RW + - mautrix_bluesky_container.Mounts | length == 2 + fail_msg: "The running container does not carry the role's exact config and data mounts" + success_msg: "The running container carries read-only config and writable data mounts" + vars: + mautrix_bluesky_config_mount: >- + {{ mautrix_bluesky_container.Mounts + | selectattr('Destination', 'equalto', '/config') + | first | default({}) }} + mautrix_bluesky_data_mount: >- + {{ mautrix_bluesky_container.Mounts + | selectattr('Destination', 'equalto', '/data') + | first | default({}) }} + + - name: Assert the rendered labels are attached to the running container + ansible.builtin.assert: + that: + - mautrix_bluesky_container.Config.Labels['traefik.enable'] == 'true' + - mautrix_bluesky_container.Config.Labels['traefik.docker.network'] == matrix_bridge_mautrix_bluesky_container_network + - mautrix_bluesky_container.Config.Labels['traefik.http.services.matrix-mautrix-bluesky-exposure.loadbalancer.server.port'] == '29340' + - mautrix_bluesky_container.Config.Labels['molecule.bluesky.coverage'] == 'enabled' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The running container carries the labels the role rendered" + + - name: Assert the running container has the exact network and port exposure + ansible.builtin.assert: + that: + - mautrix_bluesky_container.HostConfig.NetworkMode == matrix_bridge_mautrix_bluesky_container_network + - matrix_bridge_mautrix_bluesky_container_network in mautrix_bluesky_container.NetworkSettings.Networks + - mautrix_bluesky_container.NetworkSettings.Networks | length == 1 + - mautrix_bluesky_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: >- + The container has unexpected networks or host ports: + networks={{ mautrix_bluesky_container.NetworkSettings.Networks.keys() | list }}, + ports={{ mautrix_bluesky_container.HostConfig.PortBindings | default({}) }} + success_msg: "The container uses only its dedicated network and publishes no host ports" diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-bluesky/tasks/main.yml index 0071485aa..abfab10b1 100644 --- a/roles/custom/matrix-bridge-mautrix-bluesky/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-bluesky/tasks/main.yml @@ -10,15 +10,15 @@ - install-all - install-mautrix-bluesky block: - - when: matrix_mautrix_bluesky_enabled | bool + - when: matrix_bridge_mautrix_bluesky_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_bluesky_enabled | bool + - when: matrix_bridge_mautrix_bluesky_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mautrix-bluesky block: - - when: not matrix_mautrix_bluesky_enabled | bool + - when: not matrix_bridge_mautrix_bluesky_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-bluesky/tasks/setup_install.yml index ef45a0528..98e6f499e 100644 --- a/roles/custom/matrix-bridge-mautrix-bluesky/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-bluesky/tasks/setup_install.yml @@ -5,19 +5,17 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_bluesky_migration_requires_restart: false + matrix_bridge_mautrix_bluesky_migration_requires_restart: false - name: Ensure Mautrix Bluesky image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_bluesky_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_bluesky_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_bluesky_container_image_force_pull }}" - when: matrix_mautrix_bluesky_enabled | bool and not matrix_mautrix_bluesky_container_image_self_build - register: matrix_mautrix_bluesky_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_bluesky_container_image }}" + pull: always + when: matrix_bridge_mautrix_bluesky_enabled | bool and not matrix_bridge_mautrix_bluesky_container_image_self_build + register: matrix_bridge_mautrix_bluesky_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_bluesky_container_image_pull_result is not failed + until: matrix_bridge_mautrix_bluesky_container_image_pull_result is not failed - name: Ensure Mautrix Bluesky paths exist ansible.builtin.file: @@ -27,67 +25,77 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_bluesky_base_path }}", when: true} - - {path: "{{ matrix_mautrix_bluesky_config_path }}", when: true} - - {path: "{{ matrix_mautrix_bluesky_data_path }}", when: true} - - {path: "{{ matrix_mautrix_bluesky_container_src_files_path }}", when: "{{ matrix_mautrix_bluesky_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_bluesky_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_bluesky_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_bluesky_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_bluesky_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_bluesky_container_image_self_build }}"} when: item.when | bool +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix Bluesky repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_bluesky_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_bluesky_enabled | bool and matrix_bridge_mautrix_bluesky_container_image_self_build" + - name: Ensure Mautrix Bluesky repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_mautrix_bluesky_container_image_self_build_repo }}" - version: "{{ matrix_mautrix_bluesky_container_image_self_build_repo_version }}" - dest: "{{ matrix_mautrix_bluesky_container_src_files_path }}" + repo: "{{ matrix_bridge_mautrix_bluesky_container_image_self_build_repo }}" + version: "{{ matrix_bridge_mautrix_bluesky_container_image_self_build_repo_version }}" + dest: "{{ matrix_bridge_mautrix_bluesky_container_src_files_path }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_bluesky_git_pull_results - when: "matrix_mautrix_bluesky_enabled | bool and matrix_mautrix_bluesky_container_image_self_build" + register: matrix_bridge_mautrix_bluesky_git_pull_results + when: "matrix_bridge_mautrix_bluesky_enabled | bool and matrix_bridge_mautrix_bluesky_container_image_self_build" - name: Ensure Mautrix Bluesky Docker image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_bluesky_container_image }}" - source: build - force_source: "{{ matrix_mautrix_bluesky_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_bluesky_container_src_files_path }}" - pull: true - when: "matrix_mautrix_bluesky_enabled | bool and matrix_mautrix_bluesky_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_bluesky_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_bluesky_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_bluesky_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_bluesky_enabled | bool and matrix_bridge_mautrix_bluesky_container_image_self_build | bool" + register: matrix_bridge_mautrix_bluesky_container_image_build_result - name: Ensure mautrix-bluesky config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_bluesky_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_bluesky_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_bluesky_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_bluesky_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_bluesky_config_result + register: matrix_bridge_mautrix_bluesky_config_result - name: Ensure mautrix-bluesky registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_bluesky_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_bluesky_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_bluesky_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_bluesky_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_bluesky_registration_result + register: matrix_bridge_mautrix_bluesky_registration_result - name: Ensure mautrix-bluesky support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_bluesky_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_bluesky_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_mautrix_bluesky_support_files_result + register: matrix_bridge_mautrix_bluesky_support_files_result - name: Ensure matrix-mautrix-bluesky container network is created + when: matrix_bridge_mautrix_bluesky_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_bluesky_container_network }}" + name: "{{ matrix_bridge_mautrix_bluesky_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -96,18 +104,19 @@ src: "{{ role_path }}/templates/systemd/matrix-mautrix-bluesky.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-bluesky.service" mode: '0644' - register: matrix_mautrix_bluesky_systemd_service_result + register: matrix_bridge_mautrix_bluesky_systemd_service_result - name: Determine whether matrix-mautrix-bluesky needs a restart ansible.builtin.set_fact: - matrix_mautrix_bluesky_restart_necessary: >- + matrix_bridge_mautrix_bluesky_restart_necessary: >- {{ - matrix_mautrix_bluesky_migration_requires_restart | default(false) - or matrix_mautrix_bluesky_config_result.changed | default(false) - or matrix_mautrix_bluesky_registration_result.changed | default(false) - or matrix_mautrix_bluesky_support_files_result.changed | default(false) - or matrix_mautrix_bluesky_systemd_service_result.changed | default(false) - or matrix_mautrix_bluesky_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_bluesky_migration_requires_restart | default(false) + or matrix_bridge_mautrix_bluesky_config_result.changed | default(false) + or matrix_bridge_mautrix_bluesky_registration_result.changed | default(false) + or matrix_bridge_mautrix_bluesky_support_files_result.changed | default(false) + or matrix_bridge_mautrix_bluesky_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_bluesky_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_bluesky_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mautrix-bluesky.service restarted, if necessary @@ -115,4 +124,4 @@ name: "matrix-mautrix-bluesky.service" state: restarted daemon_reload: true - when: "matrix_mautrix_bluesky_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_bluesky_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-bluesky/tasks/setup_uninstall.yml index e38cd26c9..a324b7b06 100644 --- a/roles/custom/matrix-bridge-mautrix-bluesky/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-bluesky/tasks/setup_uninstall.yml @@ -7,9 +7,9 @@ - name: Check existence of matrix-mautrix-bluesky service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-bluesky.service" - register: matrix_mautrix_bluesky_service_stat + register: matrix_bridge_mautrix_bluesky_service_stat -- when: matrix_mautrix_bluesky_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_bluesky_service_stat.stat.exists | bool block: - name: Ensure matrix-mautrix-bluesky is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-bluesky/tasks/validate_config.yml index c1e383521..e1324dd6a 100644 --- a/roles/custom/matrix-bridge-mautrix-bluesky/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-bluesky/tasks/validate_config.yml @@ -13,13 +13,26 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_bluesky_docker_image_name_prefix', 'new': 'matrix_mautrix_bluesky_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_bluesky_docker_image', 'new': 'matrix_mautrix_bluesky_container_image'} - - {'old': 'matrix_mautrix_bluesky_docker_image_force_pull', 'new': 'matrix_mautrix_bluesky_container_image_force_pull'} - - {'old': 'matrix_mautrix_bluesky_docker_image_registry_prefix', 'new': 'matrix_mautrix_bluesky_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_bluesky_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_bluesky_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_bluesky_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_bluesky_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_bluesky_docker_src_files_path', 'new': 'matrix_mautrix_bluesky_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_bluesky_docker_image_name_prefix', 'new': 'matrix_bridge_mautrix_bluesky_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_bluesky_docker_image', 'new': 'matrix_bridge_mautrix_bluesky_container_image'} + - {'old': 'matrix_bridge_mautrix_bluesky_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_bluesky_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_bluesky_docker_image_registry_prefix', 'new': 'matrix_bridge_mautrix_bluesky_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_bluesky_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mautrix_bluesky_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mautrix_bluesky_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mautrix_bluesky_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mautrix_bluesky_docker_src_files_path', 'new': 'matrix_bridge_mautrix_bluesky_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_bluesky_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_mautrix_bluesky_metrics_enabled', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_metrics_proxying_enabled', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_metrics_proxying_hostname', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_metrics_proxying_path_prefix', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_container_labels_metrics_enabled', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_container_labels_metrics_traefik_rule', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_container_labels_metrics_traefik_priority', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_container_labels_metrics_traefik_entrypoints', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_container_labels_metrics_traefik_tls', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_container_labels_metrics_traefik_tls_certResolver', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (mautrix-bluesky does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_bluesky_container_labels_metrics_middleware_basic_auth_users', 'new': ' (mautrix-bluesky does not support metrics)'} - name: Fail if required mautrix-bluesky settings not defined ansible.builtin.fail: @@ -27,10 +40,8 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_bluesky_appservice_token', when: true} - - {'name': 'matrix_mautrix_bluesky_homeserver_address', when: true} - - {'name': 'matrix_mautrix_bluesky_homeserver_token', when: true} - - {'name': 'matrix_mautrix_bluesky_database_hostname', when: "{{ matrix_mautrix_bluesky_database_engine == 'postgres' }}"} - - {'name': 'matrix_mautrix_bluesky_container_network', when: true} - - {'name': 'matrix_mautrix_bluesky_metrics_proxying_hostname', when: "{{ matrix_mautrix_bluesky_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_bluesky_metrics_proxying_path_prefix', when: "{{ matrix_mautrix_bluesky_metrics_proxying_enabled }}"} + - {'name': 'matrix_bridge_mautrix_bluesky_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_bluesky_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_bluesky_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_bluesky_database_hostname', when: "{{ matrix_bridge_mautrix_bluesky_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_bluesky_container_network', when: true} diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-bluesky/templates/config.yaml.j2 index 7fbac01d8..d804ecb48 100644 --- a/roles/custom/matrix-bridge-mautrix-bluesky/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-bluesky/templates/config.yaml.j2 @@ -7,11 +7,9 @@ network: get_proxy_url: null # Displayname template for Bluesky users. - # {% raw %} - # {{ .DisplayName }} is replaced with the display name of the Bluesky user. - # {{ .Username }} is replaced with the username of the Bluesky user. - # {% endraw %} - displayname_template: {{ matrix_mautrix_bluesky_network_displayname_template | to_json }} + # {% raw %}{{ .DisplayName }}{% endraw %} is replaced with the display name of the Bluesky user. + # {% raw %}{{ .Username }}{% endraw %} is replaced with the username of the Bluesky user. + displayname_template: {{ matrix_bridge_mautrix_bluesky_network_displayname_template | to_json }} # Maximum number of conversations to sync on startup conversation_sync_limit: 20 @@ -20,7 +18,7 @@ network: # Config options that affect the central bridge module. bridge: # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_mautrix_bluesky_bridge_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_mautrix_bluesky_bridge_command_prefix | to_json }} # Should the bridge create a space for each login containing the rooms that account is in? personal_filtering_spaces: true # Whether the bridge should set names and avatars explicitly for DM portals. @@ -121,7 +119,7 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_bluesky_bridge_permissions | to_json }} + permissions: {{ matrix_bridge_mautrix_bluesky_bridge_permissions | to_json }} # Config for the bridge's database. database: @@ -132,7 +130,7 @@ database: # https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_mautrix_bluesky_database_uri | to_json }} + uri: {{ matrix_bridge_mautrix_bluesky_database_uri | to_json }} # Maximum number of connections. max_open_conns: 5 max_idle_conns: 1 @@ -146,9 +144,9 @@ homeserver: # The address that this appservice can use to connect to the homeserver. # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, # but https also works if they run on different machines. - address: {{ matrix_mautrix_bluesky_homeserver_address | to_json }} + address: {{ matrix_bridge_mautrix_bluesky_homeserver_address | to_json }} # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: {{ matrix_mautrix_bluesky_homeserver_domain | to_json }} + domain: {{ matrix_bridge_mautrix_bluesky_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -164,7 +162,7 @@ homeserver: # The bridge will use the appservice as_token to authorize requests. message_send_checkpoint_endpoint: # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_mautrix_bluesky_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_mautrix_bluesky_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -180,11 +178,11 @@ appservice: # Like the homeserver address, a local non-https address is recommended when the bridge is on the same machine. # If the bridge is elsewhere, you must secure the connection yourself (e.g. with https or wireguard) # If you want to use https, you need to use a reverse proxy. The bridge does not have TLS support built in. - address: {{ matrix_mautrix_bluesky_appservice_address | to_json }} + address: {{ matrix_bridge_mautrix_bluesky_appservice_address | to_json }} # A public address that external services can use to reach this appservice. # This is only needed for things like public media. A reverse proxy is generally necessary when using this field. # This value doesn't affect the registration file. - public_address: {{ matrix_mautrix_bluesky_appservice_public_address | to_json }} + public_address: {{ matrix_bridge_mautrix_bluesky_appservice_public_address | to_json }} # The hostname and port where this appservice should listen. # For Docker, you generally have to change the hostname to 0.0.0.0. @@ -196,11 +194,11 @@ appservice: # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_mautrix_bluesky_appservice_bot_username | to_json }} + username: {{ matrix_bridge_mautrix_bluesky_appservice_bot_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. - displayname: {{ matrix_mautrix_bluesky_appservice_bot_displayname | to_json(ensure_ascii=False) }} - avatar: {{ matrix_mautrix_bluesky_appservice_bot_avatar | to_json }} + displayname: {{ matrix_bridge_mautrix_bluesky_appservice_bot_displayname | to_json(ensure_ascii=False) }} + avatar: {{ matrix_bridge_mautrix_bluesky_appservice_bot_avatar | to_json }} # Whether to receive ephemeral events via appservice transactions. ephemeral_events: true @@ -211,8 +209,8 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_mautrix_bluesky_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_bluesky_homeserver_token | to_json }} + as_token: {{ matrix_bridge_mautrix_bluesky_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_bluesky_homeserver_token | to_json }} # Localpart template of MXIDs for remote users. # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. @@ -230,7 +228,7 @@ matrix: sync_direct_chat_list: true # Whether created rooms should have federation enabled. If false, created portal rooms # will never be federated. Changing this option requires recreating rooms. - federate_rooms: {{ matrix_mautrix_bluesky_matrix_federate_rooms | to_json }} + federate_rooms: {{ matrix_bridge_mautrix_bluesky_matrix_federate_rooms | to_json }} # The threshold as bytes after which the bridge should roundtrip uploads via the disk # rather than keeping the whole file in memory. upload_file_threshold: 5242880 @@ -250,7 +248,7 @@ provisioning: prefix: /_matrix/provision # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, # or if set to "disable", the provisioning API will be disabled. - shared_secret: {{ matrix_mautrix_bluesky_provisioning_shared_secret | to_json }} + shared_secret: {{ matrix_bridge_mautrix_bluesky_provisioning_shared_secret | to_json }} # Whether to allow provisioning API requests to be authed using Matrix access tokens. # This follows the same rules as double puppeting to determine which server to contact to check the token, # which means that by default, it only works for users on the same server as the bridge. @@ -300,11 +298,11 @@ direct_media: # See https://docs.mau.fi/bridges/general/backfill.html for more details. backfill: # Whether to do backfilling at all. - enabled: {{ matrix_mautrix_bluesky_backfill_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_bluesky_backfill_enabled | to_json }} # Maximum number of messages to backfill in empty rooms. - max_initial_messages: {{ matrix_mautrix_bluesky_backfill_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_mautrix_bluesky_backfill_max_initial_messages | to_json }} # Maximum number of missed messages to backfill after bridge restarts. - max_catchup_messages: {{ matrix_mautrix_bluesky_backfill_max_catchup_messages | to_json }} + max_catchup_messages: {{ matrix_bridge_mautrix_bluesky_backfill_max_catchup_messages | to_json }} # If a backfilled chat is older than this number of hours, # mark it as read even if it's unread on the remote network. unread_hours_threshold: 720 @@ -339,35 +337,35 @@ double_puppet: allow_discovery: false # Shared secrets for automatic double puppeting. # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. - secrets: {{ matrix_mautrix_bluesky_double_puppet_secrets | to_json }} + secrets: {{ matrix_bridge_mautrix_bluesky_double_puppet_secrets | to_json }} # End-to-bridge encryption support options. # # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. - allow: {{ matrix_mautrix_bluesky_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_mautrix_bluesky_bridge_encryption_allow | to_json }} # Whether to force-enable encryption in all bridged rooms. - default: {{ matrix_mautrix_bluesky_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_mautrix_bluesky_bridge_encryption_default | to_json }} # Whether to require all messages to be encrypted and drop any unencrypted messages. - require: {{ matrix_mautrix_bluesky_bridge_encryption_require | to_json }} + require: {{ matrix_bridge_mautrix_bluesky_bridge_encryption_require | to_json }} # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. # This option is not yet compatible with standard Matrix servers like Synapse and should not be used. - appservice: {{ matrix_mautrix_bluesky_bridge_encryption_appservice | to_json }} + appservice: {{ matrix_bridge_mautrix_bluesky_bridge_encryption_appservice | to_json }} # Whether to use MSC4190 instead of appservice login to create the bridge bot device. # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_mautrix_bluesky_msc4190_enabled | to_json }} + msc4190: {{ matrix_bridge_mautrix_bluesky_msc4190_enabled | to_json }} # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) # Requires msc4190 to replace keys on reset - self_sign: {{ matrix_mautrix_bluesky_self_sign_enabled | to_json }} + self_sign: {{ matrix_bridge_mautrix_bluesky_self_sign_enabled | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_mautrix_bluesky_bridge_encryption_key_sharing_allow | to_json }} + allow_key_sharing: {{ matrix_bridge_mautrix_bluesky_bridge_encryption_key_sharing_allow | to_json }} # Pickle key for encrypting encryption keys in the bridge database. # If set to generate, a random key will be generated. - pickle_key: {{ matrix_mautrix_bluesky_bridge_encryption_pickle_key | to_json }} + pickle_key: {{ matrix_bridge_mautrix_bluesky_bridge_encryption_pickle_key | to_json }} # Options for deleting megolm sessions from the bridge. delete_keys: # Beeper-specific: delete outbound sessions when hungryserv confirms @@ -426,7 +424,7 @@ encryption: # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_mautrix_bluesky_logging_level | to_json }} + min_level: {{ matrix_bridge_mautrix_bluesky_logging_level | to_json }} writers: - type: stdout format: pretty-colored diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-bluesky/templates/labels.j2 index bec40b880..cbaac5c02 100644 --- a/roles/custom/matrix-bridge-mautrix-bluesky/templates/labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-bluesky/templates/labels.j2 @@ -4,44 +4,42 @@ SPDX-FileCopyrightText: 2025 MDAD project contributors SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_bluesky_container_labels_traefik_enabled %} +{% if matrix_bridge_mautrix_bluesky_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_mautrix_bluesky_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_bluesky_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_bluesky_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_bluesky_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.matrix-mautrix-bluesky-metrics.loadbalancer.server.port=8000 - -{% if matrix_mautrix_bluesky_container_labels_metrics_enabled %} +{% if matrix_bridge_mautrix_bluesky_container_labels_exposure_enabled %} ############################################################ # # -# Metrics # +# Bridge API exposure # # # ############################################################ -{% if matrix_mautrix_bluesky_container_labels_metrics_middleware_basic_auth_enabled %} -traefik.http.middlewares.matrix-mautrix-bluesky-metrics-basic-auth.basicauth.users={{ matrix_mautrix_bluesky_container_labels_metrics_middleware_basic_auth_users }} -traefik.http.routers.matrix-mautrix-bluesky-metrics.middlewares=matrix-mautrix-bluesky-metrics-basic-auth -{% endif %} +traefik.http.services.matrix-mautrix-bluesky-exposure.loadbalancer.server.port=29340 + +traefik.http.middlewares.matrix-mautrix-bluesky-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_bluesky_exposure_path_prefix }} +traefik.http.routers.matrix-mautrix-bluesky-exposure.middlewares=matrix-mautrix-bluesky-exposure-strip-prefix -traefik.http.routers.matrix-mautrix-bluesky-metrics.rule={{ matrix_mautrix_bluesky_container_labels_metrics_traefik_rule }} +traefik.http.routers.matrix-mautrix-bluesky-exposure.rule={{ matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_rule }} -{% if matrix_mautrix_bluesky_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-bluesky-metrics.priority={{ matrix_mautrix_bluesky_container_labels_metrics_traefik_priority }} +{% if matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-bluesky-exposure.priority={{ matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_priority }} {% endif %} -traefik.http.routers.matrix-mautrix-bluesky-metrics.service=matrix-mautrix-bluesky-metrics -traefik.http.routers.matrix-mautrix-bluesky-metrics.entrypoints={{ matrix_mautrix_bluesky_container_labels_metrics_traefik_entrypoints }} +traefik.http.routers.matrix-mautrix-bluesky-exposure.service=matrix-mautrix-bluesky-exposure +traefik.http.routers.matrix-mautrix-bluesky-exposure.entrypoints={{ matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_entrypoints }} -traefik.http.routers.matrix-mautrix-bluesky-metrics.tls={{ matrix_mautrix_bluesky_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_mautrix_bluesky_container_labels_metrics_traefik_tls %} -traefik.http.routers.matrix-mautrix-bluesky-metrics.tls.certResolver={{ matrix_mautrix_bluesky_container_labels_metrics_traefik_tls_certResolver }} +traefik.http.routers.matrix-mautrix-bluesky-exposure.tls={{ matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-mautrix-bluesky-exposure.tls.certResolver={{ matrix_bridge_mautrix_bluesky_container_labels_exposure_traefik_tls_certResolver }} {% endif %} ############################################################ # # -# /Metrics # +# /Bridge API exposure # # # ############################################################ {% endif %} @@ -49,4 +47,4 @@ traefik.http.routers.matrix-mautrix-bluesky-metrics.tls.certResolver={{ matrix_m {% endif %} -{{ matrix_mautrix_bluesky_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_bluesky_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-bluesky/templates/systemd/matrix-mautrix-bluesky.service.j2 b/roles/custom/matrix-bridge-mautrix-bluesky/templates/systemd/matrix-mautrix-bluesky.service.j2 index 54f514bd1..589d611fc 100644 --- a/roles/custom/matrix-bridge-mautrix-bluesky/templates/systemd/matrix-mautrix-bluesky.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-bluesky/templates/systemd/matrix-mautrix-bluesky.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix Bluesky bridge -{% for service in matrix_mautrix_bluesky_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_bluesky_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_bluesky_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_bluesky_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,19 +22,21 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_bluesky_container_network }} \ - --mount type=bind,src={{ matrix_mautrix_bluesky_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_mautrix_bluesky_data_path }},dst=/data \ - --label-file={{ matrix_mautrix_bluesky_base_path }}/labels \ - {% for arg in matrix_mautrix_bluesky_container_extra_arguments %} + --network={{ matrix_bridge_mautrix_bluesky_container_network }} \ + --mount type=bind,src={{ matrix_bridge_mautrix_bluesky_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_bluesky_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_bluesky_base_path }}/labels \ + {% for arg in matrix_bridge_mautrix_bluesky_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_bluesky_container_image }} \ + {{ matrix_bridge_mautrix_bluesky_container_image }} \ /usr/bin/mautrix-bluesky -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_mautrix_bluesky_container_additional_networks %} +{% if matrix_bridge_mautrix_bluesky_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_bluesky_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-bluesky {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-bluesky diff --git a/roles/custom/matrix-bridge-mautrix-discord/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-discord/defaults/main.yml index 1d3ca6883..fea94dcf0 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-discord/defaults/main.yml @@ -10,243 +10,238 @@ # mautrix-discord is a Matrix <-> Discord bridge # Project source code URL: https://github.com/mautrix/discord -matrix_mautrix_discord_enabled: true +matrix_bridge_mautrix_discord_enabled: true -matrix_mautrix_discord_hostname: "" -matrix_mautrix_discord_path_prefix: / -matrix_mautrix_discord_scheme: https +matrix_bridge_mautrix_discord_hostname: "" +matrix_bridge_mautrix_discord_path_prefix: / +matrix_bridge_mautrix_discord_scheme: https -matrix_mautrix_discord_container_image_self_build: false -matrix_mautrix_discord_container_image_self_build_repo: "https://mau.dev/mautrix/discord.git" -matrix_mautrix_discord_container_image_self_build_branch: "{{ 'main' if matrix_mautrix_discord_version == 'latest' else matrix_mautrix_discord_version }}" +matrix_bridge_mautrix_discord_container_image_self_build: false +matrix_bridge_mautrix_discord_container_image_self_build_repo: "https://mau.dev/mautrix/discord.git" +matrix_bridge_mautrix_discord_container_image_self_build_branch: "{{ 'main' if matrix_bridge_mautrix_discord_version == 'latest' else matrix_bridge_mautrix_discord_version }}" # renovate: datasource=docker depName=dock.mau.dev/mautrix/discord -matrix_mautrix_discord_version: v0.7.6 +matrix_bridge_mautrix_discord_version: v0.7.7 # See: https://mau.dev/mautrix/discord/container_registry -matrix_mautrix_discord_container_image: "{{ matrix_mautrix_discord_container_image_registry_prefix }}mautrix/discord:{{ matrix_mautrix_discord_version }}" -matrix_mautrix_discord_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_discord_container_image_self_build else matrix_mautrix_discord_container_image_registry_prefix_upstream }}" -matrix_mautrix_discord_container_image_registry_prefix_upstream: "{{ matrix_mautrix_discord_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_discord_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_discord_container_image_force_pull: "{{ matrix_mautrix_discord_container_image.endswith(':latest') }}" - -matrix_mautrix_discord_base_path: "{{ matrix_base_data_path }}/mautrix-discord" -matrix_mautrix_discord_config_path: "{{ matrix_mautrix_discord_base_path }}/config" -matrix_mautrix_discord_data_path: "{{ matrix_mautrix_discord_base_path }}/data" -matrix_mautrix_discord_container_src_files_path: "{{ matrix_mautrix_discord_base_path }}/docker-src" - -matrix_mautrix_discord_homeserver_address: "" +matrix_bridge_mautrix_discord_container_image: "{{ matrix_bridge_mautrix_discord_container_image_registry_prefix }}mautrix/discord:{{ matrix_bridge_mautrix_discord_version }}" +matrix_bridge_mautrix_discord_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_discord_container_image_self_build else matrix_bridge_mautrix_discord_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_discord_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_discord_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_discord_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bridge_mautrix_discord_base_path: "{{ matrix_base_data_path }}/mautrix-discord" +matrix_bridge_mautrix_discord_config_path: "{{ matrix_bridge_mautrix_discord_base_path }}/config" +matrix_bridge_mautrix_discord_data_path: "{{ matrix_bridge_mautrix_discord_base_path }}/data" +matrix_bridge_mautrix_discord_container_src_files_path: "{{ matrix_bridge_mautrix_discord_base_path }}/docker-src" + +matrix_bridge_mautrix_discord_homeserver_address: "" # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_mautrix_discord_homeserver_async_media: false -matrix_mautrix_discord_homeserver_domain: "{{ matrix_domain }}" -matrix_mautrix_discord_appservice_address: "http://matrix-mautrix-discord:8080" +matrix_bridge_mautrix_discord_homeserver_async_media: false +matrix_bridge_mautrix_discord_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_mautrix_discord_appservice_address: "http://matrix-mautrix-discord:8080" -matrix_mautrix_discord_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_discord_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" -matrix_mautrix_discord_bridge_command_prefix: "!discord" +matrix_bridge_mautrix_discord_bridge_command_prefix: "!discord" # Publicly accessible base URL that Discord can use to reach the bridge, used for avatars in relay mode. # If not set, avatars will not be bridged. Only the /mautrix-discord/avatar/{server}/{id}/{hash} endpoint is used on this address. # This should not have a trailing slash, the endpoint above will be appended to the provided address. -matrix_mautrix_discord_bridge_public_address: "{{ (matrix_mautrix_discord_scheme + '://' + matrix_mautrix_discord_hostname + (matrix_mautrix_discord_path_prefix if matrix_mautrix_discord_path_prefix != '/' else '')) if matrix_mautrix_discord_hostname else '' }}" +matrix_bridge_mautrix_discord_bridge_public_address: "{{ (matrix_bridge_mautrix_discord_scheme + '://' + matrix_bridge_mautrix_discord_hostname + (matrix_bridge_mautrix_discord_path_prefix if matrix_bridge_mautrix_discord_path_prefix != '/' else '')) if matrix_bridge_mautrix_discord_hostname else '' }}" # A random key used to sign the avatar URLs. The bridge will only accept requests with a valid signature. -matrix_mautrix_discord_bridge_avatar_proxy_key: '' +matrix_bridge_mautrix_discord_bridge_avatar_proxy_key: '' # Localpart template of MXIDs for Discord users. # {{ '{{.}}' }} is replaced with the internal ID of the Discord user. -matrix_mautrix_discord_bridge_username_template: "{% raw %}discord_{{.}}{% endraw %}" +matrix_bridge_mautrix_discord_bridge_username_template: "{% raw %}discord_{{.}}{% endraw %}" # Displayname template for Discord users. This is also used as the room name in DMs if private_chat_portal_meta is enabled. -matrix_mautrix_discord_bridge_displayname_template: "{% raw %}{{or .GlobalName .Username}}{{if .Bot}} (bot){{end}} (Discord){% endraw %}" +matrix_bridge_mautrix_discord_bridge_displayname_template: "{% raw %}{{or .GlobalName .Username}}{{if .Bot}} (bot){{end}} (Discord){% endraw %}" # Displayname template for Discord channels (bridged as rooms, or spaces when type=4). -matrix_mautrix_discord_bridge_channel_name_template: "{% raw %}{{if or (eq .Type 3) (eq .Type 4)}}{{.Name}}{{else}}#{{.Name}}{{end}}{% endraw %}" +matrix_bridge_mautrix_discord_bridge_channel_name_template: "{% raw %}{{if or (eq .Type 3) (eq .Type 4)}}{{.Name}}{{else}}#{{.Name}}{{end}}{% endraw %}" # Displayname template for Discord guilds (bridged as spaces). -matrix_mautrix_discord_bridge_guild_name_template: "{% raw %}{{.Name}}{% endraw %}" +matrix_bridge_mautrix_discord_bridge_guild_name_template: "{% raw %}{{.Name}}{% endraw %}" -matrix_mautrix_discord_bridge_permissions: | +matrix_bridge_mautrix_discord_bridge_permissions: | {{ - {'*': 'relay', matrix_mautrix_discord_homeserver_domain: 'user'} + {'*': 'relay', matrix_bridge_mautrix_discord_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} -matrix_mautrix_discord_container_network: '' +matrix_bridge_mautrix_discord_container_network: '' -matrix_mautrix_discord_container_additional_networks: "{{ matrix_mautrix_discord_container_additional_networks_auto + matrix_mautrix_discord_container_additional_networks_custom }}" -matrix_mautrix_discord_container_additional_networks_auto: [] -matrix_mautrix_discord_container_additional_networks_custom: [] +matrix_bridge_mautrix_discord_container_additional_networks: "{{ matrix_bridge_mautrix_discord_container_additional_networks_auto + matrix_bridge_mautrix_discord_container_additional_networks_custom }}" +matrix_bridge_mautrix_discord_container_additional_networks_auto: [] +matrix_bridge_mautrix_discord_container_additional_networks_custom: [] -# matrix_mautrix_discord_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_mautrix_discord_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_discord_container_labels_additional_labels`. -matrix_mautrix_discord_container_labels_traefik_enabled: true -matrix_mautrix_discord_container_labels_traefik_docker_network: "{{ matrix_mautrix_discord_container_network }}" -matrix_mautrix_discord_container_labels_traefik_hostname: "{{ matrix_mautrix_discord_hostname }}" +# To inject your own other container labels, see `matrix_bridge_mautrix_discord_container_labels_additional_labels`. +matrix_bridge_mautrix_discord_container_labels_traefik_enabled: true +matrix_bridge_mautrix_discord_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_discord_container_network }}" +matrix_bridge_mautrix_discord_container_labels_traefik_hostname: "{{ matrix_bridge_mautrix_discord_hostname }}" # The path prefix must either be `/` or not end with a slash (e.g. `/matrix-alertmanager-receiver`). -matrix_mautrix_discord_container_labels_traefik_path_prefix: "{{ matrix_mautrix_discord_path_prefix }}" -matrix_mautrix_discord_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_discord_container_labels_traefik_tls_certResolver: default # noqa var-naming +matrix_bridge_mautrix_discord_container_labels_traefik_path_prefix: "{{ matrix_bridge_mautrix_discord_path_prefix }}" +matrix_bridge_mautrix_discord_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_discord_container_labels_traefik_tls_certResolver: default # noqa var-naming # Controls whether labels will be added that expose the bridge's avatar proxy (`/mautrix-discord/avatar/{server}/{id}/{hash}`). -# See: matrix_mautrix_discord_bridge_public_address -matrix_mautrix_discord_container_labels_avatar_proxy_enabled: "{{ matrix_mautrix_discord_bridge_public_address != '' }}" -matrix_mautrix_discord_container_labels_avatar_proxy_hostname: "{{ matrix_mautrix_discord_container_labels_traefik_hostname }}" -matrix_mautrix_discord_container_labels_avatar_proxy_path_prefix: "{{ matrix_mautrix_discord_container_labels_traefik_path_prefix if matrix_mautrix_discord_container_labels_traefik_path_prefix == '/' else (matrix_mautrix_discord_container_labels_traefik_path_prefix + '/') }}mautrix-discord/avatar" -matrix_mautrix_discord_container_labels_avatar_proxy_traefik_rule: "Host(`{{ matrix_mautrix_discord_container_labels_traefik_hostname }}`) && PathPrefix(`{{ matrix_mautrix_discord_container_labels_avatar_proxy_path_prefix }}`)" -matrix_mautrix_discord_container_labels_avatar_proxy_traefik_priority: 0 -matrix_mautrix_discord_container_labels_avatar_proxy_traefik_entrypoints: "{{ matrix_mautrix_discord_container_labels_traefik_entrypoints }}" -matrix_mautrix_discord_container_labels_avatar_proxy_traefik_tls: "{{ matrix_mautrix_discord_container_labels_avatar_proxy_traefik_entrypoints != 'web' }}" -matrix_mautrix_discord_container_labels_avatar_proxy_traefik_tls_certResolver: "{{ matrix_mautrix_discord_container_labels_traefik_tls_certResolver }}" # noqa var-naming - -# matrix_mautrix_discord_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# See: matrix_bridge_mautrix_discord_bridge_public_address +matrix_bridge_mautrix_discord_container_labels_avatar_proxy_enabled: "{{ matrix_bridge_mautrix_discord_bridge_public_address != '' }}" +matrix_bridge_mautrix_discord_container_labels_avatar_proxy_hostname: "{{ matrix_bridge_mautrix_discord_container_labels_traefik_hostname }}" +matrix_bridge_mautrix_discord_container_labels_avatar_proxy_path_prefix: "{{ matrix_bridge_mautrix_discord_container_labels_traefik_path_prefix if matrix_bridge_mautrix_discord_container_labels_traefik_path_prefix == '/' else (matrix_bridge_mautrix_discord_container_labels_traefik_path_prefix + '/') }}mautrix-discord/avatar" +matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_rule: "Host(`{{ matrix_bridge_mautrix_discord_container_labels_traefik_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_discord_container_labels_avatar_proxy_path_prefix }}`)" +matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_priority: 0 +matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_entrypoints: "{{ matrix_bridge_mautrix_discord_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_tls: "{{ matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_discord_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_discord_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_discord_container_labels_additional_labels: | +# matrix_bridge_mautrix_discord_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_discord_container_labels_additional_labels: '' +matrix_bridge_mautrix_discord_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_discord_container_extra_arguments: [] +matrix_bridge_mautrix_discord_container_extra_arguments: [] # List of systemd services that matrix-mautrix-discord.service depends on. -matrix_mautrix_discord_systemd_required_services_list: "{{ matrix_mautrix_discord_systemd_required_services_list_default + matrix_mautrix_discord_systemd_required_services_list_auto + matrix_mautrix_discord_systemd_required_services_list_custom }}" -matrix_mautrix_discord_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_discord_systemd_required_services_list_auto: [] -matrix_mautrix_discord_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_discord_systemd_required_services_list: "{{ matrix_bridge_mautrix_discord_systemd_required_services_list_default + matrix_bridge_mautrix_discord_systemd_required_services_list_auto + matrix_bridge_mautrix_discord_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_discord_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_discord_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_discord_systemd_required_services_list_custom: [] # List of systemd services that matrix-mautrix-discord.service wants -matrix_mautrix_discord_systemd_wanted_services_list: [] +matrix_bridge_mautrix_discord_systemd_wanted_services_list: [] -matrix_mautrix_discord_appservice_token: '' -matrix_mautrix_discord_homeserver_token: '' +matrix_bridge_mautrix_discord_appservice_token: '' +matrix_bridge_mautrix_discord_homeserver_token: '' -matrix_mautrix_discord_appservice_bot_username: discordbot -matrix_mautrix_discord_appservice_bot_displayname: Discord bridge bot -matrix_mautrix_discord_appservice_bot_avatar: mxc://maunium.net/nIdEykemnwdisvHbpxflpDlC +matrix_bridge_mautrix_discord_appservice_bot_username: discordbot +matrix_bridge_mautrix_discord_appservice_bot_displayname: Discord bridge bot +matrix_bridge_mautrix_discord_appservice_bot_avatar: mxc://maunium.net/nIdEykemnwdisvHbpxflpDlC -matrix_mautrix_discord_provisioning_shared_secret: disable +matrix_bridge_mautrix_discord_provisioning_shared_secret: disable # Minimum severity of journal log messages. # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_discord_logging_level: 'warn' +matrix_bridge_mautrix_discord_logging_level: 'warn' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_mautrix_discord_federate_rooms: true +matrix_bridge_mautrix_discord_federate_rooms: true # Database-related configuration fields. # # To use SQLite, stick to these defaults. # # To use Postgres: -# - change the engine (`matrix_mautrix_discord_database_engine: 'postgres'`) -# - adjust your database credentials via the `matrix_mautrix_discord_database_*` variables -matrix_mautrix_discord_database_engine: 'sqlite' +# - change the engine (`matrix_bridge_mautrix_discord_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_mautrix_discord_database_*` variables +matrix_bridge_mautrix_discord_database_engine: 'sqlite' -matrix_mautrix_discord_sqlite_database_path_local: "{{ matrix_mautrix_discord_data_path }}/mautrix-discord.db" -matrix_mautrix_discord_sqlite_database_path_in_container: "/data/mautrix-discord.db" +matrix_bridge_mautrix_discord_sqlite_database_path_local: "{{ matrix_bridge_mautrix_discord_data_path }}/mautrix-discord.db" +matrix_bridge_mautrix_discord_sqlite_database_path_in_container: "/data/mautrix-discord.db" -matrix_mautrix_discord_database_username: 'matrix_mautrix_discord' -matrix_mautrix_discord_database_password: 'some-password' -matrix_mautrix_discord_database_hostname: '' -matrix_mautrix_discord_database_port: 5432 -matrix_mautrix_discord_database_name: 'matrix_mautrix_discord' -matrix_mautrix_discord_database_sslmode: disable +matrix_bridge_mautrix_discord_database_username: 'matrix_mautrix_discord' +matrix_bridge_mautrix_discord_database_password: 'some-password' +matrix_bridge_mautrix_discord_database_hostname: '' +matrix_bridge_mautrix_discord_database_port: 5432 +matrix_bridge_mautrix_discord_database_name: 'matrix_mautrix_discord' +matrix_bridge_mautrix_discord_database_sslmode: disable -matrix_mautrix_discord_database_connection_string: 'postgresql://{{ matrix_mautrix_discord_database_username }}:{{ matrix_mautrix_discord_database_password }}@{{ matrix_mautrix_discord_database_hostname }}:{{ matrix_mautrix_discord_database_port }}/{{ matrix_mautrix_discord_database_name }}?sslmode={{ matrix_mautrix_discord_database_sslmode }}' +matrix_bridge_mautrix_discord_database_connection_string: 'postgresql://{{ matrix_bridge_mautrix_discord_database_username }}:{{ matrix_bridge_mautrix_discord_database_password }}@{{ matrix_bridge_mautrix_discord_database_hostname }}:{{ matrix_bridge_mautrix_discord_database_port }}/{{ matrix_bridge_mautrix_discord_database_name }}?sslmode={{ matrix_bridge_mautrix_discord_database_sslmode }}' -matrix_mautrix_discord_appservice_database_type: "{{ - { - 'sqlite': 'sqlite3', - 'postgres':'postgres', - }[matrix_mautrix_discord_database_engine] -}}" +matrix_bridge_mautrix_discord_appservice_database_type: "{{ { + 'sqlite': 'sqlite3', + 'postgres': 'postgres', +}[matrix_bridge_mautrix_discord_database_engine] }}" -matrix_mautrix_discord_appservice_database_uri: "{{ - { - 'sqlite': matrix_mautrix_discord_sqlite_database_path_in_container, - 'postgres': matrix_mautrix_discord_database_connection_string, - }[matrix_mautrix_discord_database_engine] -}}" +matrix_bridge_mautrix_discord_appservice_database_uri: "{{ { + 'sqlite': matrix_bridge_mautrix_discord_sqlite_database_path_in_container, + 'postgres': matrix_bridge_mautrix_discord_database_connection_string, +}[matrix_bridge_mautrix_discord_database_engine] }}" -matrix_mautrix_discord_bridge_login_shared_secret_map: "{{ matrix_mautrix_discord_bridge_login_shared_secret_map_auto | combine(matrix_mautrix_discord_bridge_login_shared_secret_map_custom) }}" -matrix_mautrix_discord_bridge_login_shared_secret_map_auto: {} -matrix_mautrix_discord_bridge_login_shared_secret_map_custom: {} +matrix_bridge_mautrix_discord_bridge_login_shared_secret_map: "{{ matrix_bridge_mautrix_discord_bridge_login_shared_secret_map_auto | combine(matrix_bridge_mautrix_discord_bridge_login_shared_secret_map_custom) }}" +matrix_bridge_mautrix_discord_bridge_login_shared_secret_map_auto: {} +matrix_bridge_mautrix_discord_bridge_login_shared_secret_map_custom: {} # Servers to always allow double puppeting from -matrix_mautrix_discord_bridge_double_puppet_server_map: "{{ matrix_mautrix_discord_bridge_double_puppet_server_map_default | combine(matrix_mautrix_discord_bridge_double_puppet_server_map_auto) | combine(matrix_mautrix_discord_bridge_double_puppet_server_map_custom) }}" -matrix_mautrix_discord_bridge_double_puppet_server_map_default: |- +matrix_bridge_mautrix_discord_bridge_double_puppet_server_map: "{{ matrix_bridge_mautrix_discord_bridge_double_puppet_server_map_default | combine(matrix_bridge_mautrix_discord_bridge_double_puppet_server_map_auto) | combine(matrix_bridge_mautrix_discord_bridge_double_puppet_server_map_custom) }}" +matrix_bridge_mautrix_discord_bridge_double_puppet_server_map_default: |- {{ {} | combine({ - matrix_beeper_linkedin_homeserver_domain: matrix_beeper_linkedin_homeserver_address + matrix_bridge_mautrix_discord_homeserver_domain: matrix_bridge_mautrix_discord_homeserver_address }) }} -matrix_mautrix_discord_bridge_double_puppet_server_map_auto: {} -matrix_mautrix_discord_bridge_double_puppet_server_map_custom: {} +matrix_bridge_mautrix_discord_bridge_double_puppet_server_map_auto: {} +matrix_bridge_mautrix_discord_bridge_double_puppet_server_map_custom: {} # Default mautrix-discord configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_discord_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_discord_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_discord_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_discord_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_discord_configuration_extension_yaml: | +matrix_bridge_mautrix_discord_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_discord_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_discord_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_discord_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_discord_configuration_yaml`. -matrix_mautrix_discord_configuration_extension: "{{ matrix_mautrix_discord_configuration_extension_yaml | from_yaml if matrix_mautrix_discord_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_discord_configuration_extension: "{{ matrix_bridge_mautrix_discord_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_discord_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_discord_configuration_yaml`. -matrix_mautrix_discord_configuration: "{{ matrix_mautrix_discord_configuration_yaml | from_yaml | combine(matrix_mautrix_discord_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_discord_configuration_yaml`. +matrix_bridge_mautrix_discord_configuration: "{{ matrix_bridge_mautrix_discord_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_discord_configuration_extension, recursive=True) }}" -matrix_mautrix_discord_registration_yaml: | +matrix_bridge_mautrix_discord_registration_yaml: | id: discord - url: {{ matrix_mautrix_discord_appservice_address }} - as_token: "{{ matrix_mautrix_discord_appservice_token }}" - hs_token: "{{ matrix_mautrix_discord_homeserver_token }}" + url: {{ matrix_bridge_mautrix_discord_appservice_address }} + as_token: "{{ matrix_bridge_mautrix_discord_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_discord_homeserver_token }}" # See https://github.com/mautrix/signal/issues/43 - sender_localpart: _bot_{{ matrix_mautrix_discord_appservice_bot_username }} + sender_localpart: _bot_{{ matrix_bridge_mautrix_discord_appservice_bot_username }} rate_limited: false namespaces: users: - - regex: '^@discord_[0-9]+:{{ matrix_mautrix_discord_homeserver_domain | regex_escape }}$' + - regex: '^@discord_[0-9]+:{{ matrix_bridge_mautrix_discord_homeserver_domain | regex_escape }}$' exclusive: true - exclusive: true - regex: '^@{{ matrix_mautrix_discord_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_discord_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_mautrix_discord_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_discord_homeserver_domain | regex_escape }}$' de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_mautrix_discord_msc4190_enabled | to_json }} + io.element.msc4190: {{ matrix_bridge_mautrix_discord_msc4190_enabled | to_json }} -matrix_mautrix_discord_registration: "{{ matrix_mautrix_discord_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_discord_registration: "{{ matrix_bridge_mautrix_discord_registration_yaml | from_yaml }}" # Enable End-to-bridge encryption -matrix_mautrix_discord_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_discord_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_mautrix_discord_bridge_encryption_require: false -matrix_mautrix_discord_bridge_encryption_appservice: false -matrix_mautrix_discord_bridge_encryption_plaintext_mentions: false -matrix_mautrix_discord_bridge_encryption_key_sharing_allow: "{{ matrix_mautrix_discord_bridge_encryption_allow }}" +matrix_bridge_mautrix_discord_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_discord_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_discord_bridge_encryption_require: false +matrix_bridge_mautrix_discord_bridge_encryption_appservice: false +matrix_bridge_mautrix_discord_bridge_encryption_plaintext_mentions: false +matrix_bridge_mautrix_discord_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_mautrix_discord_bridge_encryption_allow }}" # On Conduit versions before 0.5.0 this option prevented users from joining spaces created by the bridge. # Setting this to false fixed the issue. -matrix_mautrix_discord_bridge_restricted_rooms: true +matrix_bridge_mautrix_discord_bridge_restricted_rooms: true -# matrix_mautrix_discord_restart_necessary controls whether the service +# matrix_bridge_mautrix_discord_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -254,4 +249,4 @@ matrix_mautrix_discord_bridge_restricted_rooms: true # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_discord_restart_necessary: false +matrix_bridge_mautrix_discord_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-discord/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/converge.yml new file mode 100644 index 000000000..065ec95c2 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-discord Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-discord Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-discord is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-discord systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-discord.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-discord/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/molecule.yml new file mode 100644 index 000000000..0ad124fc5 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/molecule.yml @@ -0,0 +1,93 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-discord-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_discord_container_network: mautrix-discord-molecule + + # The stub prepare.yml stands up. Not a real homeserver, and nothing is asserted + # about it. There is deliberately no Discord on the other side either. + matrix_bridge_mautrix_discord_homeserver_address: http://matrix.molecule.local:8008 + + # Postgres, because that is what `group_vars/matrix_servers` selects whenever postgres + # is enabled - which is the default, so it is what essentially every real deployment + # runs. prepare.yml stands one up. Name and user differ from the role's defaults, so + # reaching the database proves the role built its connection string out of these. + matrix_bridge_mautrix_discord_database_engine: postgres + matrix_bridge_mautrix_discord_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_discord_database_name: molecule_discord + matrix_bridge_mautrix_discord_database_username: molecule_discord + matrix_bridge_mautrix_discord_database_password: molecule_pg_password_a17f34 + + # Here these only have to reach the rendered configuration and the registration. + matrix_bridge_mautrix_discord_appservice_token: molecule_as_token_d15c07 + matrix_bridge_mautrix_discord_homeserver_token: molecule_hs_token_a4e2b8 + + # Different from the role's defaults, so verify.yml can tell what the role rendered + # apart from what the bridge would have chosen. + matrix_bridge_mautrix_discord_appservice_bot_username: molecule-discordbot + matrix_bridge_mautrix_discord_homeserver_domain: molecule.local + matrix_bridge_mautrix_discord_bridge_command_prefix: "!molecule-discord" + # The role defaults to `warn`, the bridge's own shipped configuration to `debug`. + # `info` is neither. + matrix_bridge_mautrix_discord_logging_level: info + + # Unlike most bridge roles here, mautrix-discord *requires* a public address: + # `validate_config.yml` fails without one, and it is derived from these three. + # Discord fetches avatars over it in relay mode. Nothing reaches it in this scenario, + # but it has to be set for the role to run at all. + # + # A non-`/` path prefix and a non-default scheme are chosen so the avatar-proxy labels + # verify.yml reads can only look the way they do if the role composed them. + matrix_bridge_mautrix_discord_hostname: discord.molecule.local + matrix_bridge_mautrix_discord_path_prefix: /discord-bridge + matrix_bridge_mautrix_discord_scheme: http + matrix_bridge_mautrix_discord_bridge_avatar_proxy_key: molecule_avatar_proxy_key_7c1d + + # verify.yml runs as its own play, where the role's defaults are out of scope, + # so the paths it reads are pinned here to match what the role derives. + matrix_bridge_mautrix_discord_base_path: /matrix/mautrix-discord + matrix_bridge_mautrix_discord_config_path: /matrix/mautrix-discord/config + matrix_bridge_mautrix_discord_data_path: /matrix/mautrix-discord/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-discord/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/prepare.yml new file mode 100644 index 000000000..25d1d3f66 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/prepare.yml @@ -0,0 +1,89 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-discord Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks set owner/group by name, which Ansible resolves through the + # passwd database, so they have to exist first. `matrix-base` creates them for real. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_discord_container_network }}" + register: mautrix_discord_molecule_network + changed_when: mautrix_discord_molecule_network.rc == 0 + failed_when: + - mautrix_discord_molecule_network.rc != 0 + - "'already exists' not in mautrix_discord_molecule_network.stderr" + + # The bridge contacts the homeserver as it starts and refuses to run if /whoami does not + # name the bot user it was configured as. See molecule-shared/homeserver-stub.py. + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_discord_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_discord_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_discord_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_discord_database_password }}" + + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_discord_container_network }}" + molecule_shared_stub_server_name: molecule.local + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_discord_appservice_bot_username }}:{{ matrix_bridge_mautrix_discord_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-discord/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-discord/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/verify.yml new file mode 100644 index 000000000..64875bea3 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-discord/molecule/default/verify.yml @@ -0,0 +1,242 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the bridge starts, reads the configuration and registration the role rendered, opens +# its appservice port, is the version the role pins, and composed the avatar-proxy labels out +# of the hostname, scheme and path prefix it was given. +# +# It does NOT bridge anything: there is no Discord on the other side, and deliberately never +# will be, because that would need a Discord account. See docs/molecule-testing.md. +- name: Verify mautrix-discord + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + + vars: + # The role derives this from scheme + hostname + path prefix. Role defaults are out of + # scope in this play, so it is recomposed from the same three values molecule.yml pinned. + mautrix_discord_expected_public_address: >- + {{ matrix_bridge_mautrix_discord_scheme }}://{{ matrix_bridge_mautrix_discord_hostname }}{{ matrix_bridge_mautrix_discord_path_prefix }} + mautrix_discord_expected_avatar_proxy_path_prefix: "{{ matrix_bridge_mautrix_discord_path_prefix }}/mautrix-discord/avatar" + + tasks: + # From the role's own defaults rather than pinned in molecule.yml, so the version + # assertion compares the running image against what the role ships, not the scenario. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_discord_role_defaults + + - name: Wait for the mautrix-discord service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-discord.service + register: mautrix_discord_service + until: mautrix_discord_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # `Restart=always` means a bridge crash-looping on unreadable config still reports + # `active`, so the restart counter is checked too. Asserted `is defined` because + # `| int` turns a missing property into 0 and would pass vacuously. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_discord_service.status.ActiveState == 'active' + - mautrix_discord_service.status.NRestarts is defined + - mautrix_discord_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-discord.service is + {{ mautrix_discord_service.status.ActiveState | default('unknown') }} + after {{ mautrix_discord_service.status.NRestarts | default('?') }} + automatic restart(s) + success_msg: "matrix-mautrix-discord.service is active and has not restarted" + + # The appservice listener is where a homeserver would push transactions. It opening at all + # means the bridge got through reading its configuration and setting itself up. + - name: Wait for the bridge to open its appservice port + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_discord_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - "http://matrix-mautrix-discord:8080/_matrix/mau/live" + register: mautrix_discord_live + changed_when: false + until: "'HTTP_STATUS=000' not in mautrix_discord_live.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge answers on its appservice port + ansible.builtin.assert: + that: + - "'HTTP_STATUS=000' not in mautrix_discord_live.stdout" + fail_msg: >- + The bridge did not answer on its appservice port + ({{ mautrix_discord_live.stdout | default('no output') }}) + success_msg: "The bridge answers on its appservice port" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_discord_config_path }}/config.yaml" + register: mautrix_discord_config_file + + # Each differs from what the bridge would use on its own, so their presence rules out a + # coincidence. The public address in particular is composed by the role out of three + # separate variables. + # + # Asserted against the parsed document rather than by substring, so a value landing under + # the wrong key cannot pass. + - name: Assert the rendered configuration carries this scenario's values + ansible.builtin.assert: + that: + - mautrix_discord_config.homeserver.address == matrix_bridge_mautrix_discord_homeserver_address + - mautrix_discord_config.homeserver.domain == matrix_bridge_mautrix_discord_homeserver_domain + - mautrix_discord_config.appservice.bot.username == matrix_bridge_mautrix_discord_appservice_bot_username + - mautrix_discord_config.appservice.as_token == matrix_bridge_mautrix_discord_appservice_token + - mautrix_discord_config.appservice.hs_token == matrix_bridge_mautrix_discord_homeserver_token + - mautrix_discord_config.appservice.database.type == 'postgres' + - mautrix_discord_config.bridge.command_prefix == matrix_bridge_mautrix_discord_bridge_command_prefix + - mautrix_discord_config.bridge.avatar_proxy_key == matrix_bridge_mautrix_discord_bridge_avatar_proxy_key + - mautrix_discord_config.bridge.public_address == mautrix_discord_expected_public_address | trim + - mautrix_discord_config.logging.min_level == matrix_bridge_mautrix_discord_logging_level + fail_msg: "The rendered configuration does not carry the scenario's values" + success_msg: "The rendered configuration carries the scenario's values" + vars: + mautrix_discord_config: "{{ mautrix_discord_config_file.content | b64decode | from_yaml }}" + + # The role generates the registration; the bridge only consumes it. `sender_localpart` + # carries the role's own `_bot_` prefixing, not something the bridge would produce. + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_discord_config_path }}/registration.yaml" + register: mautrix_discord_registration_file + + - name: Assert the registration carries the scenario's tokens and bot user + ansible.builtin.assert: + that: + - mautrix_discord_registration.as_token == matrix_bridge_mautrix_discord_appservice_token + - mautrix_discord_registration.hs_token == matrix_bridge_mautrix_discord_homeserver_token + - mautrix_discord_registration.sender_localpart == '_bot_' ~ matrix_bridge_mautrix_discord_appservice_bot_username + - mautrix_discord_registration.url == 'http://matrix-mautrix-discord:8080' + - mautrix_discord_bot_user_regex in (mautrix_discord_registration.namespaces.users | map(attribute='regex') | list) + fail_msg: "The appservice registration does not carry the scenario's tokens and bot user" + success_msg: "The appservice registration carries the scenario's tokens and bot user" + vars: + mautrix_discord_registration: "{{ mautrix_discord_registration_file.content | b64decode | from_yaml }}" + mautrix_discord_bot_user_regex: "^@{{ matrix_bridge_mautrix_discord_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_discord_homeserver_domain | regex_escape }}$" + + # Stronger than the file-on-disk check sqlite allowed: the bridge can only have created + # tables here by resolving the hostname, authenticating with the credentials the role + # rendered, and running its migrations to completion. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_discord_database_username }} + - --dbname={{ matrix_bridge_mautrix_discord_database_name }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: mautrix_discord_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the database the role pointed it at + ansible.builtin.assert: + that: + - mautrix_discord_tables.rc == 0 + - "'version' in mautrix_discord_table_names" + - mautrix_discord_table_names | length > 5 + fail_msg: >- + The bridge did not create its schema in + {{ matrix_bridge_mautrix_discord_database_name }} + (found {{ mautrix_discord_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the database the role pointed it at" + vars: + mautrix_discord_table_names: "{{ mautrix_discord_tables.stdout_lines | select | list }}" + + - name: Read the image of the running container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-discord + - --format + - "{{ '{{' }} .Config.Image {{ '}}' }}" + register: mautrix_discord_image + changed_when: false + + - name: Assert the running container is the version defaults/main.yml pins + ansible.builtin.assert: + that: + - mautrix_discord_role_defaults.matrix_bridge_mautrix_discord_version in mautrix_discord_image.stdout + fail_msg: >- + The running container is {{ mautrix_discord_image.stdout }}, which does + not carry the pinned version + {{ mautrix_discord_role_defaults.matrix_bridge_mautrix_discord_version }} + success_msg: "The running container is the version defaults/main.yml pins" + + # The avatar proxy is this role's own reverse-proxy wiring. The labels only appear because + # a public address was configured, and the role composes their hostname and path prefix + # rather than copying them from a variable. + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_discord_base_path }}/labels" + register: mautrix_discord_labels + + - name: Assert the avatar-proxy labels were composed from the scenario's hostname and path prefix + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_discord_labels_rendered" + - "'traefik.docker.network=' ~ matrix_bridge_mautrix_discord_container_network in mautrix_discord_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-discord-avatar-proxy.rule=Host(`' ~ matrix_bridge_mautrix_discord_hostname ~ '`) && PathPrefix(`' ~ mautrix_discord_expected_avatar_proxy_path_prefix ~ '`)' in mautrix_discord_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-discord-strip-prefix.stripprefix.prefixes=' ~ matrix_bridge_mautrix_discord_path_prefix in mautrix_discord_labels_rendered" + fail_msg: >- + The avatar-proxy labels do not carry the scenario's hostname + ({{ matrix_bridge_mautrix_discord_hostname }}) and path prefix + ({{ mautrix_discord_expected_avatar_proxy_path_prefix }}) + success_msg: "The avatar-proxy labels were composed from the scenario's hostname and path prefix" + vars: + mautrix_discord_labels_rendered: "{{ mautrix_discord_labels.content | b64decode }}" + + # The label file is fed to `docker create --label-file`, so a wrongly rendered label is + # not cosmetic: it stops the container being created at all. Reading them back off the + # running container proves Docker accepted them. + - name: Read the labels Docker attached to the running container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-discord + - --format + - "{{ '{{' }} index .Config.Labels \"traefik.http.routers.matrix-mautrix-discord-avatar-proxy.rule\" {{ '}}' }}" + register: mautrix_discord_container_label + changed_when: false + + - name: Assert Docker carries the avatar-proxy router label the role rendered + ansible.builtin.assert: + that: + - matrix_bridge_mautrix_discord_hostname in mautrix_discord_container_label.stdout + - mautrix_discord_expected_avatar_proxy_path_prefix in mautrix_discord_container_label.stdout + fail_msg: >- + The running container's avatar-proxy router label is + "{{ mautrix_discord_container_label.stdout }}" + success_msg: "The running container carries the avatar-proxy router label the role rendered" diff --git a/roles/custom/matrix-bridge-mautrix-discord/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-discord/tasks/main.yml index dc5ccdd4e..02669ad1e 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-discord/tasks/main.yml @@ -11,15 +11,15 @@ - install-all - install-mautrix-discord block: - - when: matrix_mautrix_discord_enabled | bool + - when: matrix_bridge_mautrix_discord_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_discord_enabled | bool + - when: matrix_bridge_mautrix_discord_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mautrix-discord block: - - when: not matrix_mautrix_discord_enabled | bool + - when: not matrix_bridge_mautrix_discord_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-discord/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-discord/tasks/setup_install.yml index 31c1d576c..92aecc6a0 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-discord/tasks/setup_install.yml @@ -8,32 +8,32 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_discord_migration_requires_restart: false + matrix_bridge_mautrix_discord_migration_requires_restart: false -- when: "matrix_mautrix_discord_database_engine == 'postgres'" +- when: "matrix_bridge_mautrix_discord_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mautrix_discord_sqlite_database_path_local }}" - register: matrix_mautrix_discord_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mautrix_discord_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_discord_sqlite_database_path_local_stat_result - - when: "matrix_mautrix_discord_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mautrix_discord_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mautrix_discord_sqlite_database_path_local }}" - dst: "{{ matrix_mautrix_discord_database_connection_string }}" + src: "{{ matrix_bridge_mautrix_discord_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_discord_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mautrix_discord_database_engine' + engine_variable_name: 'matrix_bridge_mautrix_discord_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-mautrix-discord.service'] pgloader_options: ['--with "quote identifiers"'] - ansible.builtin.set_fact: - matrix_mautrix_discord_migration_requires_restart: true + matrix_bridge_mautrix_discord_migration_requires_restart: true - name: Ensure Mautrix Discord paths exists ansible.builtin.file: @@ -43,80 +43,87 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_discord_base_path }}", when: true} - - {path: "{{ matrix_mautrix_discord_config_path }}", when: true} - - {path: "{{ matrix_mautrix_discord_data_path }}", when: true} - - {path: "{{ matrix_mautrix_discord_container_src_files_path }}", when: "{{ matrix_mautrix_discord_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_discord_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_discord_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_discord_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_discord_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_discord_container_image_self_build }}"} when: item.when | bool - name: Ensure Mautrix Discord image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_discord_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_discord_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_discord_container_image_force_pull }}" - when: not matrix_mautrix_discord_container_image_self_build - register: matrix_mautrix_discord_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_discord_container_image }}" + pull: always + when: not matrix_bridge_mautrix_discord_container_image_self_build + register: matrix_bridge_mautrix_discord_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_discord_container_image_pull_result is not failed + until: matrix_bridge_mautrix_discord_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix discord repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_discord_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_discord_container_image_self_build | bool" - name: Ensure Mautrix discord repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_mautrix_discord_container_image_self_build_repo }}" - dest: "{{ matrix_mautrix_discord_container_src_files_path }}" - version: "{{ matrix_mautrix_discord_container_image_self_build_branch }}" + repo: "{{ matrix_bridge_mautrix_discord_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_mautrix_discord_container_src_files_path }}" + version: "{{ matrix_bridge_mautrix_discord_container_image_self_build_branch }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_discord_git_pull_results - when: "matrix_mautrix_discord_container_image_self_build | bool" + register: matrix_bridge_mautrix_discord_git_pull_results + when: "matrix_bridge_mautrix_discord_container_image_self_build | bool" - name: Ensure Mautrix discord Docker image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_discord_container_image }}" - source: build - force_source: "{{ matrix_mautrix_discord_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_discord_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_discord_container_src_files_path }}" - pull: true - when: "matrix_mautrix_discord_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_discord_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_discord_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_discord_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_discord_container_image_self_build | bool" + register: matrix_bridge_mautrix_discord_container_image_build_result - name: Ensure mautrix-discord config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_discord_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_discord_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_discord_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_discord_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_discord_config_result + register: matrix_bridge_mautrix_discord_config_result - name: Ensure mautrix-discord registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_discord_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_discord_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_discord_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_discord_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_discord_registration_result + register: matrix_bridge_mautrix_discord_registration_result - name: Ensure mautrix-discord support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_discord_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_discord_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_mautrix_discord_support_files_result + register: matrix_bridge_mautrix_discord_support_files_result - name: Ensure mautrix-discord container network is created + when: matrix_bridge_mautrix_discord_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_discord_container_network }}" + name: "{{ matrix_bridge_mautrix_discord_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -125,18 +132,19 @@ src: "{{ role_path }}/templates/systemd/matrix-mautrix-discord.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-discord.service" mode: '0644' - register: matrix_mautrix_discord_systemd_service_result + register: matrix_bridge_mautrix_discord_systemd_service_result - name: Determine whether matrix-mautrix-discord needs a restart ansible.builtin.set_fact: - matrix_mautrix_discord_restart_necessary: >- + matrix_bridge_mautrix_discord_restart_necessary: >- {{ - matrix_mautrix_discord_migration_requires_restart | default(false) - or matrix_mautrix_discord_config_result.changed | default(false) - or matrix_mautrix_discord_registration_result.changed | default(false) - or matrix_mautrix_discord_support_files_result.changed | default(false) - or matrix_mautrix_discord_systemd_service_result.changed | default(false) - or matrix_mautrix_discord_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_discord_migration_requires_restart | default(false) + or matrix_bridge_mautrix_discord_config_result.changed | default(false) + or matrix_bridge_mautrix_discord_registration_result.changed | default(false) + or matrix_bridge_mautrix_discord_support_files_result.changed | default(false) + or matrix_bridge_mautrix_discord_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_discord_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_discord_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mautrix-discord.service restarted, if necessary @@ -144,4 +152,4 @@ name: "matrix-mautrix-discord.service" state: restarted daemon_reload: true - when: "matrix_mautrix_discord_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_discord_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-discord/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-discord/tasks/setup_uninstall.yml index 0b5ddc54f..d62dd8508 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-discord/tasks/setup_uninstall.yml @@ -8,9 +8,9 @@ - name: Check existence of matrix-mautrix-discord service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-discord.service" - register: matrix_mautrix_discord_service_stat + register: matrix_bridge_mautrix_discord_service_stat -- when: matrix_mautrix_discord_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_discord_service_stat.stat.exists | bool block: - name: Ensure matrix-mautrix-discord is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mautrix-discord/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-discord/tasks/validate_config.yml index aacec0ac7..e5feae150 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-discord/tasks/validate_config.yml @@ -13,16 +13,17 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_discord_login_shared_secret', 'new': ''} - - {'old': 'matrix_mautrix_discord_homeserver_public_address', 'new': 'matrix_mautrix_discord_bridge_public_address'} - - {'old': 'matrix_mautrix_discord_command_prefix', 'new': 'matrix_mautrix_discord_bridge_command_prefix'} - - {'old': 'matrix_mautrix_discord_docker_image_name_prefix', 'new': 'matrix_mautrix_discord_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_discord_docker_image', 'new': 'matrix_mautrix_discord_container_image'} - - {'old': 'matrix_mautrix_discord_docker_image_force_pull', 'new': 'matrix_mautrix_discord_container_image_force_pull'} - - {'old': 'matrix_mautrix_discord_docker_image_registry_prefix', 'new': 'matrix_mautrix_discord_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_discord_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_discord_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_discord_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_discord_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_discord_docker_src_files_path', 'new': 'matrix_mautrix_discord_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_discord_login_shared_secret', 'new': ''} + - {'old': 'matrix_bridge_mautrix_discord_homeserver_public_address', 'new': 'matrix_bridge_mautrix_discord_bridge_public_address'} + - {'old': 'matrix_bridge_mautrix_discord_command_prefix', 'new': 'matrix_bridge_mautrix_discord_bridge_command_prefix'} + - {'old': 'matrix_bridge_mautrix_discord_docker_image_name_prefix', 'new': 'matrix_bridge_mautrix_discord_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_discord_docker_image', 'new': 'matrix_bridge_mautrix_discord_container_image'} + - {'old': 'matrix_bridge_mautrix_discord_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_discord_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_discord_docker_image_registry_prefix', 'new': 'matrix_bridge_mautrix_discord_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_discord_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mautrix_discord_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mautrix_discord_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mautrix_discord_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mautrix_discord_docker_src_files_path', 'new': 'matrix_bridge_mautrix_discord_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_discord_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required mautrix-discord settings not defined ansible.builtin.fail: @@ -30,11 +31,11 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_discord_appservice_token', when: true} - - {'name': 'matrix_mautrix_discord_homeserver_address', when: true} - - {'name': 'matrix_mautrix_discord_homeserver_token', when: true} - - {'name': 'matrix_mautrix_discord_bridge_public_address', when: true} - - {'name': 'matrix_mautrix_discord_container_network', when: true} - - {'name': 'matrix_mautrix_discord_database_hostname', when: "{{ matrix_mautrix_discord_database_engine == 'postgres' }}"} - - {'name': 'matrix_mautrix_discord_container_labels_avatar_proxy_hostname', when: "{{ matrix_mautrix_discord_container_labels_avatar_proxy_enabled }}"} - - {'name': 'matrix_mautrix_discord_container_labels_avatar_proxy_path_prefix', when: "{{ matrix_mautrix_discord_container_labels_avatar_proxy_enabled }}"} + - {'name': 'matrix_bridge_mautrix_discord_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_discord_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_discord_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_discord_bridge_public_address', when: true} + - {'name': 'matrix_bridge_mautrix_discord_container_network', when: true} + - {'name': 'matrix_bridge_mautrix_discord_database_hostname', when: "{{ matrix_bridge_mautrix_discord_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_discord_container_labels_avatar_proxy_hostname', when: "{{ matrix_bridge_mautrix_discord_container_labels_avatar_proxy_enabled }}"} + - {'name': 'matrix_bridge_mautrix_discord_container_labels_avatar_proxy_path_prefix', when: "{{ matrix_bridge_mautrix_discord_container_labels_avatar_proxy_enabled }}"} diff --git a/roles/custom/matrix-bridge-mautrix-discord/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-discord/templates/config.yaml.j2 index 061cc3c82..632dd0285 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-discord/templates/config.yaml.j2 @@ -2,9 +2,9 @@ # Homeserver details. homeserver: # The address that this appservice can use to connect to the homeserver. - address: {{ matrix_mautrix_discord_homeserver_address | to_json }} + address: {{ matrix_bridge_mautrix_discord_homeserver_address | to_json }} # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: {{ matrix_mautrix_discord_homeserver_domain | to_json }} + domain: {{ matrix_bridge_mautrix_discord_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -16,7 +16,7 @@ homeserver: # Endpoint for reporting per-message status. message_send_checkpoint_endpoint: null # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_mautrix_discord_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_mautrix_discord_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -29,7 +29,7 @@ homeserver: # Changing these values requires regeneration of the registration. appservice: # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_mautrix_discord_appservice_address | to_json }} + address: {{ matrix_bridge_mautrix_discord_appservice_address | to_json }} # The hostname and port where this appservice should listen. hostname: 0.0.0.0 @@ -38,13 +38,13 @@ appservice: # Database config. database: # The database type. "sqlite3-fk-wal" and "postgres" are supported. - type: {{ matrix_mautrix_discord_appservice_database_type | to_json }} + type: {{ matrix_bridge_mautrix_discord_appservice_database_type | to_json }} # The database URI. # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. # https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_mautrix_discord_appservice_database_uri | to_json }} + uri: {{ matrix_bridge_mautrix_discord_appservice_database_uri | to_json }} # Maximum number of connections. Mostly relevant for Postgres. max_open_conns: 20 max_idle_conns: 2 @@ -58,11 +58,11 @@ appservice: # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_mautrix_discord_appservice_bot_username | to_json }} + username: {{ matrix_bridge_mautrix_discord_appservice_bot_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. - displayname: {{ matrix_mautrix_discord_appservice_bot_displayname | to_json(ensure_ascii=False) }} - avatar: {{ matrix_mautrix_discord_appservice_bot_avatar | to_json }} + displayname: {{ matrix_bridge_mautrix_discord_appservice_bot_displayname | to_json(ensure_ascii=False) }} + avatar: {{ matrix_bridge_mautrix_discord_appservice_bot_avatar | to_json }} # Whether or not to receive ephemeral events via appservice transactions. # Requires MSC2409 support (i.e. Synapse 1.22+). @@ -74,14 +74,14 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_mautrix_discord_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_discord_homeserver_token | to_json }} + as_token: {{ matrix_bridge_mautrix_discord_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_discord_homeserver_token | to_json }} # Bridge config bridge: # Localpart template of MXIDs for Discord users. # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the Discord user. - username_template: {{ matrix_mautrix_discord_bridge_username_template | to_json }} + username_template: {{ matrix_bridge_mautrix_discord_bridge_username_template | to_json }} # Displayname template for Discord users. This is also used as the room name in DMs if private_chat_portal_meta is enabled. # Available variables: # .ID - Internal user ID @@ -92,7 +92,7 @@ bridge: # .System - Whether the user is an official system user # .Webhook - Whether the user is a webhook and is not an application # .Application - Whether the user is an application - displayname_template: {{ matrix_mautrix_discord_bridge_displayname_template | to_json }} + displayname_template: {{ matrix_bridge_mautrix_discord_bridge_displayname_template | to_json }} # Displayname template for Discord channels (bridged as rooms, or spaces when type=4). # Available variables: # .Name - Channel name, or user displayname (pre-formatted with displayname_template) in DMs. @@ -100,11 +100,11 @@ bridge: # .GuildName - Guild name. # .NSFW - Whether the channel is marked as NSFW. # .Type - Channel type (see values at https://github.com/bwmarrin/discordgo/blob/v0.25.0/structs.go#L251-L267) - channel_name_template: {{ matrix_mautrix_discord_bridge_channel_name_template | to_json }} + channel_name_template: {{ matrix_bridge_mautrix_discord_bridge_channel_name_template | to_json }} # Displayname template for Discord guilds (bridged as spaces). # Available variables: # .Name - Guild name - guild_name_template: {{ matrix_mautrix_discord_bridge_guild_name_template | to_json }} + guild_name_template: {{ matrix_bridge_mautrix_discord_bridge_guild_name_template | to_json }} # Whether to explicitly set the avatar and room name for private chat portal rooms. # If set to `default`, this will be enabled in encrypted rooms and disabled in unencrypted rooms. # If set to `always`, all DM rooms will have explicit names and avatars set. @@ -114,9 +114,9 @@ bridge: # Publicly accessible base URL that Discord can use to reach the bridge, used for avatars in relay mode. # If not set, avatars will not be bridged. Only the /mautrix-discord/avatar/{server}/{id}/{hash} endpoint is used on this address. # This should not have a trailing slash, the endpoint above will be appended to the provided address. - public_address: {{ matrix_mautrix_discord_bridge_public_address | to_json }} + public_address: {{ matrix_bridge_mautrix_discord_bridge_public_address | to_json }} # A random key used to sign the avatar URLs. The bridge will only accept requests with a valid signature. - avatar_proxy_key: {{ matrix_mautrix_discord_bridge_avatar_proxy_key | to_json }} + avatar_proxy_key: {{ matrix_bridge_mautrix_discord_bridge_avatar_proxy_key | to_json }} portal_message_buffer: 128 @@ -131,7 +131,7 @@ bridge: message_error_notices: true # Should the bridge use space-restricted join rules instead of invite-only for guild rooms? # This can avoid unnecessary invite events in guild rooms when members are synced in. - restricted_rooms: {{ matrix_mautrix_discord_bridge_restricted_rooms | to_json }} + restricted_rooms: {{ matrix_bridge_mautrix_discord_bridge_restricted_rooms | to_json }} # Should the bridge automatically join the user to threads on Discord when the thread is opened on Matrix? # This only works with clients that support thread read receipts (MSC3771 added in Matrix v1.4). autojoin_thread_on_open: true @@ -159,7 +159,7 @@ bridge: delete_guild_on_leave: true # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. - federate_rooms: {{ matrix_mautrix_discord_federate_rooms | to_json }} + federate_rooms: {{ matrix_bridge_mautrix_discord_federate_rooms | to_json }} # Prefix messages from webhooks with the profile info? This can be used along with a custom displayname_template # to better handle webhooks that change their name all the time (like ones used by bridges). prefix_webhook_messages: false @@ -207,7 +207,7 @@ bridge: height: 320 fps: 25 # only for webm, webp and gif (2, 5, 10, 20 or 25 recommended) # Servers to always allow double puppeting from - double_puppet_server_map: {{ matrix_mautrix_discord_bridge_double_puppet_server_map | to_json }} + double_puppet_server_map: {{ matrix_bridge_mautrix_discord_bridge_double_puppet_server_map | to_json }} # Allow using double puppeting from any server with a valid client .well-known file. double_puppet_allow_discovery: false # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth @@ -215,10 +215,10 @@ bridge: # If set, double puppeting will be enabled automatically for local users # instead of users having to find an access token and run `login-matrix` # manually. - login_shared_secret_map: {{ matrix_mautrix_discord_bridge_login_shared_secret_map | to_json }} + login_shared_secret_map: {{ matrix_bridge_mautrix_discord_bridge_login_shared_secret_map | to_json }} # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_mautrix_discord_bridge_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_mautrix_discord_bridge_command_prefix | to_json }} # Messages sent upon joining a management room. # Markdown is supported. The defaults are listed below. management_room_text: @@ -260,24 +260,24 @@ bridge: # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Allow encryption, work in group chat rooms with e2ee enabled - allow: {{ matrix_mautrix_discord_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_mautrix_discord_bridge_encryption_allow | to_json }} # Default to encryption, force-enable encryption in all portals the bridge creates # This will cause the bridge bot to be in private chats for the encryption to work properly. - default: {{ matrix_mautrix_discord_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_mautrix_discord_bridge_encryption_default | to_json }} # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. - appservice: {{ matrix_mautrix_discord_bridge_encryption_appservice | to_json}} + appservice: {{ matrix_bridge_mautrix_discord_bridge_encryption_appservice | to_json}} # Require encryption, drop any unencrypted messages. - require: {{ matrix_mautrix_discord_bridge_encryption_require | to_json }} + require: {{ matrix_bridge_mautrix_discord_bridge_encryption_require | to_json }} # Whether to use MSC4190 instead of appservice login to create the bridge bot device. # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_mautrix_discord_msc4190_enabled | to_json }} + msc4190: {{ matrix_bridge_mautrix_discord_msc4190_enabled | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_mautrix_discord_bridge_encryption_key_sharing_allow | to_json }} + allow_key_sharing: {{ matrix_bridge_mautrix_discord_bridge_encryption_key_sharing_allow | to_json }} # Should users mentions be in the event wire content to enable the server to send push notifications? - plaintext_mentions: {{ matrix_mautrix_discord_bridge_encryption_plaintext_mentions | to_json }} + plaintext_mentions: {{ matrix_bridge_mautrix_discord_bridge_encryption_plaintext_mentions | to_json }} # Options for deleting megolm sessions from the bridge. delete_keys: # Beeper-specific: delete outbound sessions when hungryserv confirms @@ -344,7 +344,7 @@ bridge: prefix: /_matrix/provision # Shared secret for authentication. If set to "generate", a random secret will be generated, # or if set to "disable", the provisioning API will be disabled. - shared_secret: {{ matrix_mautrix_discord_provisioning_shared_secret | to_json }} + shared_secret: {{ matrix_bridge_mautrix_discord_provisioning_shared_secret | to_json }} # Enable debug API at /debug with provisioning authentication. debug_endpoints: false @@ -357,11 +357,11 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_discord_bridge_permissions|to_json }} + permissions: {{ matrix_bridge_mautrix_discord_bridge_permissions|to_json }} # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_mautrix_discord_logging_level | to_json }} + min_level: {{ matrix_bridge_mautrix_discord_logging_level | to_json }} writers: - type: stdout format: pretty-colored diff --git a/roles/custom/matrix-bridge-mautrix-discord/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-discord/templates/labels.j2 index be59b906e..98851f0c3 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/templates/labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-discord/templates/labels.j2 @@ -4,16 +4,16 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_discord_container_labels_traefik_enabled %} +{% if matrix_bridge_mautrix_discord_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_mautrix_discord_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_discord_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_discord_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_discord_container_labels_traefik_docker_network }} {% endif %} traefik.http.services.matrix-mautrix-discord.loadbalancer.server.port=8080 -{% if matrix_mautrix_discord_container_labels_avatar_proxy_enabled %} +{% if matrix_bridge_mautrix_discord_container_labels_avatar_proxy_enabled %} ############################################################ # # # Avatar proxy # @@ -22,21 +22,21 @@ traefik.http.services.matrix-mautrix-discord.loadbalancer.server.port=8080 {% set middlewares = [] %} -{% if matrix_mautrix_discord_container_labels_traefik_path_prefix != '/' %} -traefik.http.middlewares.matrix-mautrix-discord-slashless-redirect.redirectregex.regex=({{ matrix_mautrix_discord_container_labels_traefik_path_prefix | quote }})$ +{% if matrix_bridge_mautrix_discord_container_labels_traefik_path_prefix != '/' %} +traefik.http.middlewares.matrix-mautrix-discord-slashless-redirect.redirectregex.regex=({{ matrix_bridge_mautrix_discord_container_labels_traefik_path_prefix | quote }})$ traefik.http.middlewares.matrix-mautrix-discord-slashless-redirect.redirectregex.replacement=${1}/ {% set middlewares = middlewares + ['matrix-mautrix-discord-slashless-redirect'] %} {% endif %} -{% if matrix_mautrix_discord_container_labels_traefik_path_prefix != '/' %} -traefik.http.middlewares.matrix-mautrix-discord-strip-prefix.stripprefix.prefixes={{ matrix_mautrix_discord_container_labels_traefik_path_prefix }} +{% if matrix_bridge_mautrix_discord_container_labels_traefik_path_prefix != '/' %} +traefik.http.middlewares.matrix-mautrix-discord-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_discord_container_labels_traefik_path_prefix }} {% set middlewares = middlewares + ['matrix-mautrix-discord-strip-prefix'] %} {% endif %} -traefik.http.routers.matrix-mautrix-discord-avatar-proxy.rule={{ matrix_mautrix_discord_container_labels_avatar_proxy_traefik_rule }} +traefik.http.routers.matrix-mautrix-discord-avatar-proxy.rule={{ matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_rule }} -{% if matrix_mautrix_discord_container_labels_avatar_proxy_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-discord-avatar-proxy.priority={{ matrix_mautrix_discord_container_labels_avatar_proxy_traefik_priority }} +{% if matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-discord-avatar-proxy.priority={{ matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_priority }} {% endif %} {% if middlewares | length > 0 %} @@ -44,11 +44,11 @@ traefik.http.routers.matrix-mautrix-discord-avatar-proxy.middlewares={{ middlewa {% endif %} traefik.http.routers.matrix-mautrix-discord-avatar-proxy.service=matrix-mautrix-discord -traefik.http.routers.matrix-mautrix-discord-avatar-proxy.entrypoints={{ matrix_mautrix_discord_container_labels_avatar_proxy_traefik_entrypoints }} +traefik.http.routers.matrix-mautrix-discord-avatar-proxy.entrypoints={{ matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_entrypoints }} -traefik.http.routers.matrix-mautrix-discord-avatar-proxy.tls={{ matrix_mautrix_discord_container_labels_avatar_proxy_traefik_tls | to_json }} -{% if matrix_mautrix_discord_container_labels_avatar_proxy_traefik_tls %} -traefik.http.routers.matrix-mautrix-discord-avatar-proxy.tls.certResolver={{ matrix_mautrix_discord_container_labels_avatar_proxy_traefik_tls_certResolver }} +traefik.http.routers.matrix-mautrix-discord-avatar-proxy.tls={{ matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_tls %} +traefik.http.routers.matrix-mautrix-discord-avatar-proxy.tls.certResolver={{ matrix_bridge_mautrix_discord_container_labels_avatar_proxy_traefik_tls_certResolver }} {% endif %} ############################################################ @@ -61,4 +61,4 @@ traefik.http.routers.matrix-mautrix-discord-avatar-proxy.tls.certResolver={{ mat {% endif %} -{{ matrix_mautrix_discord_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_discord_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-discord/templates/systemd/matrix-mautrix-discord.service.j2 b/roles/custom/matrix-bridge-mautrix-discord/templates/systemd/matrix-mautrix-discord.service.j2 index 770ef59dc..4817b2648 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/templates/systemd/matrix-mautrix-discord.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-discord/templates/systemd/matrix-mautrix-discord.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix Discord bridge -{% for service in matrix_mautrix_discord_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_discord_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_discord_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_discord_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,20 +22,22 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_discord_container_network }} \ - --label-file={{ matrix_mautrix_discord_base_path }}/labels \ - --mount type=bind,src={{ matrix_mautrix_discord_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_mautrix_discord_data_path }},dst=/data \ + --network={{ matrix_bridge_mautrix_discord_container_network }} \ + --label-file={{ matrix_bridge_mautrix_discord_base_path }}/labels \ + --mount type=bind,src={{ matrix_bridge_mautrix_discord_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_discord_data_path }},dst=/data \ --workdir=/data \ - {% for arg in matrix_mautrix_discord_container_extra_arguments %} + {% for arg in matrix_bridge_mautrix_discord_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_discord_container_image }} \ + {{ matrix_bridge_mautrix_discord_container_image }} \ /usr/bin/mautrix-discord -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_mautrix_discord_container_additional_networks %} +{% if matrix_bridge_mautrix_discord_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_discord_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-discord {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-discord diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-gmessages/defaults/main.yml index 4c1063688..b7b52c9e5 100644 --- a/roles/custom/matrix-bridge-mautrix-gmessages/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-gmessages/defaults/main.yml @@ -11,219 +11,218 @@ # mautrix-gmessages is a Matrix <-> gmessages bridge # Project source code URL: https://github.com/mautrix/gmessages -matrix_mautrix_gmessages_enabled: true +matrix_bridge_mautrix_gmessages_enabled: true -matrix_mautrix_gmessages_container_image_self_build: false -matrix_mautrix_gmessages_container_image_self_build_repo: "https://github.com/mautrix/gmessages.git" -matrix_mautrix_gmessages_container_image_self_build_branch: "{{ 'main' if matrix_mautrix_gmessages_version == 'latest' else matrix_mautrix_gmessages_version }}" +matrix_bridge_mautrix_gmessages_container_image_self_build: false +matrix_bridge_mautrix_gmessages_container_image_self_build_repo: "https://github.com/mautrix/gmessages.git" +matrix_bridge_mautrix_gmessages_container_image_self_build_branch: "{{ 'main' if matrix_bridge_mautrix_gmessages_version == 'latest' else matrix_bridge_mautrix_gmessages_version }}" # renovate: datasource=docker depName=dock.mau.dev/mautrix/gmessages -matrix_mautrix_gmessages_version: v0.2602.0 +matrix_bridge_mautrix_gmessages_version: v0.2608.0 # See: https://mau.dev/mautrix/gmessages/container_registry -matrix_mautrix_gmessages_container_image: "{{ matrix_mautrix_gmessages_container_image_registry_prefix }}mautrix/gmessages:{{ matrix_mautrix_gmessages_version }}" -matrix_mautrix_gmessages_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_gmessages_container_image_self_build else matrix_mautrix_gmessages_container_image_registry_prefix_upstream }}" -matrix_mautrix_gmessages_container_image_registry_prefix_upstream: "{{ matrix_mautrix_gmessages_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_gmessages_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_gmessages_container_image_force_pull: "{{ matrix_mautrix_gmessages_container_image.endswith(':latest') }}" - -matrix_mautrix_gmessages_base_path: "{{ matrix_base_data_path }}/mautrix-gmessages" -matrix_mautrix_gmessages_config_path: "{{ matrix_mautrix_gmessages_base_path }}/config" -matrix_mautrix_gmessages_data_path: "{{ matrix_mautrix_gmessages_base_path }}/data" -matrix_mautrix_gmessages_container_src_files_path: "{{ matrix_mautrix_gmessages_base_path }}/docker-src" - -matrix_mautrix_gmessages_homeserver_address: "" +matrix_bridge_mautrix_gmessages_container_image: "{{ matrix_bridge_mautrix_gmessages_container_image_registry_prefix }}mautrix/gmessages:{{ matrix_bridge_mautrix_gmessages_version }}" +matrix_bridge_mautrix_gmessages_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_gmessages_container_image_self_build else matrix_bridge_mautrix_gmessages_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_gmessages_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_gmessages_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_gmessages_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bridge_mautrix_gmessages_base_path: "{{ matrix_base_data_path }}/mautrix-gmessages" +matrix_bridge_mautrix_gmessages_config_path: "{{ matrix_bridge_mautrix_gmessages_base_path }}/config" +matrix_bridge_mautrix_gmessages_data_path: "{{ matrix_bridge_mautrix_gmessages_base_path }}/data" +matrix_bridge_mautrix_gmessages_container_src_files_path: "{{ matrix_bridge_mautrix_gmessages_base_path }}/docker-src" + +matrix_bridge_mautrix_gmessages_homeserver_address: "" # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_mautrix_gmessages_homeserver_async_media: false -matrix_mautrix_gmessages_homeserver_domain: "{{ matrix_domain }}" -matrix_mautrix_gmessages_appservice_address: "http://matrix-mautrix-gmessages:8080" +matrix_bridge_mautrix_gmessages_homeserver_async_media: false +matrix_bridge_mautrix_gmessages_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_mautrix_gmessages_appservice_address: "http://matrix-mautrix-gmessages:8080" + +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_gmessages_bridge_public_address`). +matrix_bridge_mautrix_gmessages_scheme: https -matrix_mautrix_gmessages_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" -matrix_mautrix_gmessages_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" +# The public base URL at which this bridge's HTTP API is reachable from outside (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_gmessages_bridge_public_address: "{{ (matrix_bridge_mautrix_gmessages_scheme + '://' + matrix_bridge_mautrix_gmessages_exposure_hostname + matrix_bridge_mautrix_gmessages_exposure_path_prefix) if matrix_bridge_mautrix_gmessages_exposure_enabled else '' }}" -matrix_mautrix_gmessages_backfill_enabled: true -matrix_mautrix_gmessages_backfill_max_initial_messages: 50 -matrix_mautrix_gmessages_backfill_max_catchup_messages: 500 -matrix_mautrix_gmessages_backfill_unread_hours_threshold: 720 -matrix_mautrix_gmessages_backfill_threads_max_initial_messages: 50 +matrix_bridge_mautrix_gmessages_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_gmessages_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" -matrix_mautrix_gmessages_command_prefix: "!gm" +matrix_bridge_mautrix_gmessages_backfill_enabled: true +matrix_bridge_mautrix_gmessages_backfill_max_initial_messages: 50 +matrix_bridge_mautrix_gmessages_backfill_max_catchup_messages: 500 +matrix_bridge_mautrix_gmessages_backfill_unread_hours_threshold: 720 +matrix_bridge_mautrix_gmessages_backfill_threads_max_initial_messages: 50 -matrix_mautrix_gmessages_container_network: "" +matrix_bridge_mautrix_gmessages_command_prefix: "!gm" -matrix_mautrix_gmessages_container_additional_networks: "{{ matrix_mautrix_gmessages_container_additional_networks_auto + matrix_mautrix_gmessages_container_additional_networks_custom }}" -matrix_mautrix_gmessages_container_additional_networks_auto: [] -matrix_mautrix_gmessages_container_additional_networks_custom: [] +matrix_bridge_mautrix_gmessages_container_network: "" -# matrix_mautrix_gmessages_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +matrix_bridge_mautrix_gmessages_container_additional_networks: "{{ matrix_bridge_mautrix_gmessages_container_additional_networks_auto + matrix_bridge_mautrix_gmessages_container_additional_networks_custom }}" +matrix_bridge_mautrix_gmessages_container_additional_networks_auto: [] +matrix_bridge_mautrix_gmessages_container_additional_networks_custom: [] + +# matrix_bridge_mautrix_gmessages_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_gmessages_container_labels_additional_labels`. -matrix_mautrix_gmessages_container_labels_traefik_enabled: true -matrix_mautrix_gmessages_container_labels_traefik_docker_network: "{{ matrix_mautrix_gmessages_container_network }}" -matrix_mautrix_gmessages_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_gmessages_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose mautrix-gmessages' metrics -matrix_mautrix_gmessages_container_labels_metrics_enabled: "{{ matrix_mautrix_gmessages_metrics_enabled and matrix_mautrix_gmessages_metrics_proxying_enabled }}" -matrix_mautrix_gmessages_container_labels_metrics_traefik_rule: "Host(`{{ matrix_mautrix_gmessages_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_mautrix_gmessages_metrics_proxying_path_prefix }}`)" -matrix_mautrix_gmessages_container_labels_metrics_traefik_priority: 0 -matrix_mautrix_gmessages_container_labels_metrics_traefik_entrypoints: "{{ matrix_mautrix_gmessages_container_labels_traefik_entrypoints }}" -matrix_mautrix_gmessages_container_labels_metrics_traefik_tls: "{{ matrix_mautrix_gmessages_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_mautrix_gmessages_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_mautrix_gmessages_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_mautrix_gmessages_container_labels_metrics_middleware_basic_auth_enabled: false -# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_mautrix_gmessages_container_labels_metrics_middleware_basic_auth_users: '' - -# matrix_mautrix_gmessages_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# To inject your own other container labels, see `matrix_bridge_mautrix_gmessages_container_labels_additional_labels`. +matrix_bridge_mautrix_gmessages_container_labels_traefik_enabled: true +matrix_bridge_mautrix_gmessages_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_gmessages_container_network }}" +matrix_bridge_mautrix_gmessages_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_gmessages_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-gmessages' HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_gmessages_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_gmessages_exposure_enabled }}" +matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_gmessages_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_gmessages_exposure_path_prefix }}`)" +matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_gmessages_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_gmessages_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_gmessages_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_gmessages_container_labels_additional_labels: | +# matrix_bridge_mautrix_gmessages_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_gmessages_container_labels_additional_labels: '' +matrix_bridge_mautrix_gmessages_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_gmessages_container_extra_arguments: [] +matrix_bridge_mautrix_gmessages_container_extra_arguments: [] # List of systemd services that matrix-mautrix-gmessages.service depends on. -matrix_mautrix_gmessages_systemd_required_services_list: "{{ matrix_mautrix_gmessages_systemd_required_services_list_default + matrix_mautrix_gmessages_systemd_required_services_list_auto + matrix_mautrix_gmessages_systemd_required_services_list_custom }}" -matrix_mautrix_gmessages_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_gmessages_systemd_required_services_list_auto: [] -matrix_mautrix_gmessages_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_gmessages_systemd_required_services_list: "{{ matrix_bridge_mautrix_gmessages_systemd_required_services_list_default + matrix_bridge_mautrix_gmessages_systemd_required_services_list_auto + matrix_bridge_mautrix_gmessages_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_gmessages_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_gmessages_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_gmessages_systemd_required_services_list_custom: [] # List of systemd services that matrix-mautrix-gmessages.service wants -matrix_mautrix_gmessages_systemd_wanted_services_list: [] +matrix_bridge_mautrix_gmessages_systemd_wanted_services_list: [] -matrix_mautrix_gmessages_appservice_token: '' -matrix_mautrix_gmessages_homeserver_token: '' +matrix_bridge_mautrix_gmessages_appservice_token: '' +matrix_bridge_mautrix_gmessages_homeserver_token: '' -matrix_mautrix_gmessages_appservice_bot_username: gmessagesbot +matrix_bridge_mautrix_gmessages_appservice_bot_username: gmessagesbot # Minimum severity of journal log messages. # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_gmessages_logging_level: 'warn' +matrix_bridge_mautrix_gmessages_logging_level: 'warn' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_mautrix_gmessages_federate_rooms: true - -# Whether or not metrics endpoint should be enabled. -# Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_mautrix_gmessages_metrics_proxying_enabled`. -matrix_mautrix_gmessages_metrics_enabled: false +matrix_bridge_mautrix_gmessages_federate_rooms: true -# Controls whether metrics should be proxied (exposed) on a public URL. -matrix_mautrix_gmessages_metrics_proxying_enabled: false -matrix_mautrix_gmessages_metrics_proxying_hostname: '' -matrix_mautrix_gmessages_metrics_proxying_path_prefix: '' +# Controls whether mautrix-gmessages' HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_gmessages_exposure_enabled: false +matrix_bridge_mautrix_gmessages_exposure_hostname: '' +matrix_bridge_mautrix_gmessages_exposure_path_prefix: '' # Database-related configuration fields. # # To use SQLite, stick to these defaults. # # To use Postgres: -# - change the engine (`matrix_mautrix_gmessages_database_engine: 'postgres'`) -# - adjust your database credentials via the `matrix_mautrix_gmessages_database_*` variables -matrix_mautrix_gmessages_database_engine: 'sqlite' - -matrix_mautrix_gmessages_sqlite_database_path_local: "{{ matrix_mautrix_gmessages_data_path }}/mautrix-gmessages.db" -matrix_mautrix_gmessages_sqlite_database_path_in_container: "/data/mautrix-gmessages.db" - -matrix_mautrix_gmessages_database_username: 'matrix_mautrix_gmessages' -matrix_mautrix_gmessages_database_password: 'some-password' -matrix_mautrix_gmessages_database_hostname: '' -matrix_mautrix_gmessages_database_port: 5432 -matrix_mautrix_gmessages_database_name: 'matrix_mautrix_gmessages' -matrix_mautrix_gmessages_database_sslmode: disable - -matrix_mautrix_gmessages_database_connection_string: 'postgresql://{{ matrix_mautrix_gmessages_database_username }}:{{ matrix_mautrix_gmessages_database_password }}@{{ matrix_mautrix_gmessages_database_hostname }}:{{ matrix_mautrix_gmessages_database_port }}/{{ matrix_mautrix_gmessages_database_name }}?sslmode={{ matrix_mautrix_gmessages_database_sslmode }}' - -matrix_mautrix_gmessages_appservice_database_type: "{{ - { - 'sqlite': 'sqlite3', - 'postgres':'postgres', - }[matrix_mautrix_gmessages_database_engine] -}}" - -matrix_mautrix_gmessages_appservice_database_uri: "{{ - { - 'sqlite': matrix_mautrix_gmessages_sqlite_database_path_in_container, - 'postgres': matrix_mautrix_gmessages_database_connection_string, - }[matrix_mautrix_gmessages_database_engine] -}}" - -matrix_mautrix_gmessages_double_puppet_secrets: "{{ matrix_mautrix_gmessages_double_puppet_secrets_auto | combine(matrix_mautrix_gmessages_double_puppet_secrets_custom) }}" -matrix_mautrix_gmessages_double_puppet_secrets_auto: {} -matrix_mautrix_gmessages_double_puppet_secrets_custom: {} +# - change the engine (`matrix_bridge_mautrix_gmessages_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_mautrix_gmessages_database_*` variables +matrix_bridge_mautrix_gmessages_database_engine: 'sqlite' + +matrix_bridge_mautrix_gmessages_sqlite_database_path_local: "{{ matrix_bridge_mautrix_gmessages_data_path }}/mautrix-gmessages.db" +matrix_bridge_mautrix_gmessages_sqlite_database_path_in_container: "/data/mautrix-gmessages.db" + +matrix_bridge_mautrix_gmessages_database_username: 'matrix_mautrix_gmessages' +matrix_bridge_mautrix_gmessages_database_password: 'some-password' +matrix_bridge_mautrix_gmessages_database_hostname: '' +matrix_bridge_mautrix_gmessages_database_port: 5432 +matrix_bridge_mautrix_gmessages_database_name: 'matrix_mautrix_gmessages' +matrix_bridge_mautrix_gmessages_database_sslmode: disable + +matrix_bridge_mautrix_gmessages_database_connection_string: 'postgresql://{{ matrix_bridge_mautrix_gmessages_database_username }}:{{ matrix_bridge_mautrix_gmessages_database_password }}@{{ matrix_bridge_mautrix_gmessages_database_hostname }}:{{ matrix_bridge_mautrix_gmessages_database_port }}/{{ matrix_bridge_mautrix_gmessages_database_name }}?sslmode={{ matrix_bridge_mautrix_gmessages_database_sslmode }}' + +matrix_bridge_mautrix_gmessages_appservice_database_type: "{{ { + 'sqlite': 'sqlite3', + 'postgres': 'postgres', +}[matrix_bridge_mautrix_gmessages_database_engine] }}" + +matrix_bridge_mautrix_gmessages_appservice_database_uri: "{{ { + 'sqlite': matrix_bridge_mautrix_gmessages_sqlite_database_path_in_container, + 'postgres': matrix_bridge_mautrix_gmessages_database_connection_string, +}[matrix_bridge_mautrix_gmessages_database_engine] }}" + +matrix_bridge_mautrix_gmessages_double_puppet_secrets: "{{ matrix_bridge_mautrix_gmessages_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_gmessages_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_gmessages_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_gmessages_double_puppet_secrets_custom: {} # Enable End-to-bridge encryption -matrix_mautrix_gmessages_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_gmessages_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_mautrix_gmessages_bridge_encryption_require: false -matrix_mautrix_gmessages_bridge_encryption_appservice: false -matrix_mautrix_gmessages_bridge_encryption_key_sharing_allow: "{{ matrix_mautrix_gmessages_bridge_encryption_allow }}" +matrix_bridge_mautrix_gmessages_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_gmessages_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_gmessages_bridge_encryption_require: false +matrix_bridge_mautrix_gmessages_bridge_encryption_appservice: false +matrix_bridge_mautrix_gmessages_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_mautrix_gmessages_bridge_encryption_allow }}" # For compatibility with the older Gmessages bridge, you may wish to set the pickle key to: "go.mau.fi/mautrix-gmessages" -matrix_mautrix_gmessages_bridge_encryption_pickle_key: mautrix.bridge.e2ee +matrix_bridge_mautrix_gmessages_bridge_encryption_pickle_key: mautrix.bridge.e2ee + +matrix_bridge_mautrix_gmessages_network_displayname_template: "{% raw %}{{or .FullName .PhoneNumber}} (GMessages){% endraw %}" +matrix_bridge_mautrix_gmessages_appservice_username_template: "{% raw %}gmessages_{{.}}{% endraw %}" -matrix_mautrix_gmessages_network_displayname_template: "{% raw %}{{or .FullName .PhoneNumber}} (GMessages){% endraw %}" -matrix_mautrix_gmessages_appservice_username_template: "{% raw %}gmessages_{{.}}{% endraw %}" +matrix_bridge_mautrix_gmessages_public_media_signing_key: '' -matrix_mautrix_gmessages_public_media_signing_key: '' +# Shared secret for authentication of provisioning API requests. +# If set to "disable", the provisioning API will be disabled. +matrix_bridge_mautrix_gmessages_provisioning_shared_secret: disable -matrix_mautrix_gmessages_bridge_personal_filtering_spaces: true +matrix_bridge_mautrix_gmessages_bridge_personal_filtering_spaces: true -matrix_mautrix_gmessages_bridge_permissions: | +matrix_bridge_mautrix_gmessages_bridge_permissions: | {{ - {'*': 'relay', matrix_mautrix_gmessages_homeserver_domain: 'user'} + {'*': 'relay', matrix_bridge_mautrix_gmessages_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} # Default mautrix-gmessages configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_gmessages_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_gmessages_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_gmessages_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_gmessages_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_gmessages_configuration_extension_yaml: | +matrix_bridge_mautrix_gmessages_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_gmessages_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_gmessages_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_gmessages_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_gmessages_configuration_yaml`. -matrix_mautrix_gmessages_configuration_extension: "{{ matrix_mautrix_gmessages_configuration_extension_yaml | from_yaml if matrix_mautrix_gmessages_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_gmessages_configuration_extension: "{{ matrix_bridge_mautrix_gmessages_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_gmessages_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_gmessages_configuration_yaml`. -matrix_mautrix_gmessages_configuration: "{{ matrix_mautrix_gmessages_configuration_yaml | from_yaml | combine(matrix_mautrix_gmessages_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_gmessages_configuration_yaml`. +matrix_bridge_mautrix_gmessages_configuration: "{{ matrix_bridge_mautrix_gmessages_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_gmessages_configuration_extension, recursive=True) }}" -matrix_mautrix_gmessages_registration_yaml: | +matrix_bridge_mautrix_gmessages_registration_yaml: | id: gmessages - url: {{ matrix_mautrix_gmessages_appservice_address }} - as_token: "{{ matrix_mautrix_gmessages_appservice_token }}" - hs_token: "{{ matrix_mautrix_gmessages_homeserver_token }}" + url: {{ matrix_bridge_mautrix_gmessages_appservice_address }} + as_token: "{{ matrix_bridge_mautrix_gmessages_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_gmessages_homeserver_token }}" # See https://github.com/mautrix/signal/issues/43 - sender_localpart: _bot_{{ matrix_mautrix_gmessages_appservice_bot_username }} + sender_localpart: _bot_{{ matrix_bridge_mautrix_gmessages_appservice_bot_username }} rate_limited: false namespaces: users: - - regex: '^@gmessages_.+:{{ matrix_mautrix_gmessages_homeserver_domain | regex_escape }}$' + - regex: '^@gmessages_.+:{{ matrix_bridge_mautrix_gmessages_homeserver_domain | regex_escape }}$' exclusive: true - exclusive: true - regex: '^@{{ matrix_mautrix_gmessages_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_gmessages_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_mautrix_gmessages_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_gmessages_homeserver_domain | regex_escape }}$' de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_mautrix_gmessages_msc4190_enabled | to_json }} + io.element.msc4190: {{ matrix_bridge_mautrix_gmessages_msc4190_enabled | to_json }} -matrix_mautrix_gmessages_registration: "{{ matrix_mautrix_gmessages_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_gmessages_registration: "{{ matrix_bridge_mautrix_gmessages_registration_yaml | from_yaml }}" -# matrix_mautrix_gmessages_restart_necessary controls whether the service +# matrix_bridge_mautrix_gmessages_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -231,4 +230,4 @@ matrix_mautrix_gmessages_registration: "{{ matrix_mautrix_gmessages_registration # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_gmessages_restart_necessary: false +matrix_bridge_mautrix_gmessages_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/converge.yml new file mode 100644 index 000000000..86639c7fd --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-gmessages Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-gmessages Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-gmessages is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-gmessages systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-gmessages.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/molecule.yml new file mode 100644 index 000000000..36f1bff9b --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/molecule.yml @@ -0,0 +1,95 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-gmessages-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_gmessages_container_network: mautrix-gmessages-molecule + + # The stub prepare.yml starts is not a real homeserver, and the scenario carries + # no Google account or paired Android device. That is the third-party boundary. + matrix_bridge_mautrix_gmessages_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_gmessages_homeserver_domain: molecule.local + + # Postgres is the normal deployment path. Non-default database and user names make + # the resulting schema evidence that the role composed and supplied this connection. + matrix_bridge_mautrix_gmessages_database_engine: postgres + matrix_bridge_mautrix_gmessages_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_gmessages_database_name: molecule_gmessages + matrix_bridge_mautrix_gmessages_database_username: molecule_gmessages + matrix_bridge_mautrix_gmessages_database_password: molecule_pg_password_9d268a + + # Test-only fixtures which must reach both config.yaml and registration.yaml. + matrix_bridge_mautrix_gmessages_appservice_token: molecule_gmessages_as_token_c8d734 + matrix_bridge_mautrix_gmessages_homeserver_token: molecule_gmessages_hs_token_3a9e51 + + # All differ from the role defaults, allowing parsed checks to prove role rendering. + matrix_bridge_mautrix_gmessages_appservice_bot_username: molecule-gmessagesbot + matrix_bridge_mautrix_gmessages_command_prefix: "!molecule-gmessages" + matrix_bridge_mautrix_gmessages_logging_level: info + matrix_bridge_mautrix_gmessages_federate_rooms: false + matrix_bridge_mautrix_gmessages_bridge_personal_filtering_spaces: false + matrix_bridge_mautrix_gmessages_backfill_enabled: false + matrix_bridge_mautrix_gmessages_backfill_max_initial_messages: 17 + matrix_bridge_mautrix_gmessages_backfill_max_catchup_messages: 29 + matrix_bridge_mautrix_gmessages_backfill_unread_hours_threshold: 61 + matrix_bridge_mautrix_gmessages_backfill_threads_max_initial_messages: 7 + matrix_bridge_mautrix_gmessages_provisioning_shared_secret: molecule_provisioning_secret_455c91 + matrix_bridge_mautrix_gmessages_network_displayname_template: "{% raw %}{{or .PhoneNumber .FullName}} (Molecule){% endraw %}" + matrix_bridge_mautrix_gmessages_appservice_username_template: "{% raw %}molecule_gmessages_{{.}}{% endraw %}" + + # Traefik is not started. These values exercise both the public address consumed by + # the bridge and the exposure labels consumed by Docker. + matrix_bridge_mautrix_gmessages_exposure_enabled: true + matrix_bridge_mautrix_gmessages_exposure_hostname: gmessages-api.molecule.local + matrix_bridge_mautrix_gmessages_exposure_path_prefix: /bridges/gmessages-api + matrix_bridge_mautrix_gmessages_scheme: http + matrix_bridge_mautrix_gmessages_container_labels_traefik_entrypoints: web + matrix_bridge_mautrix_gmessages_container_labels_additional_labels: | + molecule.gmessages.coverage=enabled + + # verify.yml is a separate play, where role defaults are out of scope. + matrix_bridge_mautrix_gmessages_base_path: /matrix/mautrix-gmessages + matrix_bridge_mautrix_gmessages_config_path: /matrix/mautrix-gmessages/config + matrix_bridge_mautrix_gmessages_data_path: /matrix/mautrix-gmessages/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/prepare.yml new file mode 100644 index 000000000..1f317460a --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/prepare.yml @@ -0,0 +1,87 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-gmessages Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role creates this during converge, but both dependencies attach to it first. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_gmessages_container_network }}" + register: mautrix_gmessages_molecule_network + changed_when: mautrix_gmessages_molecule_network.rc == 0 + failed_when: + - mautrix_gmessages_molecule_network.rc != 0 + - "'already exists' not in mautrix_gmessages_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_gmessages_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_gmessages_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_gmessages_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_gmessages_database_password }}" + + # The unpaired bridge still authenticates its appservice bot during startup. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_gmessages_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_gmessages_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_gmessages_appservice_bot_username }}:{{ matrix_bridge_mautrix_gmessages_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/verify.yml new file mode 100644 index 000000000..20eb5c9b9 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gmessages/molecule/default/verify.yml @@ -0,0 +1,387 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the bridge starts without a Google account or paired device, accepts the role-rendered +# configuration and registration, initializes real Postgres, and exposes its live appservice. +- name: Verify mautrix-gmessages + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + mautrix_gmessages_config: "{{ mautrix_gmessages_config_file.content | b64decode | from_yaml }}" + mautrix_gmessages_registration: "{{ mautrix_gmessages_registration_file.content | b64decode | from_yaml }}" + mautrix_gmessages_labels_rendered: "{{ mautrix_gmessages_labels_file.content | b64decode }}" + mautrix_gmessages_expected_public_address: http://gmessages-api.molecule.local/bridges/gmessages-api + gather_facts: false + + tasks: + # The version remains sourced from the role so a Renovate bump changes the expectation. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_gmessages_role_defaults + + - name: Wait for the mautrix-gmessages service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-gmessages.service + register: mautrix_gmessages_service + until: mautrix_gmessages_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always means ActiveState alone cannot distinguish a healthy service from a loop. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_gmessages_service.status.ActiveState == 'active' + - mautrix_gmessages_service.status.NRestarts is defined + - mautrix_gmessages_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-gmessages.service is + {{ mautrix_gmessages_service.status.ActiveState | default('unknown') }} after + {{ mautrix_gmessages_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-mautrix-gmessages.service is active and has not restarted" + + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_gmessages_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-gmessages:8080/_matrix/mau/live + register: mautrix_gmessages_live + changed_when: false + until: mautrix_gmessages_live.rc == 0 and mautrix_gmessages_live.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_gmessages_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-gmessages:8080/_matrix/mau/ready + register: mautrix_gmessages_ready + changed_when: false + until: mautrix_gmessages_ready.rc == 0 and mautrix_gmessages_ready.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on the configured appservice port + ansible.builtin.assert: + that: + - mautrix_gmessages_live.rc == 0 + - mautrix_gmessages_live.stdout == 'HTTP_STATUS=200' + - mautrix_gmessages_ready.rc == 0 + - mautrix_gmessages_ready.stdout == 'HTTP_STATUS=200' + fail_msg: >- + Health probes returned live={{ mautrix_gmessages_live.stdout | default('none') }} + (rc={{ mautrix_gmessages_live.rc | default('?') }}) and + ready={{ mautrix_gmessages_ready.stdout | default('none') }} + (rc={{ mautrix_gmessages_ready.rc | default('?') }}) + success_msg: "The bridge is live and ready on the configured appservice port" + + # This authenticated endpoint exercises the provisioning middleware and the network + # connector's login-flow API without starting a Google login or carrying credentials. + - name: Query the authenticated provisioning login flows + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_gmessages_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --fail-with-body + - --header + - "Authorization: Bearer {{ matrix_bridge_mautrix_gmessages_provisioning_shared_secret }}" + - "http://matrix-mautrix-gmessages:8080/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_gmessages_login_flows + changed_when: false + + - name: Query the provisioning API with an invalid secret + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_gmessages_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - --header + - "Authorization: Bearer definitely-wrong-molecule-secret" + - "http://matrix-mautrix-gmessages:8080/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_gmessages_login_flows_unauthorized + changed_when: false + failed_when: false + + - name: Assert the live provisioning API enforces auth and advertises login flows + ansible.builtin.assert: + that: + - mautrix_gmessages_login_flows.rc == 0 + - (mautrix_gmessages_login_flows.stdout | from_json).flows is sequence + - (mautrix_gmessages_login_flows.stdout | from_json).flows | length > 0 + - mautrix_gmessages_login_flows_unauthorized.rc == 0 + - mautrix_gmessages_login_flows_unauthorized.stdout == 'HTTP_STATUS=401' + fail_msg: "The provisioning API did not enforce its secret or return Google login flows" + success_msg: "The provisioning API enforces its secret and returns Google login flows" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_gmessages_config_path }}/config.yaml" + register: mautrix_gmessages_config_file + + - name: Assert the rendered configuration carries the appservice identity + ansible.builtin.assert: + that: + - mautrix_gmessages_config.homeserver.address == matrix_bridge_mautrix_gmessages_homeserver_address + - mautrix_gmessages_config.homeserver.domain == matrix_bridge_mautrix_gmessages_homeserver_domain + - mautrix_gmessages_config.appservice.id == 'gmessages' + - mautrix_gmessages_config.appservice.address == 'http://matrix-mautrix-gmessages:8080' + - mautrix_gmessages_config.appservice.public_address == mautrix_gmessages_expected_public_address + - mautrix_gmessages_config.appservice.bot.username == matrix_bridge_mautrix_gmessages_appservice_bot_username + - mautrix_gmessages_config.appservice.as_token == matrix_bridge_mautrix_gmessages_appservice_token + - mautrix_gmessages_config.appservice.hs_token == matrix_bridge_mautrix_gmessages_homeserver_token + - mautrix_gmessages_config.appservice.username_template == matrix_bridge_mautrix_gmessages_appservice_username_template + fail_msg: "The rendered configuration does not carry the scenario's appservice identity" + success_msg: "The rendered configuration carries the scenario's appservice identity" + + - name: Assert the rendered configuration carries non-default bridge behavior + ansible.builtin.assert: + that: + - mautrix_gmessages_config.bridge.command_prefix == matrix_bridge_mautrix_gmessages_command_prefix + - not mautrix_gmessages_config.bridge.personal_filtering_spaces + - not mautrix_gmessages_config.matrix.federate_rooms + - mautrix_gmessages_config.network.displayname_template == matrix_bridge_mautrix_gmessages_network_displayname_template + - mautrix_gmessages_config.provisioning.shared_secret == matrix_bridge_mautrix_gmessages_provisioning_shared_secret + - mautrix_gmessages_config.logging.min_level == matrix_bridge_mautrix_gmessages_logging_level + fail_msg: "The rendered configuration does not carry the scenario's bridge behavior" + success_msg: "The rendered configuration carries the scenario's bridge behavior" + + - name: Assert the rendered configuration carries the non-default backfill policy + ansible.builtin.assert: + that: + - not mautrix_gmessages_config.backfill.enabled + - mautrix_gmessages_config.backfill.max_initial_messages == 17 + - mautrix_gmessages_config.backfill.max_catchup_messages == 29 + - mautrix_gmessages_config.backfill.unread_hours_threshold == 61 + - mautrix_gmessages_config.backfill.threads.max_initial_messages == 7 + fail_msg: "The rendered configuration does not carry the scenario's backfill policy" + success_msg: "The rendered configuration carries the scenario's backfill policy" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - mautrix_gmessages_config.database.type == matrix_bridge_mautrix_gmessages_database_engine + - matrix_bridge_mautrix_gmessages_database_username in mautrix_gmessages_config.database.uri + - matrix_bridge_mautrix_gmessages_database_hostname in mautrix_gmessages_config.database.uri + - matrix_bridge_mautrix_gmessages_database_name in mautrix_gmessages_config.database.uri + fail_msg: >- + database.uri is {{ mautrix_gmessages_config.database.uri | default('unset') }}, which + was not composed from the scenario's connection settings + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_gmessages_config_path }}/registration.yaml" + register: mautrix_gmessages_registration_file + + - name: Assert the registration carries the configured handshake values + ansible.builtin.assert: + that: + - mautrix_gmessages_registration.id == 'gmessages' + - mautrix_gmessages_registration.as_token == matrix_bridge_mautrix_gmessages_appservice_token + - mautrix_gmessages_registration.hs_token == matrix_bridge_mautrix_gmessages_homeserver_token + - mautrix_gmessages_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_gmessages_appservice_bot_username + - mautrix_gmessages_registration.url == 'http://matrix-mautrix-gmessages:8080' + fail_msg: "The registration does not carry the configured handshake values" + success_msg: "The registration carries the configured handshake values" + + - name: Assert the registration namespaces cover only GMessages ghosts and the bridge bot + ansible.builtin.assert: + that: + - mautrix_gmessages_ghost_regex | length > 0 + - mautrix_gmessages_bot_regex | length > 0 + - mautrix_gmessages_ghost_mxid is match(mautrix_gmessages_ghost_regex) + - mautrix_gmessages_wrong_ghost_mxid is not match(mautrix_gmessages_ghost_regex) + - mautrix_gmessages_bot_mxid is match(mautrix_gmessages_bot_regex) + fail_msg: "The registration namespaces do not cover only GMessages ghosts and the bot" + success_msg: "The registration namespaces cover only GMessages ghosts and the bot" + vars: + mautrix_gmessages_user_regexes: "{{ mautrix_gmessages_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_gmessages_ghost_regex: "{{ mautrix_gmessages_user_regexes | select('search', 'gmessages_') | first | default('') }}" + mautrix_gmessages_bot_regex: "{{ mautrix_gmessages_user_regexes | reject('search', 'gmessages_') | first | default('') }}" + mautrix_gmessages_ghost_mxid: "@gmessages_15551234567:{{ matrix_bridge_mautrix_gmessages_homeserver_domain }}" + mautrix_gmessages_wrong_ghost_mxid: "@signal_15551234567:{{ matrix_bridge_mautrix_gmessages_homeserver_domain }}" + mautrix_gmessages_bot_mxid: "@{{ matrix_bridge_mautrix_gmessages_appservice_bot_username }}:{{ matrix_bridge_mautrix_gmessages_homeserver_domain }}" + + # Tables can only appear after DNS resolution, authentication and genuine migrations. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_gmessages_database_username }} + - --dbname={{ matrix_bridge_mautrix_gmessages_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: mautrix_gmessages_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - mautrix_gmessages_tables.rc == 0 + - "'version' in mautrix_gmessages_table_names" + - "'portal' in mautrix_gmessages_table_names" + - "'user_login' in mautrix_gmessages_table_names" + - "'message' in mautrix_gmessages_table_names" + - "'gmessages_version' in mautrix_gmessages_table_names" + - "'gmessages_login_prefix' in mautrix_gmessages_table_names" + - mautrix_gmessages_table_names | length > 12 + fail_msg: >- + The bridge did not migrate its schema into {{ matrix_bridge_mautrix_gmessages_database_name }} + (found {{ mautrix_gmessages_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + mautrix_gmessages_table_names: "{{ mautrix_gmessages_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_gmessages_base_path }}/labels" + register: mautrix_gmessages_labels_file + + - name: Assert the labels route the public endpoint to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_gmessages_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_gmessages_container_network in mautrix_gmessages_labels_rendered" + - "'traefik.http.services.matrix-mautrix-gmessages-exposure.loadbalancer.server.port=8080' in mautrix_gmessages_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-gmessages-exposure.rule=Host(`gmessages-api.molecule.local`) && PathPrefix(`/bridges/gmessages-api`)' in mautrix_gmessages_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-gmessages-exposure-strip-prefix.stripprefix.prefixes=/bridges/gmessages-api' in mautrix_gmessages_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-gmessages-exposure.entrypoints=web' in mautrix_gmessages_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-gmessages-exposure.tls=false' in mautrix_gmessages_labels_rendered" + - "'molecule.gmessages.coverage=enabled' in mautrix_gmessages_labels_rendered" + fail_msg: "The rendered labels do not carry the scenario's exposure configuration" + success_msg: "The rendered labels carry the scenario's exposure configuration" + + - name: Inspect the running bridge container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-gmessages + register: mautrix_gmessages_container_inspect + changed_when: false + + - name: Parse the running bridge container inspection + ansible.builtin.set_fact: + mautrix_gmessages_container: "{{ (mautrix_gmessages_container_inspect.stdout | from_json) | first }}" + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - mautrix_gmessages_container.Config.Image == mautrix_gmessages_expected_image + fail_msg: >- + The running container uses {{ mautrix_gmessages_container.Config.Image }}, expected + {{ mautrix_gmessages_expected_image }} + success_msg: "The running container uses the exact image pinned by the role" + vars: + mautrix_gmessages_expected_image: >- + {{ mautrix_gmessages_role_defaults.matrix_bridge_mautrix_gmessages_container_image_registry_prefix_upstream_default }}mautrix/gmessages:{{ mautrix_gmessages_role_defaults.matrix_bridge_mautrix_gmessages_version }} + + - name: Assert the running container uses the playbook-supplied runtime + ansible.builtin.assert: + that: + - mautrix_gmessages_container.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + - mautrix_gmessages_container.Config.WorkingDir == '/data' + - mautrix_gmessages_container.Config.Cmd == ['/usr/bin/mautrix-gmessages', '-c', '/config/config.yaml', '-r', '/config/registration.yaml', '--no-update'] + - mautrix_gmessages_container.HostConfig.RestartPolicy.Name == 'no' + - mautrix_gmessages_container.HostConfig.AutoRemove + - mautrix_gmessages_container.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container does not use the role's exact identity, command and workdir" + success_msg: "The running container uses the role's exact identity, command and workdir" + + - name: Assert the running container has the intended privilege isolation + ansible.builtin.assert: + that: + - "'ALL' in mautrix_gmessages_container.HostConfig.CapDrop" + - not mautrix_gmessages_container.HostConfig.Privileged + fail_msg: "The running container does not have the intended privilege isolation" + success_msg: "The running container drops all capabilities and is unprivileged" + + - name: Assert the running container carries the role's exact bind mounts + ansible.builtin.assert: + that: + - mautrix_gmessages_config_mount | length > 0 + - mautrix_gmessages_config_mount.Source == matrix_bridge_mautrix_gmessages_config_path + - not mautrix_gmessages_config_mount.RW + - mautrix_gmessages_data_mount | length > 0 + - mautrix_gmessages_data_mount.Source == matrix_bridge_mautrix_gmessages_data_path + - mautrix_gmessages_data_mount.RW + - mautrix_gmessages_container.Mounts | length == 2 + fail_msg: "The running container does not carry the role's exact config and data mounts" + success_msg: "The running container carries read-only config and writable data mounts" + vars: + mautrix_gmessages_config_mount: >- + {{ mautrix_gmessages_container.Mounts + | selectattr('Destination', 'equalto', '/config') + | first | default({}) }} + mautrix_gmessages_data_mount: >- + {{ mautrix_gmessages_container.Mounts + | selectattr('Destination', 'equalto', '/data') + | first | default({}) }} + + - name: Assert the rendered labels are attached to the running container + ansible.builtin.assert: + that: + - mautrix_gmessages_container.Config.Labels['traefik.enable'] == 'true' + - mautrix_gmessages_container.Config.Labels['traefik.docker.network'] == matrix_bridge_mautrix_gmessages_container_network + - mautrix_gmessages_container.Config.Labels['traefik.http.services.matrix-mautrix-gmessages-exposure.loadbalancer.server.port'] == '8080' + - mautrix_gmessages_container.Config.Labels['molecule.gmessages.coverage'] == 'enabled' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The running container carries the labels the role rendered" + + - name: Assert the running container has the exact network and port exposure + ansible.builtin.assert: + that: + - mautrix_gmessages_container.HostConfig.NetworkMode == matrix_bridge_mautrix_gmessages_container_network + - matrix_bridge_mautrix_gmessages_container_network in mautrix_gmessages_container.NetworkSettings.Networks + - mautrix_gmessages_container.NetworkSettings.Networks | length == 1 + - mautrix_gmessages_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: >- + The container has unexpected networks or host ports: + networks={{ mautrix_gmessages_container.NetworkSettings.Networks.keys() | list }}, + ports={{ mautrix_gmessages_container.HostConfig.PortBindings | default({}) }} + success_msg: "The container uses only its dedicated network and publishes no host ports" diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-gmessages/tasks/main.yml index df53f0892..49d152dc1 100644 --- a/roles/custom/matrix-bridge-mautrix-gmessages/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-gmessages/tasks/main.yml @@ -11,15 +11,15 @@ - install-all - install-mautrix-gmessages block: - - when: matrix_mautrix_gmessages_enabled | bool + - when: matrix_bridge_mautrix_gmessages_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_gmessages_enabled | bool + - when: matrix_bridge_mautrix_gmessages_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mautrix-gmessages block: - - when: not matrix_mautrix_gmessages_enabled | bool + - when: not matrix_bridge_mautrix_gmessages_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-gmessages/tasks/setup_install.yml index 96aa55778..5465a1a4f 100644 --- a/roles/custom/matrix-bridge-mautrix-gmessages/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-gmessages/tasks/setup_install.yml @@ -8,32 +8,32 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_gmessages_migration_requires_restart: false + matrix_bridge_mautrix_gmessages_migration_requires_restart: false -- when: "matrix_mautrix_gmessages_database_engine == 'postgres'" +- when: "matrix_bridge_mautrix_gmessages_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mautrix_gmessages_sqlite_database_path_local }}" - register: matrix_mautrix_gmessages_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mautrix_gmessages_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_gmessages_sqlite_database_path_local_stat_result - - when: "matrix_mautrix_gmessages_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mautrix_gmessages_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mautrix_gmessages_sqlite_database_path_local }}" - dst: "{{ matrix_mautrix_gmessages_database_connection_string }}" + src: "{{ matrix_bridge_mautrix_gmessages_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_gmessages_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mautrix_gmessages_database_engine' + engine_variable_name: 'matrix_bridge_mautrix_gmessages_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-mautrix-gmessages.service'] pgloader_options: ['--with "quote identifiers"'] - ansible.builtin.set_fact: - matrix_mautrix_gmessages_migration_requires_restart: true + matrix_bridge_mautrix_gmessages_migration_requires_restart: true - name: Ensure Mautrix gmessages paths exists ansible.builtin.file: @@ -43,56 +43,62 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_gmessages_base_path }}", when: true} - - {path: "{{ matrix_mautrix_gmessages_config_path }}", when: true} - - {path: "{{ matrix_mautrix_gmessages_data_path }}", when: true} - - {path: "{{ matrix_mautrix_gmessages_container_src_files_path }}", when: "{{ matrix_mautrix_gmessages_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_gmessages_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_gmessages_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_gmessages_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_gmessages_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_gmessages_container_image_self_build }}"} when: item.when | bool - name: Ensure Mautrix gmessages image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_gmessages_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_gmessages_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_gmessages_container_image_force_pull }}" - when: not matrix_mautrix_gmessages_container_image_self_build - register: matrix_mautrix_gmessages_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_gmessages_container_image }}" + pull: always + when: not matrix_bridge_mautrix_gmessages_container_image_self_build + register: matrix_bridge_mautrix_gmessages_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_gmessages_container_image_pull_result is not failed + until: matrix_bridge_mautrix_gmessages_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix gmessages repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_gmessages_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_gmessages_container_image_self_build | bool" - name: Ensure Mautrix gmessages repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_mautrix_gmessages_container_image_self_build_repo }}" - dest: "{{ matrix_mautrix_gmessages_container_src_files_path }}" - version: "{{ matrix_mautrix_gmessages_container_image_self_build_branch }}" + repo: "{{ matrix_bridge_mautrix_gmessages_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_mautrix_gmessages_container_src_files_path }}" + version: "{{ matrix_bridge_mautrix_gmessages_container_image_self_build_branch }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_gmessages_git_pull_results - when: "matrix_mautrix_gmessages_container_image_self_build | bool" + register: matrix_bridge_mautrix_gmessages_git_pull_results + when: "matrix_bridge_mautrix_gmessages_container_image_self_build | bool" - name: Ensure Mautrix gmessages Docker image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_gmessages_container_image }}" - source: build - force_source: "{{ matrix_mautrix_gmessages_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_gmessages_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_gmessages_container_src_files_path }}" - pull: true - when: "matrix_mautrix_gmessages_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_gmessages_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_gmessages_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_gmessages_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_gmessages_container_image_self_build | bool" + register: matrix_bridge_mautrix_gmessages_container_image_build_result - name: Check if an old database file exists ansible.builtin.stat: - path: "{{ matrix_mautrix_gmessages_base_path }}/mautrix-gmessages.db" - register: matrix_mautrix_gmessages_stat_database + path: "{{ matrix_bridge_mautrix_gmessages_base_path }}/mautrix-gmessages.db" + register: matrix_bridge_mautrix_gmessages_stat_database - name: Check if an old Matrix state file exists ansible.builtin.stat: - path: "{{ matrix_mautrix_gmessages_base_path }}/mx-state.json" - register: matrix_mautrix_gmessages_stat_mx_state + path: "{{ matrix_bridge_mautrix_gmessages_base_path }}/mx-state.json" + register: matrix_bridge_mautrix_gmessages_stat_mx_state - name: (Data relocation) Ensure matrix-mautrix-gmessages.service is stopped ansible.builtin.service: @@ -101,75 +107,77 @@ enabled: false daemon_reload: true failed_when: false - when: "matrix_mautrix_gmessages_stat_database.stat.exists" + when: "matrix_bridge_mautrix_gmessages_stat_database.stat.exists" - name: (Data relocation) Move mautrix-gmessages database file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_mautrix_gmessages_base_path }}/mautrix-gmessages.db {{ matrix_mautrix_gmessages_data_path }}/mautrix-gmessages.db" - creates: "{{ matrix_mautrix_gmessages_data_path }}/mautrix-gmessages.db" - removes: "{{ matrix_mautrix_gmessages_base_path }}/mautrix-gmessages.db" - when: "matrix_mautrix_gmessages_stat_database.stat.exists" + cmd: "mv {{ matrix_bridge_mautrix_gmessages_base_path }}/mautrix-gmessages.db {{ matrix_bridge_mautrix_gmessages_data_path }}/mautrix-gmessages.db" + creates: "{{ matrix_bridge_mautrix_gmessages_data_path }}/mautrix-gmessages.db" + removes: "{{ matrix_bridge_mautrix_gmessages_base_path }}/mautrix-gmessages.db" + when: "matrix_bridge_mautrix_gmessages_stat_database.stat.exists" - name: (Data relocation) Move mautrix-gmessages mx-state file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_mautrix_gmessages_base_path }}/mx-state.json {{ matrix_mautrix_gmessages_data_path }}/mx-state.json" - creates: "{{ matrix_mautrix_gmessages_data_path }}/mx-state.json" - removes: "{{ matrix_mautrix_gmessages_base_path }}/mx-state.json" - when: "matrix_mautrix_gmessages_stat_mx_state.stat.exists" + cmd: "mv {{ matrix_bridge_mautrix_gmessages_base_path }}/mx-state.json {{ matrix_bridge_mautrix_gmessages_data_path }}/mx-state.json" + creates: "{{ matrix_bridge_mautrix_gmessages_data_path }}/mx-state.json" + removes: "{{ matrix_bridge_mautrix_gmessages_base_path }}/mx-state.json" + when: "matrix_bridge_mautrix_gmessages_stat_mx_state.stat.exists" - name: Ensure mautrix-gmessages config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_gmessages_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_gmessages_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_gmessages_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_gmessages_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_gmessages_config_result + register: matrix_bridge_mautrix_gmessages_config_result - name: Ensure mautrix-gmessages registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_gmessages_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_gmessages_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_gmessages_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_gmessages_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_gmessages_registration_result + register: matrix_bridge_mautrix_gmessages_registration_result - name: Ensure matrix-mautrix-gmessages.service installed ansible.builtin.template: src: "{{ role_path }}/templates/systemd/matrix-mautrix-gmessages.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-gmessages.service" mode: '0644' - register: matrix_mautrix_gmessages_systemd_service_result + register: matrix_bridge_mautrix_gmessages_systemd_service_result - name: Ensure mautrix-gmessages support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_gmessages_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_gmessages_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_mautrix_gmessages_support_files_result + register: matrix_bridge_mautrix_gmessages_support_files_result - name: Ensure matrix-mautrix-gmessages container network is created + when: matrix_bridge_mautrix_gmessages_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_gmessages_container_network }}" + name: "{{ matrix_bridge_mautrix_gmessages_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - name: Determine whether matrix-mautrix-gmessages needs a restart ansible.builtin.set_fact: - matrix_mautrix_gmessages_restart_necessary: >- + matrix_bridge_mautrix_gmessages_restart_necessary: >- {{ - matrix_mautrix_gmessages_migration_requires_restart | default(false) - or matrix_mautrix_gmessages_config_result.changed | default(false) - or matrix_mautrix_gmessages_registration_result.changed | default(false) - or matrix_mautrix_gmessages_support_files_result.changed | default(false) - or matrix_mautrix_gmessages_systemd_service_result.changed | default(false) - or matrix_mautrix_gmessages_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_gmessages_migration_requires_restart | default(false) + or matrix_bridge_mautrix_gmessages_config_result.changed | default(false) + or matrix_bridge_mautrix_gmessages_registration_result.changed | default(false) + or matrix_bridge_mautrix_gmessages_support_files_result.changed | default(false) + or matrix_bridge_mautrix_gmessages_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_gmessages_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_gmessages_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mautrix-gmessages.service restarted, if necessary @@ -177,4 +185,4 @@ name: "matrix-mautrix-gmessages.service" state: restarted daemon_reload: true - when: "matrix_mautrix_gmessages_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_gmessages_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-gmessages/tasks/setup_uninstall.yml index e0fae19e7..a80a97660 100644 --- a/roles/custom/matrix-bridge-mautrix-gmessages/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-gmessages/tasks/setup_uninstall.yml @@ -7,9 +7,9 @@ - name: Check existence of matrix-mautrix-gmessages service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-gmessages.service" - register: matrix_mautrix_gmessages_service_stat + register: matrix_bridge_mautrix_gmessages_service_stat -- when: matrix_mautrix_gmessages_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_gmessages_service_stat.stat.exists | bool block: - name: Ensure matrix-mautrix-gmessages is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-gmessages/tasks/validate_config.yml index 728700fcd..4574228e4 100644 --- a/roles/custom/matrix-bridge-mautrix-gmessages/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-gmessages/tasks/validate_config.yml @@ -13,17 +13,30 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_gmessages_log_level', 'new': 'matrix_mautrix_gmessages_logging_level'} - - {'old': 'matrix_mautrix_gmessages_bridge_mute_bridging', 'new': ''} - - {'old': 'matrix_mautrix_gmessages_login_shared_secret', 'new': ''} - - {'old': 'matrix_mautrix_gmessages_bridge_login_shared_secret_map', 'new': 'matrix_mautrix_gmessages_double_puppet_secrets_custom'} - - {'old': 'matrix_mautrix_gmessages_docker_image_name_prefix', 'new': 'matrix_mautrix_gmessages_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_gmessages_docker_image', 'new': 'matrix_mautrix_gmessages_container_image'} - - {'old': 'matrix_mautrix_gmessages_docker_image_force_pull', 'new': 'matrix_mautrix_gmessages_container_image_force_pull'} - - {'old': 'matrix_mautrix_gmessages_docker_image_registry_prefix', 'new': 'matrix_mautrix_gmessages_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_gmessages_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_gmessages_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_gmessages_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_gmessages_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_gmessages_docker_src_files_path', 'new': 'matrix_mautrix_gmessages_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_gmessages_log_level', 'new': 'matrix_bridge_mautrix_gmessages_logging_level'} + - {'old': 'matrix_bridge_mautrix_gmessages_bridge_mute_bridging', 'new': ''} + - {'old': 'matrix_bridge_mautrix_gmessages_login_shared_secret', 'new': ''} + - {'old': 'matrix_bridge_mautrix_gmessages_bridge_login_shared_secret_map', 'new': 'matrix_bridge_mautrix_gmessages_double_puppet_secrets_custom'} + - {'old': 'matrix_bridge_mautrix_gmessages_docker_image_name_prefix', 'new': 'matrix_bridge_mautrix_gmessages_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_gmessages_docker_image', 'new': 'matrix_bridge_mautrix_gmessages_container_image'} + - {'old': 'matrix_bridge_mautrix_gmessages_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_gmessages_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_gmessages_docker_image_registry_prefix', 'new': 'matrix_bridge_mautrix_gmessages_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_gmessages_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mautrix_gmessages_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mautrix_gmessages_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mautrix_gmessages_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mautrix_gmessages_docker_src_files_path', 'new': 'matrix_bridge_mautrix_gmessages_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_gmessages_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_mautrix_gmessages_metrics_enabled', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_metrics_proxying_enabled', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_metrics_proxying_hostname', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_metrics_proxying_path_prefix', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_container_labels_metrics_enabled', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_container_labels_metrics_traefik_rule', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_container_labels_metrics_traefik_priority', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_container_labels_metrics_traefik_entrypoints', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_container_labels_metrics_traefik_tls', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_container_labels_metrics_traefik_tls_certResolver', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (mautrix-gmessages does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gmessages_container_labels_metrics_middleware_basic_auth_users', 'new': ' (mautrix-gmessages does not support metrics)'} - name: Fail if required mautrix-gmessages settings not defined ansible.builtin.fail: @@ -31,10 +44,8 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_gmessages_appservice_token', when: true} - - {'name': 'matrix_mautrix_gmessages_homeserver_address', when: true} - - {'name': 'matrix_mautrix_gmessages_homeserver_token', when: true} - - {'name': 'matrix_mautrix_gmessages_database_hostname', when: "{{ matrix_mautrix_gmessages_database_engine == 'postgres' }}"} - - {'name': 'matrix_mautrix_gmessages_metrics_proxying_hostname', when: "{{ matrix_mautrix_gmessages_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_gmessages_metrics_proxying_path_prefix', when: "{{ matrix_mautrix_gmessages_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_gmessages_container_network', when: true} + - {'name': 'matrix_bridge_mautrix_gmessages_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_gmessages_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_gmessages_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_gmessages_database_hostname', when: "{{ matrix_bridge_mautrix_gmessages_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_gmessages_container_network', when: true} diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-gmessages/templates/config.yaml.j2 index ae87f818d..f52a81186 100644 --- a/roles/custom/matrix-bridge-mautrix-gmessages/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-gmessages/templates/config.yaml.j2 @@ -2,7 +2,7 @@ # Network-specific config options network: # Displayname template for SMS users. - displayname_template: {{ matrix_mautrix_gmessages_network_displayname_template | to_json }} + displayname_template: {{ matrix_bridge_mautrix_gmessages_network_displayname_template | to_json }} # Settings for how the bridge appears to the phone. device_meta: # OS name to tell the phone. This is the name that shows up in the paired devices list. @@ -24,9 +24,9 @@ network: # Config options that affect the central bridge module. bridge: # The prefix for commands. Only required in non-management rooms. - command_prefix: '!gm' + command_prefix: {{ matrix_bridge_mautrix_gmessages_command_prefix | to_json }} # Should the bridge create a space for each login containing the rooms that account is in? - personal_filtering_spaces: {{ matrix_mautrix_gmessages_bridge_personal_filtering_spaces | to_json }} + personal_filtering_spaces: {{ matrix_bridge_mautrix_gmessages_bridge_personal_filtering_spaces | to_json }} # Whether the bridge should set names and avatars explicitly for DM portals. # This is only necessary when using clients that don't support MSC4171. private_chat_portal_meta: false @@ -122,7 +122,7 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_gmessages_bridge_permissions|to_json }} + permissions: {{ matrix_bridge_mautrix_gmessages_bridge_permissions|to_json }} # Config for the bridge's database. database: @@ -133,7 +133,7 @@ database: # https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_mautrix_gmessages_appservice_database_uri|to_json }} + uri: {{ matrix_bridge_mautrix_gmessages_appservice_database_uri|to_json }} # Maximum number of connections. max_open_conns: 5 max_idle_conns: 1 @@ -147,9 +147,9 @@ homeserver: # The address that this appservice can use to connect to the homeserver. # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, # but https also works if they run on different machines. - address: {{ matrix_mautrix_gmessages_homeserver_address | to_json }} + address: {{ matrix_bridge_mautrix_gmessages_homeserver_address | to_json }} # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: {{ matrix_mautrix_gmessages_homeserver_domain | to_json }} + domain: {{ matrix_bridge_mautrix_gmessages_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -165,7 +165,7 @@ homeserver: # The bridge will use the appservice as_token to authorize requests. message_send_checkpoint_endpoint: # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_mautrix_gmessages_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_mautrix_gmessages_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -178,10 +178,10 @@ homeserver: # Changing these values requires regeneration of the registration (except when noted otherwise) appservice: # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_mautrix_gmessages_appservice_address }} + address: {{ matrix_bridge_mautrix_gmessages_appservice_address }} # A public address that external services can use to reach this appservice. # This value doesn't affect the registration file. - public_address: https://bridge.example.com + public_address: {{ matrix_bridge_mautrix_gmessages_bridge_public_address | to_json }} # The hostname and port where this appservice should listen. # For Docker, you generally have to change the hostname to 0.0.0.0. @@ -193,7 +193,7 @@ appservice: # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_mautrix_gmessages_appservice_bot_username|to_json }} + username: {{ matrix_bridge_mautrix_gmessages_appservice_bot_username|to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. displayname: Google Messages bridge bot @@ -208,12 +208,12 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_mautrix_gmessages_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_gmessages_homeserver_token | to_json }} + as_token: {{ matrix_bridge_mautrix_gmessages_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_gmessages_homeserver_token | to_json }} # Localpart template of MXIDs for remote users. # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. - username_template: {{ matrix_mautrix_gmessages_appservice_username_template | to_json }} + username_template: {{ matrix_bridge_mautrix_gmessages_appservice_username_template | to_json }} # Config options that affect the Matrix connector of the bridge. matrix: @@ -227,7 +227,7 @@ matrix: sync_direct_chat_list: false # Whether created rooms should have federation enabled. If false, created portal rooms # will never be federated. Changing this option requires recreating rooms. - federate_rooms: {{ matrix_mautrix_gmessages_federate_rooms | to_json }} + federate_rooms: {{ matrix_bridge_mautrix_gmessages_federate_rooms | to_json }} # The threshold as bytes after which the bridge should roundtrip uploads via the disk # rather than keeping the whole file in memory. upload_file_threshold: 5242880 @@ -247,7 +247,7 @@ provisioning: prefix: /_matrix/provision # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, # or if set to "disable", the provisioning API will be disabled. - shared_secret: disable + shared_secret: {{ matrix_bridge_mautrix_gmessages_provisioning_shared_secret | to_json }} # Whether to allow provisioning API requests to be authed using Matrix access tokens. # This follows the same rules as double puppeting to determine which server to contact to check the token, # which means that by default, it only works for users on the same server as the bridge. @@ -263,7 +263,7 @@ public_media: enabled: false # A key for signing public media URLs. # If set to "generate", a random key will be generated. - signing_key: {{ matrix_mautrix_gmessages_public_media_signing_key | to_json }} + signing_key: {{ matrix_bridge_mautrix_gmessages_public_media_signing_key | to_json }} # Number of seconds that public media URLs are valid for. # If set to 0, URLs will never expire. expiry: 0 @@ -297,18 +297,18 @@ direct_media: # See https://docs.mau.fi/bridges/general/backfill.html for more details. backfill: # Whether to do backfilling at all. - enabled: {{ matrix_mautrix_gmessages_backfill_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_gmessages_backfill_enabled | to_json }} # Maximum number of messages to backfill in empty rooms. - max_initial_messages: {{ matrix_mautrix_gmessages_backfill_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_mautrix_gmessages_backfill_max_initial_messages | to_json }} # Maximum number of missed messages to backfill after bridge restarts. - max_catchup_messages: {{ matrix_mautrix_gmessages_backfill_max_catchup_messages | to_json }} + max_catchup_messages: {{ matrix_bridge_mautrix_gmessages_backfill_max_catchup_messages | to_json }} # If a backfilled chat is older than this number of hours, # mark it as read even if it's unread on the remote network. - unread_hours_threshold: {{ matrix_mautrix_gmessages_backfill_unread_hours_threshold | to_json }} + unread_hours_threshold: {{ matrix_bridge_mautrix_gmessages_backfill_unread_hours_threshold | to_json }} # Settings for backfilling threads within other backfills. threads: # Maximum number of messages to backfill in a new thread. - max_initial_messages: {{ matrix_mautrix_gmessages_backfill_threads_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_mautrix_gmessages_backfill_threads_max_initial_messages | to_json }} # Settings for the backwards backfill queue. This only applies when connecting to # Beeper as standard Matrix servers don't support inserting messages into history. queue: @@ -336,35 +336,35 @@ double_puppet: allow_discovery: false # Shared secrets for automatic double puppeting. # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. - secrets: {{ matrix_mautrix_gmessages_double_puppet_secrets | to_json }} + secrets: {{ matrix_bridge_mautrix_gmessages_double_puppet_secrets | to_json }} # End-to-bridge encryption support options. # # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. - allow: {{ matrix_mautrix_gmessages_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_mautrix_gmessages_bridge_encryption_allow | to_json }} # Whether to force-enable encryption in all bridged rooms. - default: {{ matrix_mautrix_gmessages_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_mautrix_gmessages_bridge_encryption_default | to_json }} # Whether to require all messages to be encrypted and drop any unencrypted messages. - require: {{ matrix_mautrix_gmessages_bridge_encryption_require | to_json }} + require: {{ matrix_bridge_mautrix_gmessages_bridge_encryption_require | to_json }} # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. # This option is not yet compatible with standard Matrix servers like Synapse and should not be used. - appservice: {{ matrix_mautrix_gmessages_bridge_encryption_appservice | to_json }} + appservice: {{ matrix_bridge_mautrix_gmessages_bridge_encryption_appservice | to_json }} # Whether to use MSC4190 instead of appservice login to create the bridge bot device. # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_mautrix_gmessages_msc4190_enabled | to_json }} + msc4190: {{ matrix_bridge_mautrix_gmessages_msc4190_enabled | to_json }} # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) # Requires msc4190 to replace keys on reset - self_sign: {{ matrix_mautrix_gmessages_self_sign_enabled | to_json }} + self_sign: {{ matrix_bridge_mautrix_gmessages_self_sign_enabled | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_mautrix_gmessages_bridge_encryption_key_sharing_allow | to_json }} + allow_key_sharing: {{ matrix_bridge_mautrix_gmessages_bridge_encryption_key_sharing_allow | to_json }} # Pickle key for encrypting encryption keys in the bridge database. # If set to generate, a random key will be generated. - pickle_key: {{ matrix_mautrix_gmessages_bridge_encryption_pickle_key | to_json }} + pickle_key: {{ matrix_bridge_mautrix_gmessages_bridge_encryption_pickle_key | to_json }} # Options for deleting megolm sessions from the bridge. delete_keys: # Beeper-specific: delete outbound sessions when hungryserv confirms @@ -423,7 +423,7 @@ encryption: # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_mautrix_gmessages_logging_level }} + min_level: {{ matrix_bridge_mautrix_gmessages_logging_level }} writers: - type: stdout format: pretty diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-gmessages/templates/labels.j2 index 8dfe66067..fe0033fef 100644 --- a/roles/custom/matrix-bridge-mautrix-gmessages/templates/labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-gmessages/templates/labels.j2 @@ -4,44 +4,42 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_gmessages_container_labels_traefik_enabled %} +{% if matrix_bridge_mautrix_gmessages_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_mautrix_gmessages_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_gmessages_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_gmessages_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_gmessages_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.matrix-mautrix-gmessages-metrics.loadbalancer.server.port=8001 - -{% if matrix_mautrix_gmessages_container_labels_metrics_enabled %} +{% if matrix_bridge_mautrix_gmessages_container_labels_exposure_enabled %} ############################################################ # # -# Metrics # +# Bridge API exposure # # # ############################################################ -{% if matrix_mautrix_gmessages_container_labels_metrics_middleware_basic_auth_enabled %} -traefik.http.middlewares.matrix-mautrix-gmessages-metrics-basic-auth.basicauth.users={{ matrix_mautrix_gmessages_container_labels_metrics_middleware_basic_auth_users }} -traefik.http.routers.matrix-mautrix-gmessages-metrics.middlewares=matrix-mautrix-gmessages-metrics-basic-auth -{% endif %} +traefik.http.services.matrix-mautrix-gmessages-exposure.loadbalancer.server.port=8080 + +traefik.http.middlewares.matrix-mautrix-gmessages-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_gmessages_exposure_path_prefix }} +traefik.http.routers.matrix-mautrix-gmessages-exposure.middlewares=matrix-mautrix-gmessages-exposure-strip-prefix -traefik.http.routers.matrix-mautrix-gmessages-metrics.rule={{ matrix_mautrix_gmessages_container_labels_metrics_traefik_rule }} +traefik.http.routers.matrix-mautrix-gmessages-exposure.rule={{ matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_rule }} -{% if matrix_mautrix_gmessages_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-gmessages-metrics.priority={{ matrix_mautrix_gmessages_container_labels_metrics_traefik_priority }} +{% if matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-gmessages-exposure.priority={{ matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_priority }} {% endif %} -traefik.http.routers.matrix-mautrix-gmessages-metrics.service=matrix-mautrix-gmessages-metrics -traefik.http.routers.matrix-mautrix-gmessages-metrics.entrypoints={{ matrix_mautrix_gmessages_container_labels_metrics_traefik_entrypoints }} +traefik.http.routers.matrix-mautrix-gmessages-exposure.service=matrix-mautrix-gmessages-exposure +traefik.http.routers.matrix-mautrix-gmessages-exposure.entrypoints={{ matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_entrypoints }} -traefik.http.routers.matrix-mautrix-gmessages-metrics.tls={{ matrix_mautrix_gmessages_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_mautrix_gmessages_container_labels_metrics_traefik_tls %} -traefik.http.routers.matrix-mautrix-gmessages-metrics.tls.certResolver={{ matrix_mautrix_gmessages_container_labels_metrics_traefik_tls_certResolver }} +traefik.http.routers.matrix-mautrix-gmessages-exposure.tls={{ matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-mautrix-gmessages-exposure.tls.certResolver={{ matrix_bridge_mautrix_gmessages_container_labels_exposure_traefik_tls_certResolver }} {% endif %} ############################################################ # # -# /Metrics # +# /Bridge API exposure # # # ############################################################ {% endif %} @@ -49,4 +47,4 @@ traefik.http.routers.matrix-mautrix-gmessages-metrics.tls.certResolver={{ matrix {% endif %} -{{ matrix_mautrix_gmessages_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_gmessages_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-gmessages/templates/systemd/matrix-mautrix-gmessages.service.j2 b/roles/custom/matrix-bridge-mautrix-gmessages/templates/systemd/matrix-mautrix-gmessages.service.j2 index 9cc2f58ab..6a39d46d9 100644 --- a/roles/custom/matrix-bridge-mautrix-gmessages/templates/systemd/matrix-mautrix-gmessages.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-gmessages/templates/systemd/matrix-mautrix-gmessages.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix gmessages bridge -{% for service in matrix_mautrix_gmessages_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_gmessages_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_gmessages_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_gmessages_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,20 +22,22 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_gmessages_container_network }} \ - --mount type=bind,src={{ matrix_mautrix_gmessages_config_path }},dst=/config \ - --mount type=bind,src={{ matrix_mautrix_gmessages_data_path }},dst=/data \ - --label-file={{ matrix_mautrix_gmessages_base_path }}/labels \ + --network={{ matrix_bridge_mautrix_gmessages_container_network }} \ + --mount type=bind,src={{ matrix_bridge_mautrix_gmessages_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_gmessages_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_gmessages_base_path }}/labels \ --workdir=/data \ - {% for arg in matrix_mautrix_gmessages_container_extra_arguments %} + {% for arg in matrix_bridge_mautrix_gmessages_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_gmessages_container_image }} \ + {{ matrix_bridge_mautrix_gmessages_container_image }} \ /usr/bin/mautrix-gmessages -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_mautrix_gmessages_container_additional_networks %} +{% if matrix_bridge_mautrix_gmessages_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_gmessages_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-gmessages {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-gmessages diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-googlechat/defaults/main.yml index e47836b94..9553dd747 100644 --- a/roles/custom/matrix-bridge-mautrix-googlechat/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-googlechat/defaults/main.yml @@ -13,116 +13,115 @@ # mautrix-googlechat is a Matrix <-> googlechat bridge # Project source code URL: https://github.com/mautrix/googlechat -matrix_mautrix_googlechat_enabled: true +matrix_bridge_mautrix_googlechat_enabled: true -matrix_mautrix_googlechat_container_image_self_build: false -matrix_mautrix_googlechat_container_image_self_build_repo: "https://github.com/mautrix/googlechat.git" -matrix_mautrix_googlechat_container_image_self_build_repo_version: "{{ 'master' if matrix_mautrix_googlechat_version == 'latest' else matrix_mautrix_googlechat_version }}" +matrix_bridge_mautrix_googlechat_container_image_self_build: false +matrix_bridge_mautrix_googlechat_container_image_self_build_repo: "https://github.com/mautrix/googlechat.git" +matrix_bridge_mautrix_googlechat_container_image_self_build_repo_version: "{{ 'master' if matrix_bridge_mautrix_googlechat_version == 'latest' else matrix_bridge_mautrix_googlechat_version }}" # renovate: datasource=docker depName=dock.mau.dev/mautrix/googlechat -matrix_mautrix_googlechat_version: v0.5.2 +matrix_bridge_mautrix_googlechat_version: v0.5.2 # See: https://mau.dev/mautrix/googlechat/container_registry -matrix_mautrix_googlechat_container_image: "{{ matrix_mautrix_googlechat_container_image_registry_prefix }}mautrix/googlechat:{{ matrix_mautrix_googlechat_version }}" -matrix_mautrix_googlechat_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_googlechat_container_image_self_build else matrix_mautrix_googlechat_container_image_registry_prefix_upstream }}" -matrix_mautrix_googlechat_container_image_registry_prefix_upstream: "{{ matrix_mautrix_googlechat_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_googlechat_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_googlechat_container_image_force_pull: "{{ matrix_mautrix_googlechat_container_image.endswith(':latest') }}" +matrix_bridge_mautrix_googlechat_container_image: "{{ matrix_bridge_mautrix_googlechat_container_image_registry_prefix }}mautrix/googlechat:{{ matrix_bridge_mautrix_googlechat_version }}" +matrix_bridge_mautrix_googlechat_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_googlechat_container_image_self_build else matrix_bridge_mautrix_googlechat_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_googlechat_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_googlechat_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_googlechat_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_googlechat_base_path: "{{ matrix_base_data_path }}/mautrix-googlechat" -matrix_mautrix_googlechat_config_path: "{{ matrix_mautrix_googlechat_base_path }}/config" -matrix_mautrix_googlechat_data_path: "{{ matrix_mautrix_googlechat_base_path }}/data" -matrix_mautrix_googlechat_container_src_files_path: "{{ matrix_mautrix_googlechat_base_path }}/docker-src" +matrix_bridge_mautrix_googlechat_base_path: "{{ matrix_base_data_path }}/mautrix-googlechat" +matrix_bridge_mautrix_googlechat_config_path: "{{ matrix_bridge_mautrix_googlechat_base_path }}/config" +matrix_bridge_mautrix_googlechat_data_path: "{{ matrix_bridge_mautrix_googlechat_base_path }}/data" +matrix_bridge_mautrix_googlechat_container_src_files_path: "{{ matrix_bridge_mautrix_googlechat_base_path }}/docker-src" -matrix_mautrix_googlechat_public_endpoint: '/mautrix-googlechat' +matrix_bridge_mautrix_googlechat_public_endpoint: '/mautrix-googlechat' -matrix_mautrix_googlechat_homeserver_address: "" -matrix_mautrix_googlechat_homeserver_domain: '{{ matrix_domain }}' -matrix_mautrix_googlechat_appservice_address: 'http://matrix-mautrix-googlechat:8080' +matrix_bridge_mautrix_googlechat_homeserver_address: "" +matrix_bridge_mautrix_googlechat_homeserver_domain: '{{ matrix_domain }}' +matrix_bridge_mautrix_googlechat_appservice_address: 'http://matrix-mautrix-googlechat:8080' -matrix_mautrix_googlechat_command_prefix: "!gc" +matrix_bridge_mautrix_googlechat_command_prefix: "!gc" # Controls whether the matrix-mautrix-googlechat container exposes its HTTP port (tcp/8080 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:9007"), or empty string to not expose. -matrix_mautrix_googlechat_container_http_host_bind_port: '' +matrix_bridge_mautrix_googlechat_container_http_host_bind_port: '' -matrix_mautrix_googlechat_container_network: "" +matrix_bridge_mautrix_googlechat_container_network: "" -matrix_mautrix_googlechat_container_additional_networks: "{{ matrix_mautrix_googlechat_container_additional_networks_auto + matrix_mautrix_googlechat_container_additional_networks_custom }}" -matrix_mautrix_googlechat_container_additional_networks_auto: [] -matrix_mautrix_googlechat_container_additional_networks_custom: [] +matrix_bridge_mautrix_googlechat_container_additional_networks: "{{ matrix_bridge_mautrix_googlechat_container_additional_networks_auto + matrix_bridge_mautrix_googlechat_container_additional_networks_custom }}" +matrix_bridge_mautrix_googlechat_container_additional_networks_auto: [] +matrix_bridge_mautrix_googlechat_container_additional_networks_custom: [] -# matrix_mautrix_googlechat_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_mautrix_googlechat_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_googlechat_container_labels_additional_labels`. -matrix_mautrix_googlechat_container_labels_traefik_enabled: true -matrix_mautrix_googlechat_container_labels_traefik_docker_network: "{{ matrix_mautrix_googlechat_container_network }}" -matrix_mautrix_googlechat_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_googlechat_container_labels_traefik_tls_certResolver: default # noqa var-naming +# To inject your own other container labels, see `matrix_bridge_mautrix_googlechat_container_labels_additional_labels`. +matrix_bridge_mautrix_googlechat_container_labels_traefik_enabled: true +matrix_bridge_mautrix_googlechat_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_googlechat_container_network }}" +matrix_bridge_mautrix_googlechat_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_googlechat_container_labels_traefik_tls_certResolver: default # noqa var-naming # Controls whether labels will be added that expose mautrix-googlechat's public endpoint -matrix_mautrix_googlechat_container_labels_public_endpoint_enabled: true -matrix_mautrix_googlechat_container_labels_public_endpoint_hostname: "" -matrix_mautrix_googlechat_container_labels_public_endpoint_path_prefix: "{{ matrix_mautrix_googlechat_public_endpoint }}" -matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_rule: "Host(`{{ matrix_mautrix_googlechat_container_labels_public_endpoint_hostname }}`) && PathPrefix(`{{ matrix_mautrix_googlechat_container_labels_public_endpoint_path_prefix }}`)" -matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_priority: 0 -matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_entrypoints: "{{ matrix_mautrix_googlechat_container_labels_traefik_entrypoints }}" -matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_tls: "{{ matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_entrypoints != 'web' }}" -matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_tls_certResolver: "{{ matrix_mautrix_googlechat_container_labels_traefik_tls_certResolver }}" # noqa var-naming +matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_enabled: true +matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_hostname: "" +matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_path_prefix: "{{ matrix_bridge_mautrix_googlechat_public_endpoint }}" +matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_rule: "Host(`{{ matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_path_prefix }}`)" +matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_priority: 0 +matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_entrypoints: "{{ matrix_bridge_mautrix_googlechat_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_tls: "{{ matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_googlechat_container_labels_traefik_tls_certResolver }}" # noqa var-naming # Controls whether labels will be added that expose mautrix-googlechat's metrics -matrix_mautrix_googlechat_container_labels_metrics_enabled: "{{ matrix_mautrix_googlechat_metrics_enabled and matrix_mautrix_googlechat_metrics_proxying_enabled }}" -matrix_mautrix_googlechat_container_labels_metrics_traefik_rule: "Host(`{{ matrix_mautrix_googlechat_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_mautrix_googlechat_metrics_proxying_path_prefix }}`)" -matrix_mautrix_googlechat_container_labels_metrics_traefik_priority: 0 -matrix_mautrix_googlechat_container_labels_metrics_traefik_entrypoints: "{{ matrix_mautrix_googlechat_container_labels_traefik_entrypoints }}" -matrix_mautrix_googlechat_container_labels_metrics_traefik_tls: "{{ matrix_mautrix_googlechat_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_mautrix_googlechat_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_mautrix_googlechat_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_mautrix_googlechat_container_labels_metrics_middleware_basic_auth_enabled: false +matrix_bridge_mautrix_googlechat_container_labels_metrics_enabled: "{{ matrix_bridge_mautrix_googlechat_metrics_enabled and matrix_bridge_mautrix_googlechat_metrics_proxying_enabled }}" +matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_rule: "Host(`{{ matrix_bridge_mautrix_googlechat_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_googlechat_metrics_proxying_path_prefix }}`)" +matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_priority: 0 +matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_entrypoints: "{{ matrix_bridge_mautrix_googlechat_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_tls: "{{ matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_googlechat_container_labels_traefik_tls_certResolver }}" # noqa var-naming +matrix_bridge_mautrix_googlechat_container_labels_metrics_middleware_basic_auth_enabled: false # See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_mautrix_googlechat_container_labels_metrics_middleware_basic_auth_users: '' +matrix_bridge_mautrix_googlechat_container_labels_metrics_middleware_basic_auth_users: '' -# matrix_mautrix_googlechat_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# matrix_bridge_mautrix_googlechat_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_googlechat_container_labels_additional_labels: | +# matrix_bridge_mautrix_googlechat_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_googlechat_container_labels_additional_labels: '' +matrix_bridge_mautrix_googlechat_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_googlechat_container_extra_arguments: [] +matrix_bridge_mautrix_googlechat_container_extra_arguments: [] # List of systemd services that matrix-mautrix-googlechat.service depends on. -matrix_mautrix_googlechat_systemd_required_services_list: "{{ matrix_mautrix_googlechat_systemd_required_services_list_default + matrix_mautrix_googlechat_systemd_required_services_list_auto + matrix_mautrix_googlechat_systemd_required_services_list_custom }}" -matrix_mautrix_googlechat_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_googlechat_systemd_required_services_list_auto: [] -matrix_mautrix_googlechat_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_googlechat_systemd_required_services_list: "{{ matrix_bridge_mautrix_googlechat_systemd_required_services_list_default + matrix_bridge_mautrix_googlechat_systemd_required_services_list_auto + matrix_bridge_mautrix_googlechat_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_googlechat_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_googlechat_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_googlechat_systemd_required_services_list_custom: [] # List of systemd services that matrix-mautrix-googlechat.service wants -matrix_mautrix_googlechat_systemd_wanted_services_list: [] +matrix_bridge_mautrix_googlechat_systemd_wanted_services_list: [] -matrix_mautrix_googlechat_appservice_token: '' -matrix_mautrix_googlechat_homeserver_token: '' +matrix_bridge_mautrix_googlechat_appservice_token: '' +matrix_bridge_mautrix_googlechat_homeserver_token: '' # Whether or not metrics endpoint should be enabled. # Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_mautrix_googlechat_metrics_proxying_enabled`. -matrix_mautrix_googlechat_metrics_enabled: false +# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_bridge_mautrix_googlechat_metrics_proxying_enabled`. +matrix_bridge_mautrix_googlechat_metrics_enabled: false # Controls whether metrics should be proxied (exposed) on a public URL. -matrix_mautrix_googlechat_metrics_proxying_enabled: false -matrix_mautrix_googlechat_metrics_proxying_hostname: '' -matrix_mautrix_googlechat_metrics_proxying_path_prefix: '' +matrix_bridge_mautrix_googlechat_metrics_proxying_enabled: false +matrix_bridge_mautrix_googlechat_metrics_proxying_hostname: '' +matrix_bridge_mautrix_googlechat_metrics_proxying_path_prefix: '' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_mautrix_googlechat_federate_rooms: true +matrix_bridge_mautrix_googlechat_federate_rooms: true -matrix_mautrix_googlechat_bridge_permissions: | +matrix_bridge_mautrix_googlechat_bridge_permissions: | {{ - {matrix_mautrix_googlechat_homeserver_domain: 'user'} + {matrix_bridge_mautrix_googlechat_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} @@ -131,83 +130,81 @@ matrix_mautrix_googlechat_bridge_permissions: | # To use SQLite, stick to these defaults. # # To use Postgres: -# - change the engine (`matrix_mautrix_googlechat_database_engine: 'postgres'`) -# - adjust your database credentials via the `matrix_mautrix_googlechat_database_*` variables -matrix_mautrix_googlechat_database_engine: 'sqlite' +# - change the engine (`matrix_bridge_mautrix_googlechat_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_mautrix_googlechat_database_*` variables +matrix_bridge_mautrix_googlechat_database_engine: 'sqlite' -matrix_mautrix_googlechat_sqlite_database_path_local: "{{ matrix_mautrix_googlechat_data_path }}/mautrix-googlechat.db" -matrix_mautrix_googlechat_sqlite_database_path_in_container: "/data/mautrix-googlechat.db" +matrix_bridge_mautrix_googlechat_sqlite_database_path_local: "{{ matrix_bridge_mautrix_googlechat_data_path }}/mautrix-googlechat.db" +matrix_bridge_mautrix_googlechat_sqlite_database_path_in_container: "/data/mautrix-googlechat.db" -matrix_mautrix_googlechat_database_username: 'matrix_mautrix_googlechat' -matrix_mautrix_googlechat_database_password: 'some-password' -matrix_mautrix_googlechat_database_hostname: '' -matrix_mautrix_googlechat_database_port: 5432 -matrix_mautrix_googlechat_database_name: 'matrix_mautrix_googlechat' +matrix_bridge_mautrix_googlechat_database_username: 'matrix_mautrix_googlechat' +matrix_bridge_mautrix_googlechat_database_password: 'some-password' +matrix_bridge_mautrix_googlechat_database_hostname: '' +matrix_bridge_mautrix_googlechat_database_port: 5432 +matrix_bridge_mautrix_googlechat_database_name: 'matrix_mautrix_googlechat' -matrix_mautrix_googlechat_database_connection_string: 'postgres://{{ matrix_mautrix_googlechat_database_username }}:{{ matrix_mautrix_googlechat_database_password }}@{{ matrix_mautrix_googlechat_database_hostname }}:{{ matrix_mautrix_googlechat_database_port }}/{{ matrix_mautrix_googlechat_database_name }}' +matrix_bridge_mautrix_googlechat_database_connection_string: 'postgres://{{ matrix_bridge_mautrix_googlechat_database_username }}:{{ matrix_bridge_mautrix_googlechat_database_password }}@{{ matrix_bridge_mautrix_googlechat_database_hostname }}:{{ matrix_bridge_mautrix_googlechat_database_port }}/{{ matrix_bridge_mautrix_googlechat_database_name }}' -matrix_mautrix_googlechat_appservice_database: "{{ - { - 'sqlite': ('sqlite:///' + matrix_mautrix_googlechat_sqlite_database_path_in_container), - 'postgres': matrix_mautrix_googlechat_database_connection_string, - }[matrix_mautrix_googlechat_database_engine] -}}" +matrix_bridge_mautrix_googlechat_appservice_database: "{{ { + 'sqlite': ('sqlite:///' + matrix_bridge_mautrix_googlechat_sqlite_database_path_in_container), + 'postgres': matrix_bridge_mautrix_googlechat_database_connection_string, +}[matrix_bridge_mautrix_googlechat_database_engine] }}" # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth) or Appservice Double Puppet. -matrix_mautrix_googlechat_login_shared_secret: '' +matrix_bridge_mautrix_googlechat_login_shared_secret: '' -matrix_mautrix_googlechat_appservice_bot_username: googlechatbot +matrix_bridge_mautrix_googlechat_appservice_bot_username: googlechatbot # Specifies the default log level for all bridge loggers. -matrix_mautrix_googlechat_logging_level: WARNING +matrix_bridge_mautrix_googlechat_logging_level: WARNING # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_googlechat_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_googlechat_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_googlechat_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_googlechat_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_googlechat_configuration_extension_yaml: | +matrix_bridge_mautrix_googlechat_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_googlechat_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_googlechat_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_googlechat_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_googlechat_configuration_yaml`. -matrix_mautrix_googlechat_configuration_extension: "{{ matrix_mautrix_googlechat_configuration_extension_yaml | from_yaml if matrix_mautrix_googlechat_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_googlechat_configuration_extension: "{{ matrix_bridge_mautrix_googlechat_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_googlechat_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_googlechat_configuration_yaml`. -matrix_mautrix_googlechat_configuration: "{{ matrix_mautrix_googlechat_configuration_yaml | from_yaml | combine(matrix_mautrix_googlechat_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_googlechat_configuration_yaml`. +matrix_bridge_mautrix_googlechat_configuration: "{{ matrix_bridge_mautrix_googlechat_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_googlechat_configuration_extension, recursive=True) }}" -matrix_mautrix_googlechat_registration_yaml: | +matrix_bridge_mautrix_googlechat_registration_yaml: | id: googlechat - as_token: "{{ matrix_mautrix_googlechat_appservice_token }}" - hs_token: "{{ matrix_mautrix_googlechat_homeserver_token }}" + as_token: "{{ matrix_bridge_mautrix_googlechat_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_googlechat_homeserver_token }}" namespaces: users: - exclusive: true - regex: '^@googlechat_.+:{{ matrix_mautrix_googlechat_homeserver_domain | regex_escape }}$' + regex: '^@googlechat_.+:{{ matrix_bridge_mautrix_googlechat_homeserver_domain | regex_escape }}$' - exclusive: true - regex: '^@{{ matrix_mautrix_googlechat_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_googlechat_homeserver_domain | regex_escape }}$' - url: {{ matrix_mautrix_googlechat_appservice_address }} + regex: '^@{{ matrix_bridge_mautrix_googlechat_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_googlechat_homeserver_domain | regex_escape }}$' + url: {{ matrix_bridge_mautrix_googlechat_appservice_address }} # See https://github.com/mautrix/signal/issues/43 - sender_localpart: _bot_{{ matrix_mautrix_googlechat_appservice_bot_username }} + sender_localpart: _bot_{{ matrix_bridge_mautrix_googlechat_appservice_bot_username }} rate_limited: false de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true -matrix_mautrix_googlechat_registration: "{{ matrix_mautrix_googlechat_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_googlechat_registration: "{{ matrix_bridge_mautrix_googlechat_registration_yaml | from_yaml }}" # Enable End-to-bridge encryption -matrix_mautrix_googlechat_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_googlechat_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_googlechat_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_googlechat_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -# matrix_mautrix_googlechat_restart_necessary controls whether the service +# matrix_bridge_mautrix_googlechat_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -215,4 +212,4 @@ matrix_mautrix_googlechat_bridge_encryption_default: "{{ matrix_bridges_encrypti # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_googlechat_restart_necessary: false +matrix_bridge_mautrix_googlechat_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/converge.yml new file mode 100644 index 000000000..2e77c53f5 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-googlechat Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-googlechat Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-googlechat is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-googlechat systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-googlechat.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/molecule.yml new file mode 100644 index 000000000..f015b134e --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/molecule.yml @@ -0,0 +1,90 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-googlechat-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_googlechat_container_network: mautrix-googlechat-molecule + + # The stub is the Matrix-side boundary. The scenario carries no Google account + # and does not attempt to log in to Google Chat. + matrix_bridge_mautrix_googlechat_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_googlechat_homeserver_domain: molecule.local + matrix_homeserver_url: http://matrix.molecule.local:8008 + + # Postgres is the normal deployment path. Non-default identifiers make its schema + # evidence that the role composed and supplied this exact connection string. + matrix_bridge_mautrix_googlechat_database_engine: postgres + matrix_bridge_mautrix_googlechat_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_googlechat_database_name: molecule_googlechat + matrix_bridge_mautrix_googlechat_database_username: molecule_googlechat + matrix_bridge_mautrix_googlechat_database_password: molecule_pg_password_7c1d43 + + matrix_bridge_mautrix_googlechat_appservice_token: molecule_googlechat_as_token_96c74e + matrix_bridge_mautrix_googlechat_homeserver_token: molecule_googlechat_hs_token_51a2d8 + + # These differ from role/component defaults so parsed assertions prove rendering. + matrix_bridge_mautrix_googlechat_appservice_bot_username: molecule-googlechatbot + matrix_bridge_mautrix_googlechat_command_prefix: "!molecule-googlechat" + matrix_bridge_mautrix_googlechat_logging_level: INFO + matrix_bridge_mautrix_googlechat_federate_rooms: false + matrix_bridge_mautrix_googlechat_login_shared_secret: molecule_googlechat_login_secret_6832f1 + matrix_bridge_mautrix_googlechat_metrics_enabled: true + + # Traefik is not started; these values exercise role-rendered routing labels. + matrix_bridge_mautrix_googlechat_public_endpoint: /molecule-googlechat + matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_hostname: googlechat.molecule.local + matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_path_prefix: /molecule-googlechat + matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_entrypoints: web + matrix_bridge_mautrix_googlechat_container_labels_metrics_enabled: true + matrix_bridge_mautrix_googlechat_metrics_proxying_hostname: metrics.molecule.local + matrix_bridge_mautrix_googlechat_metrics_proxying_path_prefix: /metrics/googlechat + matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_entrypoints: web + matrix_bridge_mautrix_googlechat_container_labels_additional_labels: | + molecule.googlechat.coverage=enabled + + # verify.yml is a separate play, where role defaults are out of scope. + matrix_bridge_mautrix_googlechat_base_path: /matrix/mautrix-googlechat + matrix_bridge_mautrix_googlechat_config_path: /matrix/mautrix-googlechat/config + matrix_bridge_mautrix_googlechat_data_path: /matrix/mautrix-googlechat/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/prepare.yml new file mode 100644 index 000000000..218539fb6 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/prepare.yml @@ -0,0 +1,86 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-googlechat Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_googlechat_container_network }}" + register: mautrix_googlechat_molecule_network + changed_when: mautrix_googlechat_molecule_network.rc == 0 + failed_when: + - mautrix_googlechat_molecule_network.rc != 0 + - "'already exists' not in mautrix_googlechat_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_googlechat_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_googlechat_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_googlechat_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_googlechat_database_password }}" + + # The bridge verifies the appservice bot before opening its listener. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_googlechat_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_googlechat_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_googlechat_appservice_bot_username }}:{{ matrix_bridge_mautrix_googlechat_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/verify.yml new file mode 100644 index 000000000..cecc05da2 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-googlechat/molecule/default/verify.yml @@ -0,0 +1,344 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the old Python bridge accepts the role-rendered configuration, completes its +# Matrix-side startup, migrates real Postgres and exposes its appservice and metrics. +- name: Verify mautrix-googlechat + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + mautrix_googlechat_config: "{{ mautrix_googlechat_config_file.content | b64decode | from_yaml }}" + mautrix_googlechat_registration: "{{ mautrix_googlechat_registration_file.content | b64decode | from_yaml }}" + mautrix_googlechat_labels_rendered: "{{ mautrix_googlechat_labels_file.content | b64decode }}" + gather_facts: false + tasks: + # Read the version from the role so a Renovate bump changes the expected image. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_googlechat_role_defaults + + - name: Wait for the mautrix-googlechat service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-googlechat.service + register: mautrix_googlechat_service + until: mautrix_googlechat_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_googlechat_service.status.ActiveState == 'active' + - mautrix_googlechat_service.status.NRestarts is defined + - mautrix_googlechat_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-googlechat.service is + {{ mautrix_googlechat_service.status.ActiveState | default('unknown') }} after + {{ mautrix_googlechat_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-mautrix-googlechat.service is active and has not restarted" + + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_googlechat_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-googlechat:8080/_matrix/mau/live + register: mautrix_googlechat_live + changed_when: false + until: mautrix_googlechat_live.rc == 0 and mautrix_googlechat_live.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_googlechat_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-googlechat:8080/_matrix/mau/ready + register: mautrix_googlechat_ready + changed_when: false + until: mautrix_googlechat_ready.rc == 0 and mautrix_googlechat_ready.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on its appservice listener + ansible.builtin.assert: + that: + - mautrix_googlechat_live.rc == 0 + - mautrix_googlechat_live.stdout == 'HTTP_STATUS=200' + - mautrix_googlechat_ready.rc == 0 + - mautrix_googlechat_ready.stdout == 'HTTP_STATUS=200' + fail_msg: >- + Health probes returned live={{ mautrix_googlechat_live.stdout | default('none') }} and + ready={{ mautrix_googlechat_ready.stdout | default('none') }} + success_msg: "The bridge is live and ready on its appservice listener" + + - name: Query the enabled metrics listener + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_googlechat_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --fail + - http://matrix-mautrix-googlechat:8000/metrics + register: mautrix_googlechat_metrics + changed_when: false + + - name: Assert the live metrics surface comes from the running Python bridge + ansible.builtin.assert: + that: + - mautrix_googlechat_metrics.rc == 0 + - "'# HELP python_gc_objects_collected_total' in mautrix_googlechat_metrics.stdout" + - "'# HELP process_start_time_seconds' in mautrix_googlechat_metrics.stdout" + - "'# HELP python_info' in mautrix_googlechat_metrics.stdout" + fail_msg: "The enabled metrics listener did not expose the Python process metrics" + success_msg: "The enabled metrics listener exposes the Python process metrics" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_googlechat_config_path }}/config.yaml" + register: mautrix_googlechat_config_file + + - name: Assert the rendered configuration carries the appservice identity + ansible.builtin.assert: + that: + - mautrix_googlechat_config.homeserver.address == matrix_bridge_mautrix_googlechat_homeserver_address + - mautrix_googlechat_config.homeserver.domain == matrix_bridge_mautrix_googlechat_homeserver_domain + - mautrix_googlechat_config.appservice.id == 'googlechat' + - mautrix_googlechat_config.appservice.address == 'http://matrix-mautrix-googlechat:8080' + - mautrix_googlechat_config.appservice.bot_username == matrix_bridge_mautrix_googlechat_appservice_bot_username + - mautrix_googlechat_config.appservice.as_token == matrix_bridge_mautrix_googlechat_appservice_token + - mautrix_googlechat_config.appservice.hs_token == matrix_bridge_mautrix_googlechat_homeserver_token + fail_msg: "The rendered configuration does not carry the scenario's appservice identity" + success_msg: "The rendered configuration carries the scenario's appservice identity" + + - name: Assert the rendered configuration carries non-default bridge behavior + ansible.builtin.assert: + that: + - mautrix_googlechat_config.bridge.command_prefix == matrix_bridge_mautrix_googlechat_command_prefix + - not mautrix_googlechat_config.bridge.federate_rooms + - mautrix_googlechat_config.bridge.login_shared_secret == matrix_bridge_mautrix_googlechat_login_shared_secret + - mautrix_googlechat_config.bridge.web.auth.public == 'http://matrix.molecule.local:8008/molecule-googlechat/login' + - mautrix_googlechat_config.bridge.web.auth.prefix == '/molecule-googlechat/login' + - mautrix_googlechat_config.metrics.enabled + - mautrix_googlechat_config.logging.root.level == matrix_bridge_mautrix_googlechat_logging_level + fail_msg: "The rendered configuration does not carry the scenario's bridge behavior" + success_msg: "The rendered configuration carries the scenario's bridge behavior" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - mautrix_googlechat_config.appservice.database is string + - mautrix_googlechat_config.appservice.database is match('^postgres://') + - matrix_bridge_mautrix_googlechat_database_username in mautrix_googlechat_config.appservice.database + - matrix_bridge_mautrix_googlechat_database_hostname in mautrix_googlechat_config.appservice.database + - matrix_bridge_mautrix_googlechat_database_name in mautrix_googlechat_config.appservice.database + fail_msg: >- + appservice.database is {{ mautrix_googlechat_config.appservice.database | default('unset') }}, + which was not composed from the scenario's Postgres settings + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_googlechat_config_path }}/registration.yaml" + register: mautrix_googlechat_registration_file + + - name: Assert the registration carries the configured handshake values + ansible.builtin.assert: + that: + - mautrix_googlechat_registration.id == 'googlechat' + - mautrix_googlechat_registration.as_token == matrix_bridge_mautrix_googlechat_appservice_token + - mautrix_googlechat_registration.hs_token == matrix_bridge_mautrix_googlechat_homeserver_token + - mautrix_googlechat_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_googlechat_appservice_bot_username + - mautrix_googlechat_registration.url == 'http://matrix-mautrix-googlechat:8080' + fail_msg: "The registration does not carry the configured handshake values" + success_msg: "The registration carries the configured handshake values" + + - name: Assert the registration namespaces cover only Google Chat ghosts and the bot + ansible.builtin.assert: + that: + - mautrix_googlechat_ghost_regex | length > 0 + - mautrix_googlechat_bot_regex | length > 0 + - mautrix_googlechat_ghost_mxid is match(mautrix_googlechat_ghost_regex) + - mautrix_googlechat_wrong_ghost_mxid is not match(mautrix_googlechat_ghost_regex) + - mautrix_googlechat_bot_mxid is match(mautrix_googlechat_bot_regex) + fail_msg: "The registration namespaces do not cover only Google Chat ghosts and the bot" + success_msg: "The registration namespaces cover only Google Chat ghosts and the bot" + vars: + mautrix_googlechat_user_regexes: "{{ mautrix_googlechat_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_googlechat_ghost_regex: "{{ mautrix_googlechat_user_regexes | select('search', 'googlechat_') | first | default('') }}" + mautrix_googlechat_bot_regex: "{{ mautrix_googlechat_user_regexes | reject('search', 'googlechat_') | first | default('') }}" + mautrix_googlechat_ghost_mxid: "@googlechat_123456:{{ matrix_bridge_mautrix_googlechat_homeserver_domain }}" + mautrix_googlechat_wrong_ghost_mxid: "@gvoice_123456:{{ matrix_bridge_mautrix_googlechat_homeserver_domain }}" + mautrix_googlechat_bot_mxid: "@{{ matrix_bridge_mautrix_googlechat_appservice_bot_username }}:{{ matrix_bridge_mautrix_googlechat_homeserver_domain }}" + + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_googlechat_database_username }} + - --dbname={{ matrix_bridge_mautrix_googlechat_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: mautrix_googlechat_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - mautrix_googlechat_tables.rc == 0 + - "'version' in mautrix_googlechat_table_names" + - "'portal' in mautrix_googlechat_table_names" + - "'puppet' in mautrix_googlechat_table_names" + - "'message' in mautrix_googlechat_table_names" + - "'mx_version' in mautrix_googlechat_table_names" + - mautrix_googlechat_table_names | length >= 10 + fail_msg: >- + The bridge did not migrate its schema into {{ matrix_bridge_mautrix_googlechat_database_name }} + (found {{ mautrix_googlechat_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + mautrix_googlechat_table_names: "{{ mautrix_googlechat_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_googlechat_base_path }}/labels" + register: mautrix_googlechat_labels_file + + - name: Assert the labels route both HTTP surfaces to their configured ports + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_googlechat_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_googlechat_container_network in mautrix_googlechat_labels_rendered" + - "'traefik.http.services.matrix-mautrix-googlechat-public.loadbalancer.server.port=8080' in mautrix_googlechat_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-googlechat-public.rule=Host(`googlechat.molecule.local`) && PathPrefix(`/molecule-googlechat`)' in mautrix_googlechat_labels_rendered" + - "'traefik.http.services.matrix-mautrix-googlechat-metrics.loadbalancer.server.port=8000' in mautrix_googlechat_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-googlechat-metrics.rule=Host(`metrics.molecule.local`) && PathPrefix(`/metrics/googlechat`)' in mautrix_googlechat_labels_rendered" + - "'molecule.googlechat.coverage=enabled' in mautrix_googlechat_labels_rendered" + fail_msg: "The rendered labels do not carry both HTTP routing contracts" + success_msg: "The rendered labels carry both HTTP routing contracts" + + - name: Inspect the running bridge container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-googlechat + register: mautrix_googlechat_container_inspect + changed_when: false + + - name: Parse the running bridge container inspection + ansible.builtin.set_fact: + mautrix_googlechat_container: "{{ (mautrix_googlechat_container_inspect.stdout | from_json) | first }}" + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - mautrix_googlechat_container.Config.Image == mautrix_googlechat_expected_image + fail_msg: >- + The running container uses {{ mautrix_googlechat_container.Config.Image }}, expected + {{ mautrix_googlechat_expected_image }} + success_msg: "The running container uses the exact image pinned by the role" + vars: + mautrix_googlechat_expected_image: >- + {{ mautrix_googlechat_role_defaults.matrix_bridge_mautrix_googlechat_container_image_registry_prefix_upstream_default }}mautrix/googlechat:{{ mautrix_googlechat_role_defaults.matrix_bridge_mautrix_googlechat_version }} + + - name: Assert the running container uses the playbook-supplied runtime + ansible.builtin.assert: + that: + - mautrix_googlechat_container.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + - mautrix_googlechat_container.Config.WorkingDir == '/opt/mautrix-googlechat' + - mautrix_googlechat_container.Config.Cmd == ['python3', '-m', 'mautrix_googlechat', '-c', '/config/config.yaml', '--no-update'] + - mautrix_googlechat_container.HostConfig.RestartPolicy.Name == 'no' + - mautrix_googlechat_container.HostConfig.AutoRemove + - mautrix_googlechat_container.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container does not use the role's exact identity, command and workdir" + success_msg: "The running container uses the role's exact identity, command and workdir" + + - name: Assert the running container has the intended privilege isolation + ansible.builtin.assert: + that: + - "'ALL' in mautrix_googlechat_container.HostConfig.CapDrop" + - not mautrix_googlechat_container.HostConfig.Privileged + fail_msg: "The running container does not have the intended privilege isolation" + success_msg: "The running container drops all capabilities and is unprivileged" + + - name: Assert the running container carries the role's two bind mounts + ansible.builtin.assert: + that: + - mautrix_googlechat_config_mount | length > 0 + - mautrix_googlechat_config_mount.Source == matrix_bridge_mautrix_googlechat_config_path + - not mautrix_googlechat_config_mount.RW + - mautrix_googlechat_data_mount | length > 0 + - mautrix_googlechat_data_mount.Source == matrix_bridge_mautrix_googlechat_data_path + - mautrix_googlechat_data_mount.RW + - mautrix_googlechat_container.Mounts | length == 2 + fail_msg: "The running container does not carry the role's exact config and data mounts" + success_msg: "The running container carries its read-only config and writable data mounts" + vars: + mautrix_googlechat_config_mount: >- + {{ mautrix_googlechat_container.Mounts + | selectattr('Destination', 'equalto', '/config') + | first | default({}) }} + mautrix_googlechat_data_mount: >- + {{ mautrix_googlechat_container.Mounts + | selectattr('Destination', 'equalto', '/data') + | first | default({}) }} + + - name: Assert the rendered labels are attached to the running container + ansible.builtin.assert: + that: + - mautrix_googlechat_container.Config.Labels['traefik.enable'] == 'true' + - mautrix_googlechat_container.Config.Labels['traefik.docker.network'] == matrix_bridge_mautrix_googlechat_container_network + - mautrix_googlechat_container.Config.Labels['traefik.http.services.matrix-mautrix-googlechat-public.loadbalancer.server.port'] == '8080' + - mautrix_googlechat_container.Config.Labels['traefik.http.services.matrix-mautrix-googlechat-metrics.loadbalancer.server.port'] == '8000' + - mautrix_googlechat_container.Config.Labels['molecule.googlechat.coverage'] == 'enabled' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The running container carries the labels the role rendered" + + - name: Assert the running container has the exact network and port exposure + ansible.builtin.assert: + that: + - mautrix_googlechat_container.HostConfig.NetworkMode == matrix_bridge_mautrix_googlechat_container_network + - matrix_bridge_mautrix_googlechat_container_network in mautrix_googlechat_container.NetworkSettings.Networks + - mautrix_googlechat_container.NetworkSettings.Networks | length == 1 + - mautrix_googlechat_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: >- + The container has unexpected networks or host ports: + networks={{ mautrix_googlechat_container.NetworkSettings.Networks.keys() | list }}, + ports={{ mautrix_googlechat_container.HostConfig.PortBindings | default({}) }} + success_msg: "The container uses only its dedicated network and publishes no host ports" diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-googlechat/tasks/main.yml index 3cdc701da..06d619770 100644 --- a/roles/custom/matrix-bridge-mautrix-googlechat/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-googlechat/tasks/main.yml @@ -12,15 +12,15 @@ - install-all - install-mautrix-googlechat block: - - when: matrix_mautrix_googlechat_enabled | bool + - when: matrix_bridge_mautrix_googlechat_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_googlechat_enabled | bool + - when: matrix_bridge_mautrix_googlechat_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mautrix-googlechat block: - - when: not matrix_mautrix_googlechat_enabled | bool + - when: not matrix_bridge_mautrix_googlechat_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-googlechat/tasks/setup_install.yml index 562ac67e3..a9249a38c 100644 --- a/roles/custom/matrix-bridge-mautrix-googlechat/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-googlechat/tasks/setup_install.yml @@ -11,43 +11,41 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_googlechat_migration_requires_restart: false + matrix_bridge_mautrix_googlechat_migration_requires_restart: false -- when: "matrix_mautrix_googlechat_database_engine == 'postgres'" +- when: "matrix_bridge_mautrix_googlechat_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mautrix_googlechat_sqlite_database_path_local }}" - register: matrix_mautrix_googlechat_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mautrix_googlechat_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_googlechat_sqlite_database_path_local_stat_result - - when: "matrix_mautrix_googlechat_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mautrix_googlechat_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mautrix_googlechat_sqlite_database_path_local }}" - dst: "{{ matrix_mautrix_googlechat_database_connection_string }}" + src: "{{ matrix_bridge_mautrix_googlechat_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_googlechat_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mautrix_googlechat_database_engine' + engine_variable_name: 'matrix_bridge_mautrix_googlechat_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-mautrix-googlechat.service'] - ansible.builtin.set_fact: - matrix_mautrix_googlechat_migration_requires_restart: true + matrix_bridge_mautrix_googlechat_migration_requires_restart: true - name: Ensure Mautrix googlechat image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_googlechat_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_googlechat_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_googlechat_container_image_force_pull }}" - when: not matrix_mautrix_googlechat_container_image_self_build - register: matrix_mautrix_googlechat_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_googlechat_container_image }}" + pull: always + when: not matrix_bridge_mautrix_googlechat_container_image_self_build + register: matrix_bridge_mautrix_googlechat_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_googlechat_container_image_pull_result is not failed + until: matrix_bridge_mautrix_googlechat_container_image_pull_result is not failed - name: Ensure Mautrix googlechat paths exist ansible.builtin.file: @@ -57,39 +55,47 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_googlechat_base_path }}", when: true} - - {path: "{{ matrix_mautrix_googlechat_config_path }}", when: true} - - {path: "{{ matrix_mautrix_googlechat_data_path }}", when: true} - - {path: "{{ matrix_mautrix_googlechat_container_src_files_path }}", when: "{{ matrix_mautrix_googlechat_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_googlechat_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_googlechat_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_googlechat_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_googlechat_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_googlechat_container_image_self_build }}"} when: "item.when | bool" +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix Hangots repository ownership is correct on self build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_googlechat_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_googlechat_container_image_self_build | bool" + - name: Ensure Mautrix Hangots repository is present on self build ansible.builtin.git: - repo: "{{ matrix_mautrix_googlechat_container_image_self_build_repo }}" - version: "{{ matrix_mautrix_googlechat_container_image_self_build_repo_version }}" - dest: "{{ matrix_mautrix_googlechat_container_src_files_path }}" + repo: "{{ matrix_bridge_mautrix_googlechat_container_image_self_build_repo }}" + version: "{{ matrix_bridge_mautrix_googlechat_container_image_self_build_repo_version }}" + dest: "{{ matrix_bridge_mautrix_googlechat_container_src_files_path }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_googlechat_git_pull_results - when: "matrix_mautrix_googlechat_container_image_self_build | bool" + register: matrix_bridge_mautrix_googlechat_git_pull_results + when: "matrix_bridge_mautrix_googlechat_container_image_self_build | bool" - name: Ensure Mautrix googlechat Docker image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_googlechat_container_image }}" - source: build - force_source: "{{ matrix_mautrix_googlechat_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_googlechat_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_googlechat_container_src_files_path }}" - pull: true - when: "matrix_mautrix_googlechat_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_googlechat_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_googlechat_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_googlechat_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_googlechat_container_image_self_build | bool" + register: matrix_bridge_mautrix_googlechat_container_image_build_result - name: Check if an old database file already exists ansible.builtin.stat: - path: "{{ matrix_mautrix_googlechat_base_path }}/mautrix-googlechat.db" - register: matrix_mautrix_googlechat_stat_database + path: "{{ matrix_bridge_mautrix_googlechat_base_path }}/mautrix-googlechat.db" + register: matrix_bridge_mautrix_googlechat_stat_database - name: (Data relocation) Ensure matrix-mautrix-googlechat.service is stopped ansible.builtin.service: @@ -98,48 +104,49 @@ enabled: false daemon_reload: true failed_when: false - when: "matrix_mautrix_googlechat_stat_database.stat.exists" + when: "matrix_bridge_mautrix_googlechat_stat_database.stat.exists" - name: (Data relocation) Move mautrix-googlechat database file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_mautrix_googlechat_base_path }}/mautrix-googlechat.db {{ matrix_mautrix_googlechat_data_path }}/mautrix-googlechat.db" - creates: "{{ matrix_mautrix_googlechat_data_path }}/mautrix-googlechat.db" - removes: "{{ matrix_mautrix_googlechat_base_path }}/mautrix-googlechat.db" - when: "matrix_mautrix_googlechat_stat_database.stat.exists" + cmd: "mv {{ matrix_bridge_mautrix_googlechat_base_path }}/mautrix-googlechat.db {{ matrix_bridge_mautrix_googlechat_data_path }}/mautrix-googlechat.db" + creates: "{{ matrix_bridge_mautrix_googlechat_data_path }}/mautrix-googlechat.db" + removes: "{{ matrix_bridge_mautrix_googlechat_base_path }}/mautrix-googlechat.db" + when: "matrix_bridge_mautrix_googlechat_stat_database.stat.exists" - name: Ensure mautrix-googlechat config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_googlechat_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_googlechat_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_googlechat_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_googlechat_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_googlechat_config_result + register: matrix_bridge_mautrix_googlechat_config_result - name: Ensure mautrix-googlechat registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_googlechat_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_googlechat_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_googlechat_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_googlechat_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_googlechat_registration_result + register: matrix_bridge_mautrix_googlechat_registration_result - name: Ensure mautrix-googlechat support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_googlechat_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_googlechat_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_mautrix_googlechat_support_files_result + register: matrix_bridge_mautrix_googlechat_support_files_result - name: Ensure matrix-mautrix-googlechat container network is created + when: matrix_bridge_mautrix_googlechat_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_googlechat_container_network }}" + name: "{{ matrix_bridge_mautrix_googlechat_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -148,18 +155,19 @@ src: "{{ role_path }}/templates/systemd/matrix-mautrix-googlechat.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-googlechat.service" mode: '0644' - register: matrix_mautrix_googlechat_systemd_service_result + register: matrix_bridge_mautrix_googlechat_systemd_service_result - name: Determine whether matrix-mautrix-googlechat needs a restart ansible.builtin.set_fact: - matrix_mautrix_googlechat_restart_necessary: >- + matrix_bridge_mautrix_googlechat_restart_necessary: >- {{ - matrix_mautrix_googlechat_migration_requires_restart | default(false) - or matrix_mautrix_googlechat_config_result.changed | default(false) - or matrix_mautrix_googlechat_registration_result.changed | default(false) - or matrix_mautrix_googlechat_support_files_result.changed | default(false) - or matrix_mautrix_googlechat_systemd_service_result.changed | default(false) - or matrix_mautrix_googlechat_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_googlechat_migration_requires_restart | default(false) + or matrix_bridge_mautrix_googlechat_config_result.changed | default(false) + or matrix_bridge_mautrix_googlechat_registration_result.changed | default(false) + or matrix_bridge_mautrix_googlechat_support_files_result.changed | default(false) + or matrix_bridge_mautrix_googlechat_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_googlechat_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_googlechat_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mautrix-googlechat.service restarted, if necessary @@ -167,4 +175,4 @@ name: "matrix-mautrix-googlechat.service" state: restarted daemon_reload: true - when: "matrix_mautrix_googlechat_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_googlechat_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-googlechat/tasks/setup_uninstall.yml index 412a08847..a32247ba9 100644 --- a/roles/custom/matrix-bridge-mautrix-googlechat/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-googlechat/tasks/setup_uninstall.yml @@ -9,9 +9,9 @@ - name: Check existence of matrix-mautrix-googlechat service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-googlechat.service" - register: matrix_mautrix_googlechat_service_stat + register: matrix_bridge_mautrix_googlechat_service_stat -- when: matrix_mautrix_googlechat_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_googlechat_service_stat.stat.exists | bool block: - name: Ensure matrix-mautrix-googlechat is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-googlechat/tasks/validate_config.yml index cdcf7ea26..c6b185667 100644 --- a/roles/custom/matrix-bridge-mautrix-googlechat/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-googlechat/tasks/validate_config.yml @@ -14,13 +14,14 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_googlechat_docker_image_name_prefix', 'new': 'matrix_mautrix_googlechat_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_googlechat_docker_image', 'new': 'matrix_mautrix_googlechat_container_image'} - - {'old': 'matrix_mautrix_googlechat_docker_image_force_pull', 'new': 'matrix_mautrix_googlechat_container_image_force_pull'} - - {'old': 'matrix_mautrix_googlechat_docker_image_registry_prefix', 'new': 'matrix_mautrix_googlechat_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_googlechat_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_googlechat_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_googlechat_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_googlechat_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_googlechat_docker_src_files_path', 'new': 'matrix_mautrix_googlechat_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_googlechat_docker_image_name_prefix', 'new': 'matrix_bridge_mautrix_googlechat_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_googlechat_docker_image', 'new': 'matrix_bridge_mautrix_googlechat_container_image'} + - {'old': 'matrix_bridge_mautrix_googlechat_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_googlechat_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_googlechat_docker_image_registry_prefix', 'new': 'matrix_bridge_mautrix_googlechat_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_googlechat_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mautrix_googlechat_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mautrix_googlechat_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mautrix_googlechat_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mautrix_googlechat_docker_src_files_path', 'new': 'matrix_bridge_mautrix_googlechat_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_googlechat_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required mautrix-googlechat settings not defined ansible.builtin.fail: @@ -28,13 +29,13 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_googlechat_public_endpoint', when: true} - - {'name': 'matrix_mautrix_googlechat_appservice_token', when: true} - - {'name': 'matrix_mautrix_googlechat_homeserver_token', when: true} - - {'name': 'matrix_mautrix_googlechat_database_hostname', when: "{{ matrix_mautrix_googlechat_database_engine == 'postgres' }}"} - - {'name': 'matrix_mautrix_googlechat_container_network', when: true} - - {'name': 'matrix_mautrix_googlechat_homeserver_address', when: true} - - {'name': 'matrix_mautrix_googlechat_metrics_proxying_hostname', when: "{{ matrix_mautrix_googlechat_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_googlechat_metrics_proxying_path_prefix', when: "{{ matrix_mautrix_googlechat_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_googlechat_container_labels_public_endpoint_hostname', when: "{{ matrix_mautrix_googlechat_container_labels_public_endpoint_enabled }}"} - - {'name': 'matrix_mautrix_googlechat_container_labels_public_endpoint_path_prefix', when: "{{ matrix_mautrix_googlechat_container_labels_public_endpoint_enabled }}"} + - {'name': 'matrix_bridge_mautrix_googlechat_public_endpoint', when: true} + - {'name': 'matrix_bridge_mautrix_googlechat_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_googlechat_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_googlechat_database_hostname', when: "{{ matrix_bridge_mautrix_googlechat_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_googlechat_container_network', when: true} + - {'name': 'matrix_bridge_mautrix_googlechat_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_googlechat_metrics_proxying_hostname', when: "{{ matrix_bridge_mautrix_googlechat_metrics_proxying_enabled }}"} + - {'name': 'matrix_bridge_mautrix_googlechat_metrics_proxying_path_prefix', when: "{{ matrix_bridge_mautrix_googlechat_metrics_proxying_enabled }}"} + - {'name': 'matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_hostname', when: "{{ matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_enabled }}"} + - {'name': 'matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_path_prefix', when: "{{ matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_enabled }}"} diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-googlechat/templates/config.yaml.j2 index 83b13f6cf..f3e74521b 100644 --- a/roles/custom/matrix-bridge-mautrix-googlechat/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-googlechat/templates/config.yaml.j2 @@ -2,9 +2,9 @@ # Homeserver details homeserver: # The address that this appservice can use to connect to the homeserver. - address: {{ matrix_mautrix_googlechat_homeserver_address }} + address: {{ matrix_bridge_mautrix_googlechat_homeserver_address }} # The domain of the homeserver (for MXIDs, etc). - domain: {{ matrix_mautrix_googlechat_homeserver_domain }} + domain: {{ matrix_bridge_mautrix_googlechat_homeserver_domain }} # Whether or not to verify the SSL certificate of the homeserver. # Only applies if address starts with https:// verify_ssl: true @@ -13,7 +13,7 @@ homeserver: # Changing these values requires regeneration of the registration. appservice: # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_mautrix_googlechat_appservice_address }} + address: {{ matrix_bridge_mautrix_googlechat_appservice_address }} # The hostname and port where this appservice should listen. hostname: 0.0.0.0 @@ -27,24 +27,24 @@ appservice: # Format examples: # SQLite: sqlite:///filename.db # Postgres: postgres://username:password@hostname/dbname - database: {{ matrix_mautrix_googlechat_appservice_database|to_json }} + database: {{ matrix_bridge_mautrix_googlechat_appservice_database|to_json }} # The unique ID of this appservice. id: googlechat # Username of the appservice bot. - bot_username: {{ matrix_mautrix_googlechat_appservice_bot_username|to_json }} + bot_username: {{ matrix_bridge_mautrix_googlechat_appservice_bot_username|to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. bot_displayname: googlechat bridge bot bot_avatar: mxc://maunium.net/FBXZnpfORkBEruORbikmleAy # Authentication tokens for AS <-> HS communication. - as_token: "{{ matrix_mautrix_googlechat_appservice_token }}" - hs_token: "{{ matrix_mautrix_googlechat_homeserver_token }}" + as_token: "{{ matrix_bridge_mautrix_googlechat_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_googlechat_homeserver_token }}" # Prometheus telemetry config. Requires prometheus-client to be installed. metrics: - enabled: {{ matrix_mautrix_googlechat_metrics_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_googlechat_metrics_enabled | to_json }} listen_port: 8000 # Bridge config @@ -67,7 +67,7 @@ bridge: - name # The prefix for commands. Only required in non-management rooms. - command_prefix: "{{ matrix_mautrix_googlechat_command_prefix }}" + command_prefix: "{{ matrix_bridge_mautrix_googlechat_command_prefix }}" # Number of chats to sync (and create portals for) on startup/login. # Maximum 20, set 0 to disable automatic syncing. @@ -83,7 +83,7 @@ bridge: # If set, custom puppets will be enabled automatically for local users # instead of users having to find an access token and run `login-matrix` # manually. - login_shared_secret: {{ matrix_mautrix_googlechat_login_shared_secret|to_json }} + login_shared_secret: {{ matrix_bridge_mautrix_googlechat_login_shared_secret|to_json }} # Whether or not to update avatars when syncing all contacts at startup. update_avatar_initial_sync: true # End-to-bridge encryption support options. These require matrix-nio to be installed with pip @@ -93,14 +93,14 @@ bridge: # application service. encryption: # Allow encryption, work in group chat rooms with e2ee enabled - allow: {{ matrix_mautrix_googlechat_bridge_encryption_allow|to_json }} + allow: {{ matrix_bridge_mautrix_googlechat_bridge_encryption_allow|to_json }} # Default to encryption, force-enable encryption in all portals the bridge creates # This will cause the bridge bot to be in private chats for the encryption to work properly. - default: {{ matrix_mautrix_googlechat_bridge_encryption_default|to_json }} + default: {{ matrix_bridge_mautrix_googlechat_bridge_encryption_default|to_json }} # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. - federate_rooms: {{ matrix_mautrix_googlechat_federate_rooms|to_json }} + federate_rooms: {{ matrix_bridge_mautrix_googlechat_federate_rooms|to_json }} # Public website and API configs web: # Auth server config @@ -110,8 +110,8 @@ bridge: # or otherwise pointed to the appservice's webserver to the path specified below (prefix). # This path should usually include a trailing slash. # Internal prefix in the appservice web server for the login endpoints. - public: "{{ matrix_homeserver_url }}{{ matrix_mautrix_googlechat_public_endpoint }}/login" - prefix: "{{ matrix_mautrix_googlechat_public_endpoint }}/login" + public: "{{ matrix_homeserver_url }}{{ matrix_bridge_mautrix_googlechat_public_endpoint }}/login" + prefix: "{{ matrix_bridge_mautrix_googlechat_public_endpoint }}/login" # Permissions for using the bridge. @@ -122,7 +122,7 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_googlechat_bridge_permissions|to_json }} + permissions: {{ matrix_bridge_mautrix_googlechat_bridge_permissions|to_json }} # Python logging configuration. # @@ -142,11 +142,11 @@ logging: formatter: colored loggers: mau: - level: {{ matrix_mautrix_googlechat_logging_level|to_json }} + level: {{ matrix_bridge_mautrix_googlechat_logging_level|to_json }} hangups: - level: {{ matrix_mautrix_googlechat_logging_level|to_json }} + level: {{ matrix_bridge_mautrix_googlechat_logging_level|to_json }} aiohttp: - level: {{ matrix_mautrix_googlechat_logging_level|to_json }} + level: {{ matrix_bridge_mautrix_googlechat_logging_level|to_json }} root: - level: {{ matrix_mautrix_googlechat_logging_level|to_json }} + level: {{ matrix_bridge_mautrix_googlechat_logging_level|to_json }} handlers: [console] diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-googlechat/templates/labels.j2 index 567dc2958..bc4ea211f 100644 --- a/roles/custom/matrix-bridge-mautrix-googlechat/templates/labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-googlechat/templates/labels.j2 @@ -4,35 +4,35 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_googlechat_container_labels_traefik_enabled %} +{% if matrix_bridge_mautrix_googlechat_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_mautrix_googlechat_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_googlechat_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_googlechat_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_googlechat_container_labels_traefik_docker_network }} {% endif %} traefik.http.services.matrix-mautrix-googlechat-public.loadbalancer.server.port=8080 traefik.http.services.matrix-mautrix-googlechat-metrics.loadbalancer.server.port=8000 -{% if matrix_mautrix_googlechat_container_labels_public_endpoint_enabled %} +{% if matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_enabled %} ############################################################ # # # Public # # # ############################################################ -traefik.http.routers.matrix-mautrix-googlechat-public.rule={{ matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_rule }} +traefik.http.routers.matrix-mautrix-googlechat-public.rule={{ matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_rule }} -{% if matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-googlechat-public.priority={{ matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_priority }} +{% if matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-googlechat-public.priority={{ matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_priority }} {% endif %} traefik.http.routers.matrix-mautrix-googlechat-public.service=matrix-mautrix-googlechat-public -traefik.http.routers.matrix-mautrix-googlechat-public.entrypoints={{ matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_entrypoints }} +traefik.http.routers.matrix-mautrix-googlechat-public.entrypoints={{ matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_entrypoints }} -traefik.http.routers.matrix-mautrix-googlechat-public.tls={{ matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_tls | to_json }} -{% if matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_tls %} -traefik.http.routers.matrix-mautrix-googlechat-public.tls.certResolver={{ matrix_mautrix_googlechat_container_labels_public_endpoint_traefik_tls_certResolver }} +traefik.http.routers.matrix-mautrix-googlechat-public.tls={{ matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_tls %} +traefik.http.routers.matrix-mautrix-googlechat-public.tls.certResolver={{ matrix_bridge_mautrix_googlechat_container_labels_public_endpoint_traefik_tls_certResolver }} {% endif %} ############################################################ @@ -43,30 +43,30 @@ traefik.http.routers.matrix-mautrix-googlechat-public.tls.certResolver={{ matrix {% endif %} -{% if matrix_mautrix_googlechat_container_labels_metrics_enabled %} +{% if matrix_bridge_mautrix_googlechat_container_labels_metrics_enabled %} ############################################################ # # # Metrics # # # ############################################################ -{% if matrix_mautrix_googlechat_container_labels_metrics_middleware_basic_auth_enabled %} -traefik.http.middlewares.matrix-mautrix-googlechat-metrics-basic-auth.basicauth.users={{ matrix_mautrix_googlechat_container_labels_metrics_middleware_basic_auth_users }} +{% if matrix_bridge_mautrix_googlechat_container_labels_metrics_middleware_basic_auth_enabled %} +traefik.http.middlewares.matrix-mautrix-googlechat-metrics-basic-auth.basicauth.users={{ matrix_bridge_mautrix_googlechat_container_labels_metrics_middleware_basic_auth_users }} traefik.http.routers.matrix-mautrix-googlechat-metrics.middlewares=matrix-mautrix-googlechat-metrics-basic-auth {% endif %} -traefik.http.routers.matrix-mautrix-googlechat-metrics.rule={{ matrix_mautrix_googlechat_container_labels_metrics_traefik_rule }} +traefik.http.routers.matrix-mautrix-googlechat-metrics.rule={{ matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_rule }} -{% if matrix_mautrix_googlechat_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-googlechat-metrics.priority={{ matrix_mautrix_googlechat_container_labels_metrics_traefik_priority }} +{% if matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-googlechat-metrics.priority={{ matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_priority }} {% endif %} traefik.http.routers.matrix-mautrix-googlechat-metrics.service=matrix-mautrix-googlechat-metrics -traefik.http.routers.matrix-mautrix-googlechat-metrics.entrypoints={{ matrix_mautrix_googlechat_container_labels_metrics_traefik_entrypoints }} +traefik.http.routers.matrix-mautrix-googlechat-metrics.entrypoints={{ matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_entrypoints }} -traefik.http.routers.matrix-mautrix-googlechat-metrics.tls={{ matrix_mautrix_googlechat_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_mautrix_googlechat_container_labels_metrics_traefik_tls %} -traefik.http.routers.matrix-mautrix-googlechat-metrics.tls.certResolver={{ matrix_mautrix_googlechat_container_labels_metrics_traefik_tls_certResolver }} +traefik.http.routers.matrix-mautrix-googlechat-metrics.tls={{ matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_tls %} +traefik.http.routers.matrix-mautrix-googlechat-metrics.tls.certResolver={{ matrix_bridge_mautrix_googlechat_container_labels_metrics_traefik_tls_certResolver }} {% endif %} ############################################################ @@ -79,4 +79,4 @@ traefik.http.routers.matrix-mautrix-googlechat-metrics.tls.certResolver={{ matri {% endif %} -{{ matrix_mautrix_googlechat_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_googlechat_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-googlechat/templates/systemd/matrix-mautrix-googlechat.service.j2 b/roles/custom/matrix-bridge-mautrix-googlechat/templates/systemd/matrix-mautrix-googlechat.service.j2 index 29c915d65..0a4d4f1e3 100644 --- a/roles/custom/matrix-bridge-mautrix-googlechat/templates/systemd/matrix-mautrix-googlechat.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-googlechat/templates/systemd/matrix-mautrix-googlechat.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix googlechat bridge -{% for service in matrix_mautrix_googlechat_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_googlechat_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_googlechat_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_googlechat_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,22 +22,24 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_googlechat_container_network }} \ - {% if matrix_mautrix_googlechat_container_http_host_bind_port %} - -p {{ matrix_mautrix_googlechat_container_http_host_bind_port }}:8080 \ + --network={{ matrix_bridge_mautrix_googlechat_container_network }} \ + {% if matrix_bridge_mautrix_googlechat_container_http_host_bind_port %} + -p {{ matrix_bridge_mautrix_googlechat_container_http_host_bind_port }}:8080 \ {% endif %} - --mount type=bind,src={{ matrix_mautrix_googlechat_config_path }},dst=/config \ - --mount type=bind,src={{ matrix_mautrix_googlechat_data_path }},dst=/data \ - --label-file={{ matrix_mautrix_googlechat_base_path }}/labels \ - {% for arg in matrix_mautrix_googlechat_container_extra_arguments %} + --mount type=bind,src={{ matrix_bridge_mautrix_googlechat_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_googlechat_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_googlechat_base_path }}/labels \ + {% for arg in matrix_bridge_mautrix_googlechat_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_googlechat_container_image }} \ + {{ matrix_bridge_mautrix_googlechat_container_image }} \ python3 -m mautrix_googlechat -c /config/config.yaml --no-update -{% for network in matrix_mautrix_googlechat_container_additional_networks %} +{% if matrix_bridge_mautrix_googlechat_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_googlechat_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-googlechat {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-googlechat diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-gvoice/defaults/main.yml new file mode 100644 index 000000000..5ed8a929d --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/defaults/main.yml @@ -0,0 +1,228 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# mautrix-gvoice is a Matrix <-> Google Voice bridge +# Project source code URL: https://github.com/mautrix/gvoice + +matrix_bridge_mautrix_gvoice_enabled: true + +matrix_bridge_mautrix_gvoice_container_image_self_build: false +matrix_bridge_mautrix_gvoice_container_image_self_build_repo: "https://github.com/mautrix/gvoice.git" +matrix_bridge_mautrix_gvoice_container_image_self_build_branch: "{{ 'main' if matrix_bridge_mautrix_gvoice_version == 'latest' else matrix_bridge_mautrix_gvoice_version }}" + +# renovate: datasource=docker depName=dock.mau.dev/mautrix/gvoice +matrix_bridge_mautrix_gvoice_version: v0.2605.0 + +# See: https://mau.dev/mautrix/gvoice/container_registry +matrix_bridge_mautrix_gvoice_container_image: "{{ matrix_bridge_mautrix_gvoice_container_image_registry_prefix }}mautrix/gvoice:{{ matrix_bridge_mautrix_gvoice_version }}" +matrix_bridge_mautrix_gvoice_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_gvoice_container_image_self_build else matrix_bridge_mautrix_gvoice_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_gvoice_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_gvoice_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_gvoice_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bridge_mautrix_gvoice_base_path: "{{ matrix_base_data_path }}/mautrix-gvoice" +matrix_bridge_mautrix_gvoice_config_path: "{{ matrix_bridge_mautrix_gvoice_base_path }}/config" +matrix_bridge_mautrix_gvoice_data_path: "{{ matrix_bridge_mautrix_gvoice_base_path }}/data" +matrix_bridge_mautrix_gvoice_container_src_files_path: "{{ matrix_bridge_mautrix_gvoice_base_path }}/docker-src" + +matrix_bridge_mautrix_gvoice_homeserver_address: "" +# Whether asynchronous uploads via MSC2246 should be enabled for media. +# Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). +matrix_bridge_mautrix_gvoice_homeserver_async_media: false +matrix_bridge_mautrix_gvoice_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_mautrix_gvoice_appservice_address: "http://matrix-mautrix-gvoice:8080" + +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_gvoice_bridge_public_address`). +matrix_bridge_mautrix_gvoice_scheme: https + +# The public base URL at which this bridge's HTTP API is reachable from outside (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_gvoice_bridge_public_address: "{{ (matrix_bridge_mautrix_gvoice_scheme + '://' + matrix_bridge_mautrix_gvoice_exposure_hostname + matrix_bridge_mautrix_gvoice_exposure_path_prefix) if matrix_bridge_mautrix_gvoice_exposure_enabled else '' }}" + +matrix_bridge_mautrix_gvoice_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_gvoice_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" + +matrix_bridge_mautrix_gvoice_backfill_enabled: true +matrix_bridge_mautrix_gvoice_backfill_max_initial_messages: 50 +matrix_bridge_mautrix_gvoice_backfill_max_catchup_messages: 500 +matrix_bridge_mautrix_gvoice_backfill_unread_hours_threshold: 720 +matrix_bridge_mautrix_gvoice_backfill_threads_max_initial_messages: 50 + +matrix_bridge_mautrix_gvoice_command_prefix: "!gv" + +matrix_bridge_mautrix_gvoice_container_network: "" + +matrix_bridge_mautrix_gvoice_container_additional_networks: "{{ matrix_bridge_mautrix_gvoice_container_additional_networks_auto + matrix_bridge_mautrix_gvoice_container_additional_networks_custom }}" +matrix_bridge_mautrix_gvoice_container_additional_networks_auto: [] +matrix_bridge_mautrix_gvoice_container_additional_networks_custom: [] + +# matrix_bridge_mautrix_gvoice_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# See `../templates/labels.j2` for details. +# +# To inject your own other container labels, see `matrix_bridge_mautrix_gvoice_container_labels_additional_labels`. +matrix_bridge_mautrix_gvoice_container_labels_traefik_enabled: true +matrix_bridge_mautrix_gvoice_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_gvoice_container_network }}" +matrix_bridge_mautrix_gvoice_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_gvoice_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-gvoice' HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_gvoice_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_gvoice_exposure_enabled }}" +matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_gvoice_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_gvoice_exposure_path_prefix }}`)" +matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_gvoice_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_gvoice_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_gvoice_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# See `../templates/labels.j2` for details. +# +# Example: +# matrix_bridge_mautrix_gvoice_container_labels_additional_labels: | +# my.label=1 +# another.label="here" +matrix_bridge_mautrix_gvoice_container_labels_additional_labels: '' + +# A list of extra arguments to pass to the container +matrix_bridge_mautrix_gvoice_container_extra_arguments: [] + +# List of systemd services that matrix-mautrix-gvoice.service depends on. +matrix_bridge_mautrix_gvoice_systemd_required_services_list: "{{ matrix_bridge_mautrix_gvoice_systemd_required_services_list_default + matrix_bridge_mautrix_gvoice_systemd_required_services_list_auto + matrix_bridge_mautrix_gvoice_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_gvoice_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_gvoice_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_gvoice_systemd_required_services_list_custom: [] + +# List of systemd services that matrix-mautrix-gvoice.service wants +matrix_bridge_mautrix_gvoice_systemd_wanted_services_list: [] + +matrix_bridge_mautrix_gvoice_appservice_token: '' +matrix_bridge_mautrix_gvoice_homeserver_token: '' + +matrix_bridge_mautrix_gvoice_appservice_bot_username: gvoicebot + +# Minimum severity of journal log messages. +# Valid values: fatal, error, warn, info, debug, trace +matrix_bridge_mautrix_gvoice_logging_level: 'warn' + +# Whether or not created rooms should have federation enabled. +# If false, created portal rooms will never be federated. +matrix_bridge_mautrix_gvoice_federate_rooms: true + +# Controls whether mautrix-gvoice' HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_gvoice_exposure_enabled: false +matrix_bridge_mautrix_gvoice_exposure_hostname: '' +matrix_bridge_mautrix_gvoice_exposure_path_prefix: '' + +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_bridge_mautrix_gvoice_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_mautrix_gvoice_database_*` variables +matrix_bridge_mautrix_gvoice_database_engine: 'sqlite' + +matrix_bridge_mautrix_gvoice_sqlite_database_path_local: "{{ matrix_bridge_mautrix_gvoice_data_path }}/mautrix-gvoice.db" +matrix_bridge_mautrix_gvoice_sqlite_database_path_in_container: "/data/mautrix-gvoice.db" + +matrix_bridge_mautrix_gvoice_database_username: 'matrix_mautrix_gvoice' +matrix_bridge_mautrix_gvoice_database_password: 'some-password' +matrix_bridge_mautrix_gvoice_database_hostname: '' +matrix_bridge_mautrix_gvoice_database_port: 5432 +matrix_bridge_mautrix_gvoice_database_name: 'matrix_mautrix_gvoice' +matrix_bridge_mautrix_gvoice_database_sslmode: disable + +matrix_bridge_mautrix_gvoice_database_connection_string: 'postgresql://{{ matrix_bridge_mautrix_gvoice_database_username }}:{{ matrix_bridge_mautrix_gvoice_database_password }}@{{ matrix_bridge_mautrix_gvoice_database_hostname }}:{{ matrix_bridge_mautrix_gvoice_database_port }}/{{ matrix_bridge_mautrix_gvoice_database_name }}?sslmode={{ matrix_bridge_mautrix_gvoice_database_sslmode }}' + +matrix_bridge_mautrix_gvoice_appservice_database_type: "{{ { + 'sqlite': 'sqlite3', + 'postgres': 'postgres', +}[matrix_bridge_mautrix_gvoice_database_engine] }}" + +matrix_bridge_mautrix_gvoice_appservice_database_uri: "{{ { + 'sqlite': matrix_bridge_mautrix_gvoice_sqlite_database_path_in_container, + 'postgres': matrix_bridge_mautrix_gvoice_database_connection_string, +}[matrix_bridge_mautrix_gvoice_database_engine] }}" + +matrix_bridge_mautrix_gvoice_double_puppet_secrets: "{{ matrix_bridge_mautrix_gvoice_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_gvoice_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_gvoice_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_gvoice_double_puppet_secrets_custom: {} + +# Enable End-to-bridge encryption +matrix_bridge_mautrix_gvoice_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_gvoice_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_gvoice_bridge_encryption_require: false +matrix_bridge_mautrix_gvoice_bridge_encryption_appservice: false +matrix_bridge_mautrix_gvoice_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_mautrix_gvoice_bridge_encryption_allow }}" +matrix_bridge_mautrix_gvoice_bridge_encryption_pickle_key: mautrix.bridge.e2ee + +matrix_bridge_mautrix_gvoice_network_displayname_template: "{% raw %}{{ or .Contact.Name .Name }}{% endraw %}" +matrix_bridge_mautrix_gvoice_appservice_username_template: "{% raw %}gvoice_{{.}}{% endraw %}" + +matrix_bridge_mautrix_gvoice_public_media_signing_key: '' + +# Shared secret for authentication of provisioning API requests. +# If set to "disable", the provisioning API will be disabled. +matrix_bridge_mautrix_gvoice_provisioning_shared_secret: disable + +matrix_bridge_mautrix_gvoice_bridge_personal_filtering_spaces: true + +matrix_bridge_mautrix_gvoice_bridge_permissions: | + {{ + {'*': 'relay', matrix_bridge_mautrix_gvoice_homeserver_domain: 'user'} + | combine({matrix_admin: 'admin'} if matrix_admin else {}) + }} + +# Default mautrix-gvoice configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_gvoice_configuration_extension_yaml`) +# or completely replace this variable with your own template. +matrix_bridge_mautrix_gvoice_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" + +matrix_bridge_mautrix_gvoice_configuration_extension_yaml: | + # Your custom YAML configuration goes here. + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_gvoice_configuration_yaml`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by + # completely redefining `matrix_bridge_mautrix_gvoice_configuration_yaml`. + +matrix_bridge_mautrix_gvoice_configuration_extension: "{{ matrix_bridge_mautrix_gvoice_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_gvoice_configuration_extension_yaml | from_yaml is mapping else {} }}" + +# Holds the final configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_gvoice_configuration_yaml`. +matrix_bridge_mautrix_gvoice_configuration: "{{ matrix_bridge_mautrix_gvoice_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_gvoice_configuration_extension, recursive=True) }}" + +matrix_bridge_mautrix_gvoice_registration_yaml: | + id: gvoice + url: {{ matrix_bridge_mautrix_gvoice_appservice_address }} + as_token: "{{ matrix_bridge_mautrix_gvoice_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_gvoice_homeserver_token }}" + # See https://github.com/mautrix/signal/issues/43 + sender_localpart: _bot_{{ matrix_bridge_mautrix_gvoice_appservice_bot_username }} + rate_limited: false + namespaces: + users: + - regex: '^@gvoice_.+:{{ matrix_bridge_mautrix_gvoice_homeserver_domain | regex_escape }}$' + exclusive: true + - exclusive: true + regex: '^@{{ matrix_bridge_mautrix_gvoice_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_gvoice_homeserver_domain | regex_escape }}$' + de.sorunome.msc2409.push_ephemeral: true + receive_ephemeral: true + io.element.msc4190: {{ matrix_bridge_mautrix_gvoice_msc4190_enabled | to_json }} + +matrix_bridge_mautrix_gvoice_registration: "{{ matrix_bridge_mautrix_gvoice_registration_yaml | from_yaml }}" + +# matrix_bridge_mautrix_gvoice_restart_necessary controls whether the service +# will be restarted (when true) or merely started (when false) by the +# systemd service manager role (when conditional restart is enabled). +# +# This value is automatically computed during installation based on whether +# any configuration files, the systemd service file, or the container image changed. +# The default of `false` means "no restart needed", appropriate when the role's +# installation tasks haven't run (e.g., due to --tags skipping them). +matrix_bridge_mautrix_gvoice_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/converge.yml new file mode 100644 index 000000000..23e268686 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-gvoice Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-gvoice Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-gvoice is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-gvoice systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-gvoice.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/molecule.yml new file mode 100644 index 000000000..3873fb221 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/molecule.yml @@ -0,0 +1,91 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-gvoice-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_gvoice_container_network: mautrix-gvoice-molecule + + # This is the Matrix-side startup boundary. No Google Voice account or + # third-party credentials are supplied or exercised. + matrix_bridge_mautrix_gvoice_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_gvoice_homeserver_domain: molecule.local + + matrix_bridge_mautrix_gvoice_database_engine: postgres + matrix_bridge_mautrix_gvoice_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_gvoice_database_name: molecule_gvoice + matrix_bridge_mautrix_gvoice_database_username: molecule_gvoice + matrix_bridge_mautrix_gvoice_database_password: molecule_pg_password_70df2c + + matrix_bridge_mautrix_gvoice_appservice_token: molecule_gvoice_as_token_29c74a + matrix_bridge_mautrix_gvoice_homeserver_token: molecule_gvoice_hs_token_f48b63 + + # Non-default values prove the role carries configuration through. + matrix_bridge_mautrix_gvoice_appservice_bot_username: molecule-gvoicebot + matrix_bridge_mautrix_gvoice_command_prefix: "!molecule-gvoice" + matrix_bridge_mautrix_gvoice_logging_level: info + matrix_bridge_mautrix_gvoice_federate_rooms: false + matrix_bridge_mautrix_gvoice_bridge_personal_filtering_spaces: false + matrix_bridge_mautrix_gvoice_backfill_enabled: false + matrix_bridge_mautrix_gvoice_backfill_max_initial_messages: 19 + matrix_bridge_mautrix_gvoice_backfill_max_catchup_messages: 31 + matrix_bridge_mautrix_gvoice_backfill_unread_hours_threshold: 67 + matrix_bridge_mautrix_gvoice_backfill_threads_max_initial_messages: 11 + matrix_bridge_mautrix_gvoice_provisioning_shared_secret: molecule_gvoice_provisioning_secret_563ca1 + matrix_bridge_mautrix_gvoice_network_displayname_template: "{% raw %}{{ or .Name .Contact.Name }} (Molecule){% endraw %}" + matrix_bridge_mautrix_gvoice_appservice_username_template: "{% raw %}molecule_gvoice_{{.}}{% endraw %}" + + # Traefik itself is not started; the bridge consumes the public address and + # Docker consumes the rendered labels. + matrix_bridge_mautrix_gvoice_exposure_enabled: true + matrix_bridge_mautrix_gvoice_exposure_hostname: gvoice-api.molecule.local + matrix_bridge_mautrix_gvoice_exposure_path_prefix: /bridges/gvoice-api + matrix_bridge_mautrix_gvoice_scheme: http + matrix_bridge_mautrix_gvoice_container_labels_traefik_entrypoints: web + matrix_bridge_mautrix_gvoice_container_labels_additional_labels: | + molecule.gvoice.coverage=enabled + + matrix_bridge_mautrix_gvoice_base_path: /matrix/mautrix-gvoice + matrix_bridge_mautrix_gvoice_config_path: /matrix/mautrix-gvoice/config + matrix_bridge_mautrix_gvoice_data_path: /matrix/mautrix-gvoice/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/prepare.yml new file mode 100644 index 000000000..7c2b404e0 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/prepare.yml @@ -0,0 +1,85 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-gvoice Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_gvoice_container_network }}" + register: mautrix_gvoice_molecule_network + changed_when: mautrix_gvoice_molecule_network.rc == 0 + failed_when: + - mautrix_gvoice_molecule_network.rc != 0 + - "'already exists' not in mautrix_gvoice_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_gvoice_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_gvoice_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_gvoice_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_gvoice_database_password }}" + + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_gvoice_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_gvoice_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_gvoice_appservice_bot_username }}:{{ matrix_bridge_mautrix_gvoice_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/verify.yml new file mode 100644 index 000000000..b79a61ee0 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/molecule/default/verify.yml @@ -0,0 +1,381 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the bridge accepts role-rendered config and registration, starts without a +# Google account, initializes real Postgres, and exposes its authenticated login API. +- name: Verify mautrix-gvoice + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + mautrix_gvoice_config: "{{ mautrix_gvoice_config_file.content | b64decode | from_yaml }}" + mautrix_gvoice_registration: "{{ mautrix_gvoice_registration_file.content | b64decode | from_yaml }}" + mautrix_gvoice_labels_rendered: "{{ mautrix_gvoice_labels_file.content | b64decode }}" + mautrix_gvoice_expected_public_address: http://gvoice-api.molecule.local/bridges/gvoice-api + gather_facts: false + tasks: + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_gvoice_role_defaults + + - name: Wait for the mautrix-gvoice service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-gvoice.service + register: mautrix_gvoice_service + until: mautrix_gvoice_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_gvoice_service.status.ActiveState == 'active' + - mautrix_gvoice_service.status.NRestarts is defined + - mautrix_gvoice_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-gvoice.service is {{ mautrix_gvoice_service.status.ActiveState | default('unknown') }} + after {{ mautrix_gvoice_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-mautrix-gvoice.service is active and has not restarted" + + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_gvoice_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-gvoice:8080/_matrix/mau/live + register: mautrix_gvoice_live + changed_when: false + until: mautrix_gvoice_live.rc == 0 and mautrix_gvoice_live.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_gvoice_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-gvoice:8080/_matrix/mau/ready + register: mautrix_gvoice_ready + changed_when: false + until: mautrix_gvoice_ready.rc == 0 and mautrix_gvoice_ready.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on the configured appservice port + ansible.builtin.assert: + that: + - mautrix_gvoice_live.rc == 0 + - mautrix_gvoice_live.stdout == 'HTTP_STATUS=200' + - mautrix_gvoice_ready.rc == 0 + - mautrix_gvoice_ready.stdout == 'HTTP_STATUS=200' + fail_msg: >- + Health probes returned live={{ mautrix_gvoice_live.stdout | default('none') }} and + ready={{ mautrix_gvoice_ready.stdout | default('none') }} + success_msg: "The bridge is live and ready on the configured appservice port" + + # This reaches the network connector's login-flow handler but supplies no Google + # credentials and starts no third-party login. + - name: Query the authenticated provisioning login flows + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_gvoice_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --fail-with-body + - --header + - "Authorization: Bearer {{ matrix_bridge_mautrix_gvoice_provisioning_shared_secret }}" + - "http://matrix-mautrix-gvoice:8080/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_gvoice_login_flows + changed_when: false + + - name: Query the provisioning API with an invalid secret + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_gvoice_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - --header + - "Authorization: Bearer definitely-wrong-molecule-secret" + - "http://matrix-mautrix-gvoice:8080/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_gvoice_login_flows_unauthorized + changed_when: false + failed_when: false + + - name: Assert the live provisioning API enforces auth and advertises cookie login + ansible.builtin.assert: + that: + - mautrix_gvoice_login_flows.rc == 0 + - (mautrix_gvoice_login_flows.stdout | from_json).flows is sequence + - (mautrix_gvoice_login_flows.stdout | from_json).flows | length == 1 + - (mautrix_gvoice_login_flows.stdout | from_json)['flows'][0]['id'] == 'cookies' + - mautrix_gvoice_login_flows_unauthorized.rc == 0 + - mautrix_gvoice_login_flows_unauthorized.stdout == 'HTTP_STATUS=401' + fail_msg: "The provisioning API did not enforce its secret or advertise cookie login" + success_msg: "The provisioning API enforces its secret and advertises cookie login" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_gvoice_config_path }}/config.yaml" + register: mautrix_gvoice_config_file + + - name: Assert the rendered configuration carries the appservice identity + ansible.builtin.assert: + that: + - mautrix_gvoice_config.homeserver.address == matrix_bridge_mautrix_gvoice_homeserver_address + - mautrix_gvoice_config.homeserver.domain == matrix_bridge_mautrix_gvoice_homeserver_domain + - mautrix_gvoice_config.appservice.id == 'gvoice' + - mautrix_gvoice_config.appservice.address == 'http://matrix-mautrix-gvoice:8080' + - mautrix_gvoice_config.appservice.public_address == mautrix_gvoice_expected_public_address + - mautrix_gvoice_config.appservice.bot.username == matrix_bridge_mautrix_gvoice_appservice_bot_username + - mautrix_gvoice_config.appservice.as_token == matrix_bridge_mautrix_gvoice_appservice_token + - mautrix_gvoice_config.appservice.hs_token == matrix_bridge_mautrix_gvoice_homeserver_token + - mautrix_gvoice_config.appservice.username_template == matrix_bridge_mautrix_gvoice_appservice_username_template + fail_msg: "The rendered configuration does not carry the scenario's appservice identity" + success_msg: "The rendered configuration carries the scenario's appservice identity" + + - name: Assert the rendered configuration carries non-default bridge behavior + ansible.builtin.assert: + that: + - mautrix_gvoice_config.bridge.command_prefix == matrix_bridge_mautrix_gvoice_command_prefix + - not mautrix_gvoice_config.bridge.personal_filtering_spaces + - not mautrix_gvoice_config.matrix.federate_rooms + - mautrix_gvoice_config.network.displayname_template == matrix_bridge_mautrix_gvoice_network_displayname_template + - mautrix_gvoice_config.provisioning.shared_secret == matrix_bridge_mautrix_gvoice_provisioning_shared_secret + - mautrix_gvoice_config.logging.min_level == matrix_bridge_mautrix_gvoice_logging_level + fail_msg: "The rendered configuration does not carry the scenario's bridge behavior" + success_msg: "The rendered configuration carries the scenario's bridge behavior" + + - name: Assert the rendered configuration carries the non-default backfill policy + ansible.builtin.assert: + that: + - not mautrix_gvoice_config.backfill.enabled + - mautrix_gvoice_config.backfill.max_initial_messages == 19 + - mautrix_gvoice_config.backfill.max_catchup_messages == 31 + - mautrix_gvoice_config.backfill.unread_hours_threshold == 67 + - mautrix_gvoice_config.backfill.threads.max_initial_messages == 11 + fail_msg: "The rendered configuration does not carry the scenario's backfill policy" + success_msg: "The rendered configuration carries the scenario's backfill policy" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - mautrix_gvoice_config.database.type == matrix_bridge_mautrix_gvoice_database_engine + - matrix_bridge_mautrix_gvoice_database_username in mautrix_gvoice_config.database.uri + - matrix_bridge_mautrix_gvoice_database_hostname in mautrix_gvoice_config.database.uri + - matrix_bridge_mautrix_gvoice_database_name in mautrix_gvoice_config.database.uri + fail_msg: >- + database.uri is {{ mautrix_gvoice_config.database.uri | default('unset') }}, which + was not composed from the scenario's connection settings + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_gvoice_config_path }}/registration.yaml" + register: mautrix_gvoice_registration_file + + - name: Assert the registration carries the configured handshake values + ansible.builtin.assert: + that: + - mautrix_gvoice_registration.id == 'gvoice' + - mautrix_gvoice_registration.as_token == matrix_bridge_mautrix_gvoice_appservice_token + - mautrix_gvoice_registration.hs_token == matrix_bridge_mautrix_gvoice_homeserver_token + - mautrix_gvoice_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_gvoice_appservice_bot_username + - mautrix_gvoice_registration.url == 'http://matrix-mautrix-gvoice:8080' + fail_msg: "The registration does not carry the configured handshake values" + success_msg: "The registration carries the configured handshake values" + + - name: Assert the registration namespaces cover only GVoice ghosts and the bridge bot + ansible.builtin.assert: + that: + - mautrix_gvoice_ghost_regex | length > 0 + - mautrix_gvoice_bot_regex | length > 0 + - mautrix_gvoice_ghost_mxid is match(mautrix_gvoice_ghost_regex) + - mautrix_gvoice_wrong_ghost_mxid is not match(mautrix_gvoice_ghost_regex) + - mautrix_gvoice_bot_mxid is match(mautrix_gvoice_bot_regex) + fail_msg: "The registration namespaces do not cover only GVoice ghosts and the bot" + success_msg: "The registration namespaces cover only GVoice ghosts and the bot" + vars: + mautrix_gvoice_user_regexes: "{{ mautrix_gvoice_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_gvoice_ghost_regex: "{{ mautrix_gvoice_user_regexes | select('search', 'gvoice_') | first | default('') }}" + mautrix_gvoice_bot_regex: "{{ mautrix_gvoice_user_regexes | reject('search', 'gvoice_') | first | default('') }}" + mautrix_gvoice_ghost_mxid: "@gvoice_15551234567:{{ matrix_bridge_mautrix_gvoice_homeserver_domain }}" + mautrix_gvoice_wrong_ghost_mxid: "@googlechat_15551234567:{{ matrix_bridge_mautrix_gvoice_homeserver_domain }}" + mautrix_gvoice_bot_mxid: "@{{ matrix_bridge_mautrix_gvoice_appservice_bot_username }}:{{ matrix_bridge_mautrix_gvoice_homeserver_domain }}" + + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_gvoice_database_username }} + - --dbname={{ matrix_bridge_mautrix_gvoice_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: mautrix_gvoice_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - mautrix_gvoice_tables.rc == 0 + - "'version' in mautrix_gvoice_table_names" + - "'portal' in mautrix_gvoice_table_names" + - "'user_login' in mautrix_gvoice_table_names" + - "'message' in mautrix_gvoice_table_names" + - "'gvoice_version' in mautrix_gvoice_table_names" + - "'gvoice_login_prefix' in mautrix_gvoice_table_names" + - mautrix_gvoice_table_names | length >= 19 + fail_msg: >- + The bridge did not migrate its schema into {{ matrix_bridge_mautrix_gvoice_database_name }} + (found {{ mautrix_gvoice_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + mautrix_gvoice_table_names: "{{ mautrix_gvoice_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_gvoice_base_path }}/labels" + register: mautrix_gvoice_labels_file + + - name: Assert the labels route the public endpoint to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_gvoice_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_gvoice_container_network in mautrix_gvoice_labels_rendered" + - "'traefik.http.services.matrix-mautrix-gvoice-exposure.loadbalancer.server.port=8080' in mautrix_gvoice_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-gvoice-exposure.rule=Host(`gvoice-api.molecule.local`) && PathPrefix(`/bridges/gvoice-api`)' in mautrix_gvoice_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-gvoice-exposure-strip-prefix.stripprefix.prefixes=/bridges/gvoice-api' in mautrix_gvoice_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-gvoice-exposure.entrypoints=web' in mautrix_gvoice_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-gvoice-exposure.tls=false' in mautrix_gvoice_labels_rendered" + - "'molecule.gvoice.coverage=enabled' in mautrix_gvoice_labels_rendered" + fail_msg: "The rendered labels do not carry the scenario's exposure configuration" + success_msg: "The rendered labels carry the scenario's exposure configuration" + + - name: Inspect the running bridge container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-gvoice + register: mautrix_gvoice_container_inspect + changed_when: false + + - name: Parse the running bridge container inspection + ansible.builtin.set_fact: + mautrix_gvoice_container: "{{ (mautrix_gvoice_container_inspect.stdout | from_json) | first }}" + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - mautrix_gvoice_container.Config.Image == mautrix_gvoice_expected_image + fail_msg: >- + The running container uses {{ mautrix_gvoice_container.Config.Image }}, expected + {{ mautrix_gvoice_expected_image }} + success_msg: "The running container uses the exact image pinned by the role" + vars: + mautrix_gvoice_expected_image: >- + {{ mautrix_gvoice_role_defaults.matrix_bridge_mautrix_gvoice_container_image_registry_prefix_upstream_default }}mautrix/gvoice:{{ mautrix_gvoice_role_defaults.matrix_bridge_mautrix_gvoice_version }} + + - name: Assert the running container uses the playbook-supplied runtime + ansible.builtin.assert: + that: + - mautrix_gvoice_container.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + - mautrix_gvoice_container.Config.WorkingDir == '/data' + - mautrix_gvoice_container.Config.Cmd == ['/usr/bin/mautrix-gvoice', '-c', '/config/config.yaml', '-r', '/config/registration.yaml', '--no-update'] + - mautrix_gvoice_container.HostConfig.RestartPolicy.Name == 'no' + - mautrix_gvoice_container.HostConfig.AutoRemove + - mautrix_gvoice_container.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container does not use the role's exact identity, command and workdir" + success_msg: "The running container uses the role's exact identity, command and workdir" + + - name: Assert the running container has the intended privilege isolation + ansible.builtin.assert: + that: + - "'ALL' in mautrix_gvoice_container.HostConfig.CapDrop" + - not mautrix_gvoice_container.HostConfig.Privileged + fail_msg: "The running container does not have the intended privilege isolation" + success_msg: "The running container drops all capabilities and is unprivileged" + + - name: Assert the running container carries the role's two bind mounts + ansible.builtin.assert: + that: + - mautrix_gvoice_config_mount | length > 0 + - mautrix_gvoice_config_mount.Source == matrix_bridge_mautrix_gvoice_config_path + - not mautrix_gvoice_config_mount.RW + - mautrix_gvoice_data_mount | length > 0 + - mautrix_gvoice_data_mount.Source == matrix_bridge_mautrix_gvoice_data_path + - mautrix_gvoice_data_mount.RW + - mautrix_gvoice_container.Mounts | length == 2 + fail_msg: "The running container does not carry the role's exact config and data mounts" + success_msg: "The running container carries its read-only config and writable data mounts" + vars: + mautrix_gvoice_config_mount: >- + {{ mautrix_gvoice_container.Mounts + | selectattr('Destination', 'equalto', '/config') + | first | default({}) }} + mautrix_gvoice_data_mount: >- + {{ mautrix_gvoice_container.Mounts + | selectattr('Destination', 'equalto', '/data') + | first | default({}) }} + + - name: Assert the rendered labels are attached to the running container + ansible.builtin.assert: + that: + - mautrix_gvoice_container.Config.Labels['traefik.enable'] == 'true' + - mautrix_gvoice_container.Config.Labels['traefik.docker.network'] == matrix_bridge_mautrix_gvoice_container_network + - mautrix_gvoice_container.Config.Labels['traefik.http.services.matrix-mautrix-gvoice-exposure.loadbalancer.server.port'] == '8080' + - mautrix_gvoice_container.Config.Labels['molecule.gvoice.coverage'] == 'enabled' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The running container carries the labels the role rendered" + + - name: Assert the running container has the exact network and port exposure + ansible.builtin.assert: + that: + - mautrix_gvoice_container.HostConfig.NetworkMode == matrix_bridge_mautrix_gvoice_container_network + - matrix_bridge_mautrix_gvoice_container_network in mautrix_gvoice_container.NetworkSettings.Networks + - mautrix_gvoice_container.NetworkSettings.Networks | length == 1 + - mautrix_gvoice_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: >- + The container has unexpected networks or host ports: + networks={{ mautrix_gvoice_container.NetworkSettings.Networks.keys() | list }}, + ports={{ mautrix_gvoice_container.HostConfig.PortBindings | default({}) }} + success_msg: "The container uses only its dedicated network and publishes no host ports" diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-gvoice/tasks/main.yml new file mode 100644 index 000000000..3074f1375 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/tasks/main.yml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- tags: + - setup-all + - setup-mautrix-gvoice + - install-all + - install-mautrix-gvoice + block: + - when: matrix_bridge_mautrix_gvoice_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" + + - when: matrix_bridge_mautrix_gvoice_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" + +- tags: + - setup-all + - setup-mautrix-gvoice + block: + - when: not matrix_bridge_mautrix_gvoice_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-gvoice/tasks/setup_install.yml new file mode 100644 index 000000000..f16785a55 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/tasks/setup_install.yml @@ -0,0 +1,186 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- ansible.builtin.set_fact: + matrix_bridge_mautrix_gvoice_migration_requires_restart: false + +- when: "matrix_bridge_mautrix_gvoice_database_engine == 'postgres'" + block: + - name: Check if an SQLite database already exists + ansible.builtin.stat: + path: "{{ matrix_bridge_mautrix_gvoice_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_gvoice_sqlite_database_path_local_stat_result + + - when: "matrix_bridge_mautrix_gvoice_sqlite_database_path_local_stat_result.stat.exists | bool" + block: + - ansible.builtin.include_role: + name: galaxy/postgres + tasks_from: migrate_db_to_postgres + vars: + postgres_db_migration_request: + src: "{{ matrix_bridge_mautrix_gvoice_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_gvoice_database_connection_string }}" + caller: "{{ role_path | basename }}" + engine_variable_name: 'matrix_bridge_mautrix_gvoice_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mautrix-gvoice.service'] + pgloader_options: ['--with "quote identifiers"'] + + - ansible.builtin.set_fact: + matrix_bridge_mautrix_gvoice_migration_requires_restart: true + +- name: Ensure Mautrix gvoice paths exists + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + mode: '0750' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - {path: "{{ matrix_bridge_mautrix_gvoice_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_gvoice_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_gvoice_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_gvoice_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_gvoice_container_image_self_build }}"} + when: item.when | bool + +- name: Ensure Mautrix gvoice image is pulled + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_gvoice_container_image }}" + pull: always + when: not matrix_bridge_mautrix_gvoice_container_image_self_build + register: matrix_bridge_mautrix_gvoice_container_image_pull_result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: matrix_bridge_mautrix_gvoice_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix gvoice repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_gvoice_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_gvoice_container_image_self_build | bool" + +- name: Ensure Mautrix gvoice repository is present on self-build + ansible.builtin.git: + repo: "{{ matrix_bridge_mautrix_gvoice_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_mautrix_gvoice_container_src_files_path }}" + version: "{{ matrix_bridge_mautrix_gvoice_container_image_self_build_branch }}" + force: "yes" + become: true + become_user: "{{ matrix_user_name }}" + register: matrix_bridge_mautrix_gvoice_git_pull_results + when: "matrix_bridge_mautrix_gvoice_container_image_self_build | bool" + +- name: Ensure Mautrix gvoice Docker image is built + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_gvoice_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_gvoice_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_gvoice_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_gvoice_container_image_self_build | bool" + register: matrix_bridge_mautrix_gvoice_container_image_build_result + +- name: Check if an old database file exists + ansible.builtin.stat: + path: "{{ matrix_bridge_mautrix_gvoice_base_path }}/mautrix-gvoice.db" + register: matrix_bridge_mautrix_gvoice_stat_database + +- name: Check if an old Matrix state file exists + ansible.builtin.stat: + path: "{{ matrix_bridge_mautrix_gvoice_base_path }}/mx-state.json" + register: matrix_bridge_mautrix_gvoice_stat_mx_state + +- name: (Data relocation) Ensure matrix-mautrix-gvoice.service is stopped + ansible.builtin.service: + name: matrix-mautrix-gvoice + state: stopped + enabled: false + daemon_reload: true + failed_when: false + when: "matrix_bridge_mautrix_gvoice_stat_database.stat.exists" + +- name: (Data relocation) Move mautrix-gvoice database file to ./data directory + ansible.builtin.command: + cmd: "mv {{ matrix_bridge_mautrix_gvoice_base_path }}/mautrix-gvoice.db {{ matrix_bridge_mautrix_gvoice_data_path }}/mautrix-gvoice.db" + creates: "{{ matrix_bridge_mautrix_gvoice_data_path }}/mautrix-gvoice.db" + removes: "{{ matrix_bridge_mautrix_gvoice_base_path }}/mautrix-gvoice.db" + when: "matrix_bridge_mautrix_gvoice_stat_database.stat.exists" + +- name: (Data relocation) Move mautrix-gvoice mx-state file to ./data directory + ansible.builtin.command: + cmd: "mv {{ matrix_bridge_mautrix_gvoice_base_path }}/mx-state.json {{ matrix_bridge_mautrix_gvoice_data_path }}/mx-state.json" + creates: "{{ matrix_bridge_mautrix_gvoice_data_path }}/mx-state.json" + removes: "{{ matrix_bridge_mautrix_gvoice_base_path }}/mx-state.json" + when: "matrix_bridge_mautrix_gvoice_stat_mx_state.stat.exists" + +- name: Ensure mautrix-gvoice config.yaml installed + ansible.builtin.copy: + content: "{{ matrix_bridge_mautrix_gvoice_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_gvoice_config_path }}/config.yaml" + mode: '0644' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bridge_mautrix_gvoice_config_result + +- name: Ensure mautrix-gvoice registration.yaml installed + ansible.builtin.copy: + content: "{{ matrix_bridge_mautrix_gvoice_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_gvoice_config_path }}/registration.yaml" + mode: '0644' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bridge_mautrix_gvoice_registration_result + +- name: Ensure matrix-mautrix-gvoice.service installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-mautrix-gvoice.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-gvoice.service" + mode: '0644' + register: matrix_bridge_mautrix_gvoice_systemd_service_result + +- name: Ensure mautrix-gvoice support files installed + ansible.builtin.template: + src: "{{ role_path }}/templates/{{ item }}.j2" + dest: "{{ matrix_bridge_mautrix_gvoice_base_path }}/{{ item }}" + mode: '0640' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - labels + register: matrix_bridge_mautrix_gvoice_support_files_result + +- name: Ensure matrix-mautrix-gvoice container network is created + when: matrix_bridge_mautrix_gvoice_container_network != 'host' + community.general.docker_network: + enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" + name: "{{ matrix_bridge_mautrix_gvoice_container_network }}" + driver: bridge + driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" + +- name: Determine whether matrix-mautrix-gvoice needs a restart + ansible.builtin.set_fact: + matrix_bridge_mautrix_gvoice_restart_necessary: >- + {{ + matrix_bridge_mautrix_gvoice_migration_requires_restart | default(false) + or matrix_bridge_mautrix_gvoice_config_result.changed | default(false) + or matrix_bridge_mautrix_gvoice_registration_result.changed | default(false) + or matrix_bridge_mautrix_gvoice_support_files_result.changed | default(false) + or matrix_bridge_mautrix_gvoice_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_gvoice_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_gvoice_container_image_build_result.changed | default(false) + }} + +- name: Ensure matrix-mautrix-gvoice.service restarted, if necessary + ansible.builtin.service: + name: "matrix-mautrix-gvoice.service" + state: restarted + daemon_reload: true + when: "matrix_bridge_mautrix_gvoice_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-gvoice/tasks/setup_uninstall.yml new file mode 100644 index 000000000..53680a5c3 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/tasks/setup_uninstall.yml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Check existence of matrix-mautrix-gvoice service + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-gvoice.service" + register: matrix_bridge_mautrix_gvoice_service_stat + +- when: matrix_bridge_mautrix_gvoice_service_stat.stat.exists | bool + block: + - name: Ensure matrix-mautrix-gvoice is stopped + ansible.builtin.service: + name: matrix-mautrix-gvoice + state: stopped + enabled: false + daemon_reload: true + + - name: Ensure matrix-mautrix-gvoice.service doesn't exist + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-gvoice.service" + state: absent diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-gvoice/tasks/validate_config.yml new file mode 100644 index 000000000..9cf028c33 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/tasks/validate_config.yml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: (Deprecation) Catch and report renamed settings + ansible.builtin.fail: + msg: >- + Your configuration contains a variable, which now has a different name. + Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_bridge_mautrix_gvoice_metrics_enabled', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_metrics_proxying_enabled', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_metrics_proxying_hostname', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_metrics_proxying_path_prefix', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_container_labels_metrics_enabled', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_container_labels_metrics_traefik_rule', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_container_labels_metrics_traefik_priority', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_container_labels_metrics_traefik_entrypoints', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_container_labels_metrics_traefik_tls', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_container_labels_metrics_traefik_tls_certResolver', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (mautrix-gvoice does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_gvoice_container_labels_metrics_middleware_basic_auth_users', 'new': ' (mautrix-gvoice does not support metrics)'} + +- name: Fail if required mautrix-gvoice settings not defined + ansible.builtin.fail: + msg: >- + You need to define a required configuration setting (`{{ item.name }}`). + when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" + with_items: + - {'name': 'matrix_bridge_mautrix_gvoice_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_gvoice_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_gvoice_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_gvoice_database_hostname', when: "{{ matrix_bridge_mautrix_gvoice_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_gvoice_container_network', when: true} diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-gvoice/templates/config.yaml.j2 new file mode 100644 index 000000000..dc6f9c24a --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/templates/config.yaml.j2 @@ -0,0 +1,413 @@ +#jinja2: lstrip_blocks: True +# Network-specific config options +network: + # Displayname template for Google Voice contacts. + displayname_template: {{ matrix_bridge_mautrix_gvoice_network_displayname_template | to_json }} + + +# Config options that affect the central bridge module. +bridge: + # The prefix for commands. Only required in non-management rooms. + command_prefix: {{ matrix_bridge_mautrix_gvoice_command_prefix | to_json }} + # Should the bridge create a space for each login containing the rooms that account is in? + personal_filtering_spaces: {{ matrix_bridge_mautrix_gvoice_bridge_personal_filtering_spaces | to_json }} + # Whether the bridge should set names and avatars explicitly for DM portals. + # This is only necessary when using clients that don't support MSC4171. + private_chat_portal_meta: false + # Should events be handled asynchronously within portal rooms? + # If true, events may end up being out of order, but slow events won't block other ones. + async_events: false + # Should every user have their own portals rather than sharing them? + # By default, users who are in the same group on the remote network will be + # in the same Matrix room bridged to that group. If this is set to true, + # every user will get their own Matrix room instead. + split_portals: false + # Should the bridge resend `m.bridge` events to all portals on startup? + resend_bridge_info: false + + # Should leaving Matrix rooms be bridged as leaving groups on the remote network? + bridge_matrix_leave: false + # Should room tags only be synced when creating the portal? Tags mean things like favorite/pin and archive/low priority. + # Tags currently can't be synced back to the remote network, so a continuous sync means tagging from Matrix will be undone. + tag_only_on_create: true + # Should room mute status only be synced when creating the portal? + # Like tags, mutes can't currently be synced back to the remote network. + mute_only_on_create: true + + # What should be done to portal rooms when a user logs out or is logged out? + # Permitted values: + # nothing - Do nothing, let the user stay in the portals + # kick - Remove the user from the portal rooms, but don't delete them + # unbridge - Remove all ghosts in the room and disassociate it from the remote chat + # delete - Remove all ghosts and users from the room (i.e. delete it) + cleanup_on_logout: + # Should cleanup on logout be enabled at all? + enabled: false + # Settings for manual logouts (explicitly initiated by the Matrix user) + manual: + # Action for private portals which will never be shared with other Matrix users. + private: nothing + # Action for portals with a relay user configured. + relayed: nothing + # Action for portals which may be shared, but don't currently have any other Matrix users. + shared_no_users: nothing + # Action for portals which have other logged-in Matrix users. + shared_has_users: nothing + # Settings for credentials being invalidated (initiated by the remote network, possibly through user action). + # Keys have the same meanings as in the manual section. + bad_credentials: + private: nothing + relayed: nothing + shared_no_users: nothing + shared_has_users: nothing + + # Settings for relay mode + relay: + # Whether relay mode should be allowed. If allowed, the set-relay command can be used to turn any + # authenticated user into a relaybot for that chat. + enabled: false + # Should only admins be allowed to set themselves as relay users? + # If true, non-admins can only set users listed in default_relays as relays in a room. + admin_only: true + # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. + default_relays: [] + # The formats to use when sending messages via the relaybot. + # Available variables: + # .Sender.UserID - The Matrix user ID of the sender. + # .Sender.Displayname - The display name of the sender (if set). + # .Sender.RequiresDisambiguation - Whether the sender's name may be confused with the name of another user in the room. + # .Sender.DisambiguatedName - The disambiguated name of the sender. This will be the displayname if set, + # plus the user ID in parentheses if the displayname is not unique. + # If the displayname is not set, this is just the user ID. + # .Message - The `formatted_body` field of the message. + # .Caption - The `formatted_body` field of the message, if it's a caption. Otherwise an empty string. + # .FileName - The name of the file being sent. + message_formats: + m.text: "{% raw %}{{ .Sender.DisambiguatedName }}: {{ .Message }}{% endraw %}" + m.notice: "{% raw %}{{ .Sender.DisambiguatedName }}: {{ .Message }}{% endraw %}" + m.emote: "{% raw %}* {{ .Sender.DisambiguatedName }} {{ .Message }}{% endraw %}" + m.file: "{% raw %}{{ .Sender.DisambiguatedName }} sent a file{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.image: "{% raw %}{{ .Sender.DisambiguatedName }} sent an image{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.audio: "{% raw %}{{ .Sender.DisambiguatedName }} sent an audio file{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.video: "{% raw %}{{ .Sender.DisambiguatedName }} sent a video{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.location: "{% raw %}{{ .Sender.DisambiguatedName }} sent a location{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + # For networks that support per-message displaynames (i.e. Slack and Discord), the template for those names. + # This has all the Sender variables available under message_formats (but without the .Sender prefix). + # Note that you need to manually remove the displayname from message_formats above. + displayname_format: "{% raw %}{{ .DisambiguatedName }}{% endraw %}" + + # Permissions for using the bridge. + # Permitted values: + # relay - Talk through the relaybot (if enabled), no access otherwise + # commands - Access to use commands in the bridge, but not login. + # user - Access to use the bridge with puppeting. + # admin - Full access, user level with some additional administration tools. + # Permitted keys: + # * - All Matrix users + # domain - All users on that homeserver + # mxid - Specific user + permissions: {{ matrix_bridge_mautrix_gvoice_bridge_permissions|to_json }} + +# Config for the bridge's database. +database: + # The database type. "sqlite3-fk-wal" and "postgres" are supported. + type: postgres + # The database URI. + # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. + # https://github.com/mattn/go-sqlite3#connection-string + # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable + # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql + uri: {{ matrix_bridge_mautrix_gvoice_appservice_database_uri|to_json }} + # Maximum number of connections. + max_open_conns: 5 + max_idle_conns: 1 + # Maximum connection idle time and lifetime before they're closed. Disabled if null. + # Parsed with https://pkg.go.dev/time#ParseDuration + max_conn_idle_time: null + max_conn_lifetime: null + +# Homeserver details. +homeserver: + # The address that this appservice can use to connect to the homeserver. + # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, + # but https also works if they run on different machines. + address: {{ matrix_bridge_mautrix_gvoice_homeserver_address | to_json }} + # The domain of the homeserver (also known as server_name, used for MXIDs, etc). + domain: {{ matrix_bridge_mautrix_gvoice_homeserver_domain | to_json }} + + # What software is the homeserver running? + # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. + software: standard + # The URL to push real-time bridge status to. + # If set, the bridge will make POST requests to this URL whenever a user's remote network connection state changes. + # The bridge will use the appservice as_token to authorize requests. + status_endpoint: + # Endpoint for reporting per-message status. + # If set, the bridge will make POST requests to this URL when processing a message from Matrix. + # It will make one request when receiving the message (step BRIDGE), one after decrypting if applicable + # (step DECRYPTED) and one after sending to the remote network (step REMOTE). Errors will also be reported. + # The bridge will use the appservice as_token to authorize requests. + message_send_checkpoint_endpoint: + # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? + async_media: {{ matrix_bridge_mautrix_gvoice_homeserver_async_media | to_json }} + + # Should the bridge use a websocket for connecting to the homeserver? + # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, + # mautrix-asmux (deprecated), and hungryserv (proprietary). + websocket: false + # How often should the websocket be pinged? Pinging will be disabled if this is zero. + ping_interval_seconds: 0 + +# Application service host/registration related details. +# Changing these values requires regeneration of the registration (except when noted otherwise) +appservice: + # The address that the homeserver can use to connect to this appservice. + address: {{ matrix_bridge_mautrix_gvoice_appservice_address }} + # A public address that external services can use to reach this appservice. + # This value doesn't affect the registration file. + public_address: {{ matrix_bridge_mautrix_gvoice_bridge_public_address | to_json }} + + # The hostname and port where this appservice should listen. + # For Docker, you generally have to change the hostname to 0.0.0.0. + hostname: 0.0.0.0 + port: 8080 + + # The unique ID of this appservice. + id: gvoice + # Appservice bot details. + bot: + # Username of the appservice bot. + username: {{ matrix_bridge_mautrix_gvoice_appservice_bot_username|to_json }} + # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty + # to leave display name/avatar as-is. + displayname: Google Voice bridge bot + avatar: mxc://maunium.net/VOPtYGBzHLRfPTEzGgNMpeKo + + # Whether to receive ephemeral events via appservice transactions. + ephemeral_events: true + # Should incoming events be handled asynchronously? + # This may be necessary for large public instances with lots of messages going through. + # However, messages will not be guaranteed to be bridged in the same order they were sent in. + # This value doesn't affect the registration file. + async_transactions: false + + # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. + as_token: {{ matrix_bridge_mautrix_gvoice_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_gvoice_homeserver_token | to_json }} + + # Localpart template of MXIDs for remote users. + # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. + username_template: {{ matrix_bridge_mautrix_gvoice_appservice_username_template | to_json }} + +# Config options that affect the Matrix connector of the bridge. +matrix: + # Whether the bridge should send the message status as a custom com.beeper.message_send_status event. + message_status_events: false + # Whether the bridge should send a read receipt after successfully bridging a message. + delivery_receipts: false + # Whether the bridge should send error notices via m.notice events when a message fails to bridge. + message_error_notices: true + # Whether the bridge should update the m.direct account data event when double puppeting is enabled. + sync_direct_chat_list: false + # Whether created rooms should have federation enabled. If false, created portal rooms + # will never be federated. Changing this option requires recreating rooms. + federate_rooms: {{ matrix_bridge_mautrix_gvoice_federate_rooms | to_json }} + # The threshold as bytes after which the bridge should roundtrip uploads via the disk + # rather than keeping the whole file in memory. + upload_file_threshold: 5242880 + +# Segment-compatible analytics endpoint for tracking some events, like provisioning API login and encryption errors. +analytics: + # API key to send with tracking requests. Tracking is disabled if this is null. + token: null + # Address to send tracking requests to. + url: https://api.segment.io/v1/track + # Optional user ID for tracking events. If null, defaults to using Matrix user ID. + user_id: null + +# Settings for provisioning API +provisioning: + # Prefix for the provisioning API paths. + prefix: /_matrix/provision + # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, + # or if set to "disable", the provisioning API will be disabled. + shared_secret: {{ matrix_bridge_mautrix_gvoice_provisioning_shared_secret | to_json }} + # Whether to allow provisioning API requests to be authed using Matrix access tokens. + # This follows the same rules as double puppeting to determine which server to contact to check the token, + # which means that by default, it only works for users on the same server as the bridge. + allow_matrix_auth: true + # Enable debug API at /debug with provisioning authentication. + debug_endpoints: false + +# Some networks require publicly accessible media download links (e.g. for user avatars when using Discord webhooks). +# These settings control whether the bridge will provide such public media access. +public_media: + # Should public media be enabled at all? + # The public_address field under the appservice section MUST be set when enabling public media. + enabled: false + # A key for signing public media URLs. + # If set to "generate", a random key will be generated. + signing_key: {{ matrix_bridge_mautrix_gvoice_public_media_signing_key | to_json }} + # Number of seconds that public media URLs are valid for. + # If set to 0, URLs will never expire. + expiry: 0 + # Length of hash to use for public media URLs. Must be between 0 and 32. + hash_length: 32 + +# Settings for converting remote media to custom mxc:// URIs instead of reuploading. +# More details can be found at https://docs.mau.fi/bridges/go/discord/direct-media.html +direct_media: + # Should custom mxc:// URIs be used instead of reuploading media? + enabled: false + # The server name to use for the custom mxc:// URIs. + # This server name will effectively be a real Matrix server, it just won't implement anything other than media. + # You must either set up .well-known delegation from this domain to the bridge, or proxy the domain directly to the bridge. + server_name: media.example.com + # Optionally a custom .well-known response. This defaults to `server_name:443` + well_known_response: + # Optionally specify a custom prefix for the media ID part of the MXC URI. + media_id_prefix: + # If the remote network supports media downloads over HTTP, then the bridge will use MSC3860/MSC3916 + # media download redirects if the requester supports it. Optionally, you can force redirects + # and not allow proxying at all by setting this to false. + # This option does nothing if the remote network does not support media downloads over HTTP. + allow_proxy: true + # Matrix server signing key to make the federation tester pass, same format as synapse's .signing.key file. + # This key is also used to sign the mxc:// URIs to ensure only the bridge can generate them. + server_key: "" + +# Settings for backfilling messages. +# Note that the exact way settings are applied depends on the network connector. +# See https://docs.mau.fi/bridges/general/backfill.html for more details. +backfill: + # Whether to do backfilling at all. + enabled: {{ matrix_bridge_mautrix_gvoice_backfill_enabled | to_json }} + # Maximum number of messages to backfill in empty rooms. + max_initial_messages: {{ matrix_bridge_mautrix_gvoice_backfill_max_initial_messages | to_json }} + # Maximum number of missed messages to backfill after bridge restarts. + max_catchup_messages: {{ matrix_bridge_mautrix_gvoice_backfill_max_catchup_messages | to_json }} + # If a backfilled chat is older than this number of hours, + # mark it as read even if it's unread on the remote network. + unread_hours_threshold: {{ matrix_bridge_mautrix_gvoice_backfill_unread_hours_threshold | to_json }} + # Settings for backfilling threads within other backfills. + threads: + # Maximum number of messages to backfill in a new thread. + max_initial_messages: {{ matrix_bridge_mautrix_gvoice_backfill_threads_max_initial_messages | to_json }} + # Settings for the backwards backfill queue. This only applies when connecting to + # Beeper as standard Matrix servers don't support inserting messages into history. + queue: + # Should the backfill queue be enabled? + enabled: false + # Number of messages to backfill in one batch. + batch_size: 100 + # Delay between batches in seconds. + batch_delay: 20 + # Maximum number of batches to backfill per portal. + # If set to -1, all available messages will be backfilled. + max_batches: -1 + # Optional network-specific overrides for max batches. + # Interpretation of this field depends on the network connector. + max_batches_override: {} + +# Settings for enabling double puppeting +double_puppet: + # Servers to always allow double puppeting from. + # This is only for other servers and should NOT contain the server the bridge is on. + servers: {} + # Whether to allow client API URL discovery for other servers. When using this option, + # users on other servers can use double puppeting even if their server URLs aren't + # explicitly added to the servers map above. + allow_discovery: false + # Shared secrets for automatic double puppeting. + # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. + secrets: {{ matrix_bridge_mautrix_gvoice_double_puppet_secrets | to_json }} + +# End-to-bridge encryption support options. +# +# See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. +encryption: + # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. + allow: {{ matrix_bridge_mautrix_gvoice_bridge_encryption_allow | to_json }} + # Whether to force-enable encryption in all bridged rooms. + default: {{ matrix_bridge_mautrix_gvoice_bridge_encryption_default | to_json }} + # Whether to require all messages to be encrypted and drop any unencrypted messages. + require: {{ matrix_bridge_mautrix_gvoice_bridge_encryption_require | to_json }} + # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. + # This option is not yet compatible with standard Matrix servers like Synapse and should not be used. + appservice: {{ matrix_bridge_mautrix_gvoice_bridge_encryption_appservice | to_json }} + # Whether to use MSC4190 instead of appservice login to create the bridge bot device. + # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. + # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). + # Changing this option requires updating the appservice registration file. + msc4190: {{ matrix_bridge_mautrix_gvoice_msc4190_enabled | to_json }} + # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) + # Requires msc4190 to replace keys on reset + self_sign: {{ matrix_bridge_mautrix_gvoice_self_sign_enabled | to_json }} + # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. + # You must use a client that supports requesting keys from other users to use this feature. + allow_key_sharing: {{ matrix_bridge_mautrix_gvoice_bridge_encryption_key_sharing_allow | to_json }} + # Pickle key for encrypting encryption keys in the bridge database. + # If set to generate, a random key will be generated. + pickle_key: {{ matrix_bridge_mautrix_gvoice_bridge_encryption_pickle_key | to_json }} + # Options for deleting megolm sessions from the bridge. + delete_keys: + # Beeper-specific: delete outbound sessions when hungryserv confirms + # that the user has uploaded the key to key backup. + delete_outbound_on_ack: false + # Don't store outbound sessions in the inbound table. + dont_store_outbound: false + # Ratchet megolm sessions forward after decrypting messages. + ratchet_on_decrypt: false + # Delete fully used keys (index >= max_messages) after decrypting messages. + delete_fully_used_on_decrypt: false + # Delete previous megolm sessions from same device when receiving a new one. + delete_prev_on_new_session: false + # Delete megolm sessions received from a device when the device is deleted. + delete_on_device_delete: false + # Periodically delete megolm sessions when 2x max_age has passed since receiving the session. + periodically_delete_expired: false + # Delete inbound megolm sessions that don't have the received_at field used for + # automatic ratcheting and expired session deletion. This is meant as a migration + # to delete old keys prior to the bridge update. + delete_outdated_inbound: false + # What level of device verification should be required from users? + # + # Valid levels: + # unverified - Send keys to all device in the room. + # cross-signed-untrusted - Require valid cross-signing, but trust all cross-signing keys. + # cross-signed-tofu - Require valid cross-signing, trust cross-signing keys on first use (and reject changes). + # cross-signed-verified - Require valid cross-signing, plus a valid user signature from the bridge bot. + # Note that creating user signatures from the bridge bot is not currently possible. + # verified - Require manual per-device verification + # (currently only possible by modifying the `trust` column in the `crypto_device` database table). + verification_levels: + # Minimum level for which the bridge should send keys to when bridging messages from the remote network to Matrix. + receive: unverified + # Minimum level that the bridge should accept for incoming Matrix messages. + send: unverified + # Minimum level that the bridge should require for accepting key requests. + share: cross-signed-tofu + # Options for Megolm room key rotation. These options allow you to configure the m.room.encryption event content. + # See https://spec.matrix.org/v1.10/client-server-api/#mroomencryption for more information about that event. + rotation: + # Enable custom Megolm room key rotation settings. Note that these + # settings will only apply to rooms created after this option is set. + enable_custom: false + # The maximum number of milliseconds a session should be used + # before changing it. The Matrix spec recommends 604800000 (a week) + # as the default. + milliseconds: 604800000 + # The maximum number of messages that should be sent with a given a + # session before changing it. The Matrix spec recommends 100 as the + # default. + messages: 100 + # Disable rotating keys when a user's devices change? + # You should not enable this option unless you understand all the implications. + disable_device_change_key_rotation: false + +# Logging config. See https://github.com/tulir/zeroconfig for details. +logging: + min_level: {{ matrix_bridge_mautrix_gvoice_logging_level }} + writers: + - type: stdout + format: pretty diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/templates/config.yaml.j2.license b/roles/custom/matrix-bridge-mautrix-gvoice/templates/config.yaml.j2.license new file mode 100644 index 000000000..bd628c0b6 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/templates/config.yaml.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-gvoice/templates/labels.j2 new file mode 100644 index 000000000..f7392abb7 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/templates/labels.j2 @@ -0,0 +1,51 @@ +{# +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later +#} + +{% if matrix_bridge_mautrix_gvoice_container_labels_traefik_enabled %} +traefik.enable=true + +{% if matrix_bridge_mautrix_gvoice_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_gvoice_container_labels_traefik_docker_network }} +{% endif %} + +{% if matrix_bridge_mautrix_gvoice_container_labels_exposure_enabled %} +############################################################ +# # +# Bridge API exposure # +# # +############################################################ + +traefik.http.services.matrix-mautrix-gvoice-exposure.loadbalancer.server.port=8080 + +traefik.http.middlewares.matrix-mautrix-gvoice-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_gvoice_exposure_path_prefix }} +traefik.http.routers.matrix-mautrix-gvoice-exposure.middlewares=matrix-mautrix-gvoice-exposure-strip-prefix + +traefik.http.routers.matrix-mautrix-gvoice-exposure.rule={{ matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_rule }} + +{% if matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-gvoice-exposure.priority={{ matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-mautrix-gvoice-exposure.service=matrix-mautrix-gvoice-exposure +traefik.http.routers.matrix-mautrix-gvoice-exposure.entrypoints={{ matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_entrypoints }} + +traefik.http.routers.matrix-mautrix-gvoice-exposure.tls={{ matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-mautrix-gvoice-exposure.tls.certResolver={{ matrix_bridge_mautrix_gvoice_container_labels_exposure_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Bridge API exposure # +# # +############################################################ +{% endif %} + + +{% endif %} + +{{ matrix_bridge_mautrix_gvoice_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk-node.service.j2 b/roles/custom/matrix-bridge-mautrix-gvoice/templates/systemd/matrix-mautrix-gvoice.service.j2 similarity index 51% rename from roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk-node.service.j2 rename to roles/custom/matrix-bridge-mautrix-gvoice/templates/systemd/matrix-mautrix-gvoice.service.j2 index 266f3cdaa..127e2adbf 100644 --- a/roles/custom/matrix-bridge-appservice-kakaotalk/templates/systemd/matrix-appservice-kakaotalk-node.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-gvoice/templates/systemd/matrix-mautrix-gvoice.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] -Description=appservice-kakaotalk-node bridge helper -{% for service in matrix_appservice_kakaotalk_node_systemd_required_services_list %} +Description=Matrix Mautrix gvoice bridge +{% for service in matrix_bridge_mautrix_gvoice_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_appservice_kakaotalk_node_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_gvoice_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -13,34 +13,39 @@ DefaultDependencies=no [Service] Type=simple Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-appservice-kakaotalk-node 2>/dev/null || true' -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-appservice-kakaotalk-node 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-mautrix-gvoice 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-mautrix-gvoice 2>/dev/null || true' ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --rm \ - --name=matrix-appservice-kakaotalk-node \ + --name=matrix-mautrix-gvoice \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_appservice_kakaotalk_container_network }} \ - --mount type=bind,src={{ matrix_appservice_kakaotalk_config_path }}/node-config.json,dst=/config.json,ro \ - {% for arg in matrix_appservice_kakaotalk_node_container_extra_arguments %} + --network={{ matrix_bridge_mautrix_gvoice_container_network }} \ + --mount type=bind,src={{ matrix_bridge_mautrix_gvoice_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_gvoice_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_gvoice_base_path }}/labels \ + --workdir=/data \ + {% for arg in matrix_bridge_mautrix_gvoice_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_appservice_kakaotalk_node_container_image }} \ - node src/main.js --config /config.json + {{ matrix_bridge_mautrix_gvoice_container_image }} \ + /usr/bin/mautrix-gvoice -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_appservice_kakaotalk_container_additional_networks %} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-appservice-kakaotalk-node +{% if matrix_bridge_mautrix_gvoice_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_gvoice_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-gvoice {% endfor %} +{% endif %} -ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-appservice-kakaotalk-node +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-gvoice -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-appservice-kakaotalk-node 2>/dev/null || true' -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-appservice-kakaotalk-node 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-mautrix-gvoice 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-mautrix-gvoice 2>/dev/null || true' Restart=always RestartSec=30 -SyslogIdentifier=matrix-appservice-kakaotalk-node +SyslogIdentifier=matrix-mautrix-gvoice [Install] WantedBy=multi-user.target diff --git a/roles/custom/matrix-bridge-mautrix-gvoice/templates/systemd/matrix-mautrix-gvoice.service.j2.license b/roles/custom/matrix-bridge-mautrix-gvoice/templates/systemd/matrix-mautrix-gvoice.service.j2.license new file mode 100644 index 000000000..bd628c0b6 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-gvoice/templates/systemd/matrix-mautrix-gvoice.service.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-linkedin/defaults/main.yml new file mode 100644 index 000000000..b57fca2fa --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/defaults/main.yml @@ -0,0 +1,228 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# mautrix-linkedin is a Matrix <-> LinkedIn bridge +# Project source code URL: https://github.com/mautrix/linkedin + +matrix_bridge_mautrix_linkedin_enabled: true + +matrix_bridge_mautrix_linkedin_container_image_self_build: false +matrix_bridge_mautrix_linkedin_container_image_self_build_repo: "https://github.com/mautrix/linkedin.git" +matrix_bridge_mautrix_linkedin_container_image_self_build_branch: "{{ 'main' if matrix_bridge_mautrix_linkedin_version == 'latest' else matrix_bridge_mautrix_linkedin_version }}" + +# renovate: datasource=docker depName=dock.mau.dev/mautrix/linkedin +matrix_bridge_mautrix_linkedin_version: v0.2608.0 + +# See: https://mau.dev/mautrix/linkedin/container_registry +matrix_bridge_mautrix_linkedin_container_image: "{{ matrix_bridge_mautrix_linkedin_container_image_registry_prefix }}mautrix/linkedin:{{ matrix_bridge_mautrix_linkedin_version }}" +matrix_bridge_mautrix_linkedin_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_linkedin_container_image_self_build else matrix_bridge_mautrix_linkedin_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_linkedin_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_linkedin_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_linkedin_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bridge_mautrix_linkedin_base_path: "{{ matrix_base_data_path }}/mautrix-linkedin" +matrix_bridge_mautrix_linkedin_config_path: "{{ matrix_bridge_mautrix_linkedin_base_path }}/config" +matrix_bridge_mautrix_linkedin_data_path: "{{ matrix_bridge_mautrix_linkedin_base_path }}/data" +matrix_bridge_mautrix_linkedin_container_src_files_path: "{{ matrix_bridge_mautrix_linkedin_base_path }}/docker-src" + +matrix_bridge_mautrix_linkedin_homeserver_address: "" +# Whether asynchronous uploads via MSC2246 should be enabled for media. +# Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). +matrix_bridge_mautrix_linkedin_homeserver_async_media: false +matrix_bridge_mautrix_linkedin_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_mautrix_linkedin_appservice_address: "http://matrix-mautrix-linkedin:8080" + +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_linkedin_bridge_public_address`). +matrix_bridge_mautrix_linkedin_scheme: https + +# The public base URL at which this bridge's HTTP API is reachable from outside (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_linkedin_bridge_public_address: "{{ (matrix_bridge_mautrix_linkedin_scheme + '://' + matrix_bridge_mautrix_linkedin_exposure_hostname + matrix_bridge_mautrix_linkedin_exposure_path_prefix) if matrix_bridge_mautrix_linkedin_exposure_enabled else '' }}" + +matrix_bridge_mautrix_linkedin_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_linkedin_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" + +matrix_bridge_mautrix_linkedin_backfill_enabled: true +matrix_bridge_mautrix_linkedin_backfill_max_initial_messages: 50 +matrix_bridge_mautrix_linkedin_backfill_max_catchup_messages: 500 +matrix_bridge_mautrix_linkedin_backfill_unread_hours_threshold: 720 +matrix_bridge_mautrix_linkedin_backfill_threads_max_initial_messages: 50 + +matrix_bridge_mautrix_linkedin_command_prefix: "!li" + +matrix_bridge_mautrix_linkedin_container_network: "" + +matrix_bridge_mautrix_linkedin_container_additional_networks: "{{ matrix_bridge_mautrix_linkedin_container_additional_networks_auto + matrix_bridge_mautrix_linkedin_container_additional_networks_custom }}" +matrix_bridge_mautrix_linkedin_container_additional_networks_auto: [] +matrix_bridge_mautrix_linkedin_container_additional_networks_custom: [] + +# matrix_bridge_mautrix_linkedin_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# See `../templates/labels.j2` for details. +# +# To inject your own other container labels, see `matrix_bridge_mautrix_linkedin_container_labels_additional_labels`. +matrix_bridge_mautrix_linkedin_container_labels_traefik_enabled: true +matrix_bridge_mautrix_linkedin_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_linkedin_container_network }}" +matrix_bridge_mautrix_linkedin_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_linkedin_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-linkedin' HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_linkedin_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_linkedin_exposure_enabled }}" +matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_linkedin_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_linkedin_exposure_path_prefix }}`)" +matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_linkedin_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_linkedin_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_linkedin_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# See `../templates/labels.j2` for details. +# +# Example: +# matrix_bridge_mautrix_linkedin_container_labels_additional_labels: | +# my.label=1 +# another.label="here" +matrix_bridge_mautrix_linkedin_container_labels_additional_labels: '' + +# A list of extra arguments to pass to the container +matrix_bridge_mautrix_linkedin_container_extra_arguments: [] + +# List of systemd services that matrix-mautrix-linkedin.service depends on. +matrix_bridge_mautrix_linkedin_systemd_required_services_list: "{{ matrix_bridge_mautrix_linkedin_systemd_required_services_list_default + matrix_bridge_mautrix_linkedin_systemd_required_services_list_auto + matrix_bridge_mautrix_linkedin_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_linkedin_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_linkedin_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_linkedin_systemd_required_services_list_custom: [] + +# List of systemd services that matrix-mautrix-linkedin.service wants +matrix_bridge_mautrix_linkedin_systemd_wanted_services_list: [] + +matrix_bridge_mautrix_linkedin_appservice_token: '' +matrix_bridge_mautrix_linkedin_homeserver_token: '' + +matrix_bridge_mautrix_linkedin_appservice_bot_username: linkedinbot + +# Minimum severity of journal log messages. +# Valid values: fatal, error, warn, info, debug, trace +matrix_bridge_mautrix_linkedin_logging_level: 'warn' + +# Whether or not created rooms should have federation enabled. +# If false, created portal rooms will never be federated. +matrix_bridge_mautrix_linkedin_federate_rooms: true + +# Controls whether mautrix-linkedin' HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_linkedin_exposure_enabled: false +matrix_bridge_mautrix_linkedin_exposure_hostname: '' +matrix_bridge_mautrix_linkedin_exposure_path_prefix: '' + +# Database-related configuration fields. +# +# To use SQLite, stick to these defaults. +# +# To use Postgres: +# - change the engine (`matrix_bridge_mautrix_linkedin_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_mautrix_linkedin_database_*` variables +matrix_bridge_mautrix_linkedin_database_engine: 'sqlite' + +matrix_bridge_mautrix_linkedin_sqlite_database_path_local: "{{ matrix_bridge_mautrix_linkedin_data_path }}/mautrix-linkedin.db" +matrix_bridge_mautrix_linkedin_sqlite_database_path_in_container: "/data/mautrix-linkedin.db" + +matrix_bridge_mautrix_linkedin_database_username: 'matrix_mautrix_linkedin' +matrix_bridge_mautrix_linkedin_database_password: 'some-password' +matrix_bridge_mautrix_linkedin_database_hostname: '' +matrix_bridge_mautrix_linkedin_database_port: 5432 +matrix_bridge_mautrix_linkedin_database_name: 'matrix_mautrix_linkedin' +matrix_bridge_mautrix_linkedin_database_sslmode: disable + +matrix_bridge_mautrix_linkedin_database_connection_string: 'postgresql://{{ matrix_bridge_mautrix_linkedin_database_username }}:{{ matrix_bridge_mautrix_linkedin_database_password }}@{{ matrix_bridge_mautrix_linkedin_database_hostname }}:{{ matrix_bridge_mautrix_linkedin_database_port }}/{{ matrix_bridge_mautrix_linkedin_database_name }}?sslmode={{ matrix_bridge_mautrix_linkedin_database_sslmode }}' + +matrix_bridge_mautrix_linkedin_appservice_database_type: "{{ { + 'sqlite': 'sqlite3', + 'postgres': 'postgres', +}[matrix_bridge_mautrix_linkedin_database_engine] }}" + +matrix_bridge_mautrix_linkedin_appservice_database_uri: "{{ { + 'sqlite': matrix_bridge_mautrix_linkedin_sqlite_database_path_in_container, + 'postgres': matrix_bridge_mautrix_linkedin_database_connection_string, +}[matrix_bridge_mautrix_linkedin_database_engine] }}" + +matrix_bridge_mautrix_linkedin_double_puppet_secrets: "{{ matrix_bridge_mautrix_linkedin_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_linkedin_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_linkedin_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_linkedin_double_puppet_secrets_custom: {} + +# Enable End-to-bridge encryption +matrix_bridge_mautrix_linkedin_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_linkedin_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_linkedin_bridge_encryption_require: false +matrix_bridge_mautrix_linkedin_bridge_encryption_appservice: false +matrix_bridge_mautrix_linkedin_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_mautrix_linkedin_bridge_encryption_allow }}" +matrix_bridge_mautrix_linkedin_bridge_encryption_pickle_key: mautrix.bridge.e2ee + +matrix_bridge_mautrix_linkedin_network_displayname_template: "{% raw %}{{ with .Organization }}{{ . }}{{ else }}{{ .FirstName }} {{ .LastName }}{{ end }}{% endraw %} (LinkedIn)" +matrix_bridge_mautrix_linkedin_appservice_username_template: "{% raw %}linkedin_{{.}}{% endraw %}" + +matrix_bridge_mautrix_linkedin_public_media_signing_key: '' + +# Shared secret for authentication of provisioning API requests. +# If set to "disable", the provisioning API will be disabled. +matrix_bridge_mautrix_linkedin_provisioning_shared_secret: disable + +matrix_bridge_mautrix_linkedin_bridge_personal_filtering_spaces: true + +matrix_bridge_mautrix_linkedin_bridge_permissions: | + {{ + {'*': 'relay', matrix_bridge_mautrix_linkedin_homeserver_domain: 'user'} + | combine({matrix_admin: 'admin'} if matrix_admin else {}) + }} + +# Default mautrix-linkedin configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_linkedin_configuration_extension_yaml`) +# or completely replace this variable with your own template. +matrix_bridge_mautrix_linkedin_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" + +matrix_bridge_mautrix_linkedin_configuration_extension_yaml: | + # Your custom YAML configuration goes here. + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_linkedin_configuration_yaml`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by + # completely redefining `matrix_bridge_mautrix_linkedin_configuration_yaml`. + +matrix_bridge_mautrix_linkedin_configuration_extension: "{{ matrix_bridge_mautrix_linkedin_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_linkedin_configuration_extension_yaml | from_yaml is mapping else {} }}" + +# Holds the final configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_linkedin_configuration_yaml`. +matrix_bridge_mautrix_linkedin_configuration: "{{ matrix_bridge_mautrix_linkedin_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_linkedin_configuration_extension, recursive=True) }}" + +matrix_bridge_mautrix_linkedin_registration_yaml: | + id: linkedin + url: {{ matrix_bridge_mautrix_linkedin_appservice_address }} + as_token: "{{ matrix_bridge_mautrix_linkedin_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_linkedin_homeserver_token }}" + # See https://github.com/mautrix/signal/issues/43 + sender_localpart: _bot_{{ matrix_bridge_mautrix_linkedin_appservice_bot_username }} + rate_limited: false + namespaces: + users: + - regex: '^@linkedin_.+:{{ matrix_bridge_mautrix_linkedin_homeserver_domain | regex_escape }}$' + exclusive: true + - exclusive: true + regex: '^@{{ matrix_bridge_mautrix_linkedin_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_linkedin_homeserver_domain | regex_escape }}$' + de.sorunome.msc2409.push_ephemeral: true + receive_ephemeral: true + io.element.msc4190: {{ matrix_bridge_mautrix_linkedin_msc4190_enabled | to_json }} + +matrix_bridge_mautrix_linkedin_registration: "{{ matrix_bridge_mautrix_linkedin_registration_yaml | from_yaml }}" + +# matrix_bridge_mautrix_linkedin_restart_necessary controls whether the service +# will be restarted (when true) or merely started (when false) by the +# systemd service manager role (when conditional restart is enabled). +# +# This value is automatically computed during installation based on whether +# any configuration files, the systemd service file, or the container image changed. +# The default of `false` means "no restart needed", appropriate when the role's +# installation tasks haven't run (e.g., due to --tags skipping them). +matrix_bridge_mautrix_linkedin_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/converge.yml new file mode 100644 index 000000000..20863bb58 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-linkedin Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-linkedin Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-linkedin is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-linkedin systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-linkedin.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/molecule.yml new file mode 100644 index 000000000..30987f05f --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/molecule.yml @@ -0,0 +1,102 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-linkedin-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_linkedin_container_network: mautrix-linkedin-molecule + + # The stub prepare.yml starts is not a real homeserver, and the scenario carries + # no LinkedIn credentials. Logged out is the intended test boundary. + matrix_bridge_mautrix_linkedin_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_linkedin_homeserver_domain: molecule.local + matrix_bridge_mautrix_linkedin_homeserver_async_media: true + + # Postgres is the normal deployment path. Non-default names make the resulting + # schema evidence that the role composed and supplied this connection. + matrix_bridge_mautrix_linkedin_database_engine: postgres + matrix_bridge_mautrix_linkedin_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_linkedin_database_name: molecule_linkedin + matrix_bridge_mautrix_linkedin_database_username: molecule_linkedin + matrix_bridge_mautrix_linkedin_database_password: molecule_pg_password_c1482d + + # Test-only fixtures which must reach both config.yaml and registration.yaml. + matrix_bridge_mautrix_linkedin_appservice_token: molecule_linkedin_as_token_b738e1 + matrix_bridge_mautrix_linkedin_homeserver_token: molecule_linkedin_hs_token_13df62 + + # All differ from role defaults, allowing parsed checks to prove role rendering. + matrix_bridge_mautrix_linkedin_appservice_bot_username: molecule-linkedinbot + matrix_bridge_mautrix_linkedin_network_displayname_template: "{% raw %}{{ .FirstName }} / {{ .LastName }} (Molecule){% endraw %}" + matrix_bridge_mautrix_linkedin_appservice_username_template: "{% raw %}molecule_linkedin_{{.}}{% endraw %}" + matrix_bridge_mautrix_linkedin_command_prefix: "!molecule-linkedin" + matrix_bridge_mautrix_linkedin_bridge_permissions: + "*": commands + molecule.local: admin + matrix_bridge_mautrix_linkedin_bridge_personal_filtering_spaces: false + matrix_bridge_mautrix_linkedin_federate_rooms: false + matrix_bridge_mautrix_linkedin_backfill_enabled: false + matrix_bridge_mautrix_linkedin_backfill_max_initial_messages: 17 + matrix_bridge_mautrix_linkedin_backfill_max_catchup_messages: 29 + matrix_bridge_mautrix_linkedin_backfill_unread_hours_threshold: 61 + matrix_bridge_mautrix_linkedin_backfill_threads_max_initial_messages: 7 + matrix_bridge_mautrix_linkedin_provisioning_shared_secret: molecule_provisioning_secret_03d1f8 + matrix_bridge_mautrix_linkedin_public_media_signing_key: molecule_public_media_key_76e2c4 + matrix_bridge_mautrix_linkedin_double_puppet_secrets_custom: + molecule.remote: molecule_double_puppet_secret_8bac31 + matrix_bridge_mautrix_linkedin_logging_level: info + + # Traefik is not started. These values exercise both the public address the bridge + # consumes and the exposure labels Docker consumes. + matrix_bridge_mautrix_linkedin_exposure_enabled: true + matrix_bridge_mautrix_linkedin_exposure_hostname: linkedin-api.molecule.local + matrix_bridge_mautrix_linkedin_exposure_path_prefix: /bridges/linkedin-api + matrix_bridge_mautrix_linkedin_scheme: http + matrix_bridge_mautrix_linkedin_container_labels_traefik_entrypoints: web + matrix_bridge_mautrix_linkedin_container_labels_additional_labels: | + molecule.linkedin.coverage=enabled + + # verify.yml is a separate play, where role defaults are out of scope. + matrix_bridge_mautrix_linkedin_base_path: /matrix/mautrix-linkedin + matrix_bridge_mautrix_linkedin_config_path: /matrix/mautrix-linkedin/config + matrix_bridge_mautrix_linkedin_data_path: /matrix/mautrix-linkedin/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/prepare.yml new file mode 100644 index 000000000..26a5efc9f --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/prepare.yml @@ -0,0 +1,87 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-linkedin Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role creates this during converge, but both dependencies attach to it first. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_linkedin_container_network }}" + register: mautrix_linkedin_molecule_network + changed_when: mautrix_linkedin_molecule_network.rc == 0 + failed_when: + - mautrix_linkedin_molecule_network.rc != 0 + - "'already exists' not in mautrix_linkedin_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_linkedin_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_linkedin_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_linkedin_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_linkedin_database_password }}" + + # The logged-out bridge still checks its appservice bot identity during startup. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_linkedin_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_linkedin_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_linkedin_appservice_bot_username }}:{{ matrix_bridge_mautrix_linkedin_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/verify.yml new file mode 100644 index 000000000..44511c0ed --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/molecule/default/verify.yml @@ -0,0 +1,397 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the logged-out bridge starts, accepts the role-rendered configuration and +# registration, migrates real Postgres, and opens its appservice and provisioning +# APIs. LinkedIn credentials are deliberately outside the scenario boundary. +- name: Verify mautrix-linkedin + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + mautrix_linkedin_config: "{{ mautrix_linkedin_config_file.content | b64decode | from_yaml }}" + mautrix_linkedin_registration: "{{ mautrix_linkedin_registration_file.content | b64decode | from_yaml }}" + mautrix_linkedin_labels_rendered: "{{ mautrix_linkedin_labels_file.content | b64decode }}" + mautrix_linkedin_expected_public_address: http://linkedin-api.molecule.local/bridges/linkedin-api + gather_facts: false + + tasks: + # A Renovate bump changes this source of truth and therefore the image expectation. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_linkedin_role_defaults + + - name: Wait for the mautrix-linkedin service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-linkedin.service + register: mautrix_linkedin_service + until: mautrix_linkedin_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes ActiveState insufficient for detecting a crash loop. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_linkedin_service.status.ActiveState == 'active' + - mautrix_linkedin_service.status.NRestarts is defined + - mautrix_linkedin_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-linkedin.service is + {{ mautrix_linkedin_service.status.ActiveState | default('unknown') }} after + {{ mautrix_linkedin_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-mautrix-linkedin.service is active and has not restarted" + + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_linkedin_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-linkedin:8080/_matrix/mau/live + register: mautrix_linkedin_live + changed_when: false + until: mautrix_linkedin_live.rc == 0 and mautrix_linkedin_live.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_linkedin_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-linkedin:8080/_matrix/mau/ready + register: mautrix_linkedin_ready + changed_when: false + until: mautrix_linkedin_ready.rc == 0 and mautrix_linkedin_ready.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on the configured appservice port + ansible.builtin.assert: + that: + - mautrix_linkedin_live.rc == 0 + - mautrix_linkedin_live.stdout == 'HTTP_STATUS=200' + - mautrix_linkedin_ready.rc == 0 + - mautrix_linkedin_ready.stdout == 'HTTP_STATUS=200' + fail_msg: >- + Health probes returned live={{ mautrix_linkedin_live.stdout | default('none') }} + (rc={{ mautrix_linkedin_live.rc | default('?') }}) and + ready={{ mautrix_linkedin_ready.stdout | default('none') }} + (rc={{ mautrix_linkedin_ready.rc | default('?') }}) + success_msg: "The bridge is live and ready on the configured appservice port" + + # This exercises the provisioning middleware and LinkedIn connector without logging in. + - name: Query the authenticated provisioning login flows + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_linkedin_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --fail-with-body + - --header + - "Authorization: Bearer {{ matrix_bridge_mautrix_linkedin_provisioning_shared_secret }}" + - "http://matrix-mautrix-linkedin:8080/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_linkedin_login_flows + changed_when: false + + - name: Query the provisioning API with an invalid secret + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_linkedin_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - --header + - "Authorization: Bearer definitely-wrong-molecule-secret" + - "http://matrix-mautrix-linkedin:8080/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_linkedin_login_flows_unauthorized + changed_when: false + failed_when: false + + - name: Assert the live provisioning API enforces auth and advertises login flows + ansible.builtin.assert: + that: + - mautrix_linkedin_login_flows.rc == 0 + - (mautrix_linkedin_login_flows.stdout | from_json).flows is sequence + - (mautrix_linkedin_login_flows.stdout | from_json).flows | length > 0 + - mautrix_linkedin_login_flows_unauthorized.rc == 0 + - mautrix_linkedin_login_flows_unauthorized.stdout == 'HTTP_STATUS=401' + fail_msg: "The provisioning API did not enforce its secret or return LinkedIn login flows" + success_msg: "The provisioning API enforces its secret and returns LinkedIn login flows" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_linkedin_config_path }}/config.yaml" + register: mautrix_linkedin_config_file + + - name: Assert the rendered configuration carries the appservice identity + ansible.builtin.assert: + that: + - mautrix_linkedin_config.homeserver.address == matrix_bridge_mautrix_linkedin_homeserver_address + - mautrix_linkedin_config.homeserver.domain == matrix_bridge_mautrix_linkedin_homeserver_domain + - mautrix_linkedin_config.homeserver.async_media + - mautrix_linkedin_config.appservice.id == 'linkedin' + - mautrix_linkedin_config.appservice.address == 'http://matrix-mautrix-linkedin:8080' + - mautrix_linkedin_config.appservice.public_address == mautrix_linkedin_expected_public_address + - mautrix_linkedin_config.appservice.bot.username == matrix_bridge_mautrix_linkedin_appservice_bot_username + - mautrix_linkedin_config.appservice.as_token == matrix_bridge_mautrix_linkedin_appservice_token + - mautrix_linkedin_config.appservice.hs_token == matrix_bridge_mautrix_linkedin_homeserver_token + - mautrix_linkedin_config.appservice.username_template == matrix_bridge_mautrix_linkedin_appservice_username_template + fail_msg: "The rendered configuration does not carry the scenario's appservice identity" + success_msg: "The rendered configuration carries the scenario's appservice identity" + + - name: Assert the rendered configuration carries non-default LinkedIn behavior + ansible.builtin.assert: + that: + - mautrix_linkedin_config.network.displayname_template == matrix_bridge_mautrix_linkedin_network_displayname_template + - mautrix_linkedin_config.bridge.command_prefix == matrix_bridge_mautrix_linkedin_command_prefix + - mautrix_linkedin_config.bridge.permissions['*'] == 'commands' + - mautrix_linkedin_config.bridge.permissions[matrix_bridge_mautrix_linkedin_homeserver_domain] == 'admin' + - not mautrix_linkedin_config.bridge.personal_filtering_spaces + - not mautrix_linkedin_config.matrix.federate_rooms + - mautrix_linkedin_config.logging.min_level == matrix_bridge_mautrix_linkedin_logging_level + fail_msg: "The rendered configuration does not carry the scenario's LinkedIn behavior" + success_msg: "The rendered configuration carries the scenario's LinkedIn behavior" + + - name: Assert the rendered configuration carries integration secrets + ansible.builtin.assert: + that: + - mautrix_linkedin_config.provisioning.shared_secret == matrix_bridge_mautrix_linkedin_provisioning_shared_secret + - mautrix_linkedin_config.public_media.signing_key == matrix_bridge_mautrix_linkedin_public_media_signing_key + - mautrix_linkedin_config.double_puppet.secrets['molecule.remote'] == 'molecule_double_puppet_secret_8bac31' + fail_msg: "The rendered configuration does not carry the scenario's integration secrets" + success_msg: "The rendered configuration carries the scenario's integration secrets" + + - name: Assert the rendered configuration carries the non-default backfill policy + ansible.builtin.assert: + that: + - not mautrix_linkedin_config.backfill.enabled + - mautrix_linkedin_config.backfill.max_initial_messages == 17 + - mautrix_linkedin_config.backfill.max_catchup_messages == 29 + - mautrix_linkedin_config.backfill.unread_hours_threshold == 61 + - mautrix_linkedin_config.backfill.threads.max_initial_messages == 7 + fail_msg: "The rendered configuration does not carry the scenario's backfill policy" + success_msg: "The rendered configuration carries the scenario's backfill policy" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - mautrix_linkedin_config.database.type == matrix_bridge_mautrix_linkedin_database_engine + - matrix_bridge_mautrix_linkedin_database_username in mautrix_linkedin_config.database.uri + - matrix_bridge_mautrix_linkedin_database_hostname in mautrix_linkedin_config.database.uri + - matrix_bridge_mautrix_linkedin_database_name in mautrix_linkedin_config.database.uri + fail_msg: >- + database.uri is {{ mautrix_linkedin_config.database.uri | default('unset') }}, which + was not composed from the scenario's connection settings + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_linkedin_config_path }}/registration.yaml" + register: mautrix_linkedin_registration_file + + - name: Assert the registration carries the configured handshake values + ansible.builtin.assert: + that: + - mautrix_linkedin_registration.id == 'linkedin' + - mautrix_linkedin_registration.as_token == matrix_bridge_mautrix_linkedin_appservice_token + - mautrix_linkedin_registration.hs_token == matrix_bridge_mautrix_linkedin_homeserver_token + - mautrix_linkedin_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_linkedin_appservice_bot_username + - mautrix_linkedin_registration.url == 'http://matrix-mautrix-linkedin:8080' + - mautrix_linkedin_registration['io.element.msc4190'] == false + fail_msg: "The registration does not carry the configured handshake values" + success_msg: "The registration carries the configured handshake values" + + - name: Assert the registration namespaces cover only LinkedIn ghosts and the bridge bot + ansible.builtin.assert: + that: + - mautrix_linkedin_ghost_regex | length > 0 + - mautrix_linkedin_bot_regex | length > 0 + - mautrix_linkedin_ghost_mxid is match(mautrix_linkedin_ghost_regex) + - mautrix_linkedin_wrong_ghost_mxid is not match(mautrix_linkedin_ghost_regex) + - mautrix_linkedin_bot_mxid is match(mautrix_linkedin_bot_regex) + fail_msg: "The registration namespaces do not cover only LinkedIn ghosts and the bot" + success_msg: "The registration namespaces cover only LinkedIn ghosts and the bot" + vars: + mautrix_linkedin_user_regexes: "{{ mautrix_linkedin_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_linkedin_ghost_regex: "{{ mautrix_linkedin_user_regexes | select('search', 'linkedin_') | first | default('') }}" + mautrix_linkedin_bot_regex: "{{ mautrix_linkedin_user_regexes | reject('search', 'linkedin_') | first | default('') }}" + mautrix_linkedin_ghost_mxid: "@linkedin_123456:{{ matrix_bridge_mautrix_linkedin_homeserver_domain }}" + mautrix_linkedin_wrong_ghost_mxid: "@twitter_123456:{{ matrix_bridge_mautrix_linkedin_homeserver_domain }}" + mautrix_linkedin_bot_mxid: "@{{ matrix_bridge_mautrix_linkedin_appservice_bot_username }}:{{ matrix_bridge_mautrix_linkedin_homeserver_domain }}" + + # Tables can appear only after hostname resolution, authentication, and real migrations. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_linkedin_database_username }} + - --dbname={{ matrix_bridge_mautrix_linkedin_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: mautrix_linkedin_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - mautrix_linkedin_tables.rc == 0 + - "'version' in mautrix_linkedin_table_names" + - "'portal' in mautrix_linkedin_table_names" + - "'user_login' in mautrix_linkedin_table_names" + - "'message' in mautrix_linkedin_table_names" + - mautrix_linkedin_table_names | length > 10 + fail_msg: >- + The bridge did not migrate its schema into {{ matrix_bridge_mautrix_linkedin_database_name }} + (found {{ mautrix_linkedin_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + mautrix_linkedin_table_names: "{{ mautrix_linkedin_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_linkedin_base_path }}/labels" + register: mautrix_linkedin_labels_file + + - name: Assert the labels route the public endpoint to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_linkedin_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_linkedin_container_network in mautrix_linkedin_labels_rendered" + - "'traefik.http.services.matrix-mautrix-linkedin-exposure.loadbalancer.server.port=8080' in mautrix_linkedin_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-linkedin-exposure.rule=Host(`linkedin-api.molecule.local`) && PathPrefix(`/bridges/linkedin-api`)' in mautrix_linkedin_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-linkedin-exposure-strip-prefix.stripprefix.prefixes=/bridges/linkedin-api' in mautrix_linkedin_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-linkedin-exposure.entrypoints=web' in mautrix_linkedin_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-linkedin-exposure.tls=false' in mautrix_linkedin_labels_rendered" + - "'molecule.linkedin.coverage=enabled' in mautrix_linkedin_labels_rendered" + fail_msg: "The rendered labels do not carry the scenario's exposure configuration" + success_msg: "The rendered labels carry the scenario's exposure configuration" + + - name: Inspect the running bridge container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-linkedin + register: mautrix_linkedin_container_inspect + changed_when: false + + - name: Parse the running bridge container inspection + ansible.builtin.set_fact: + mautrix_linkedin_container: "{{ (mautrix_linkedin_container_inspect.stdout | from_json) | first }}" + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - mautrix_linkedin_container.Config.Image == mautrix_linkedin_expected_image + fail_msg: >- + The running container uses {{ mautrix_linkedin_container.Config.Image }}, expected + {{ mautrix_linkedin_expected_image }} + success_msg: "The running container uses the exact image pinned by the role" + vars: + mautrix_linkedin_expected_image: >- + {{ mautrix_linkedin_role_defaults.matrix_bridge_mautrix_linkedin_container_image_registry_prefix_upstream_default }}mautrix/linkedin:{{ mautrix_linkedin_role_defaults.matrix_bridge_mautrix_linkedin_version }} + + - name: Assert the running container uses the playbook-supplied runtime + ansible.builtin.assert: + that: + - mautrix_linkedin_container.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + - mautrix_linkedin_container.Config.WorkingDir == '/data' + - mautrix_linkedin_container.Config.Cmd == ['/usr/bin/mautrix-linkedin', '-c', '/config/config.yaml', '-r', '/config/registration.yaml', '--no-update'] + - mautrix_linkedin_container.HostConfig.RestartPolicy.Name == 'no' + - mautrix_linkedin_container.HostConfig.AutoRemove + - mautrix_linkedin_container.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container does not use the role's exact identity and command" + success_msg: "The running container uses the role's exact identity and command" + + - name: Assert the running container has the intended privilege isolation + ansible.builtin.assert: + that: + - "'ALL' in mautrix_linkedin_container.HostConfig.CapDrop" + - not mautrix_linkedin_container.HostConfig.Privileged + fail_msg: "The running container does not have the intended privilege isolation" + success_msg: "The running container drops all capabilities and is unprivileged" + + - name: Assert the running container carries the role's exact bind mounts + ansible.builtin.assert: + that: + - mautrix_linkedin_config_mount | length > 0 + - mautrix_linkedin_config_mount.Source == matrix_bridge_mautrix_linkedin_config_path + - not mautrix_linkedin_config_mount.RW + - mautrix_linkedin_data_mount | length > 0 + - mautrix_linkedin_data_mount.Source == matrix_bridge_mautrix_linkedin_data_path + - mautrix_linkedin_data_mount.RW + - mautrix_linkedin_container.Mounts | length == 2 + fail_msg: "The running container does not carry the role's exact config and data mounts" + success_msg: "The running container carries read-only config and writable data mounts" + vars: + mautrix_linkedin_config_mount: >- + {{ mautrix_linkedin_container.Mounts + | selectattr('Destination', 'equalto', '/config') + | first | default({}) }} + mautrix_linkedin_data_mount: >- + {{ mautrix_linkedin_container.Mounts + | selectattr('Destination', 'equalto', '/data') + | first | default({}) }} + + - name: Assert the rendered labels are attached to the running container + ansible.builtin.assert: + that: + - mautrix_linkedin_container.Config.Labels['traefik.enable'] == 'true' + - mautrix_linkedin_container.Config.Labels['traefik.docker.network'] == matrix_bridge_mautrix_linkedin_container_network + - mautrix_linkedin_container.Config.Labels['traefik.http.services.matrix-mautrix-linkedin-exposure.loadbalancer.server.port'] == '8080' + - mautrix_linkedin_container.Config.Labels['molecule.linkedin.coverage'] == 'enabled' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The running container carries the labels the role rendered" + + - name: Assert the running container has the exact network and port exposure + ansible.builtin.assert: + that: + - mautrix_linkedin_container.HostConfig.NetworkMode == matrix_bridge_mautrix_linkedin_container_network + - matrix_bridge_mautrix_linkedin_container_network in mautrix_linkedin_container.NetworkSettings.Networks + - mautrix_linkedin_container.NetworkSettings.Networks | length == 1 + - mautrix_linkedin_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: >- + The container has unexpected networks or host ports: + networks={{ mautrix_linkedin_container.NetworkSettings.Networks.keys() | list }}, + ports={{ mautrix_linkedin_container.HostConfig.PortBindings | default({}) }} + success_msg: "The container uses only its dedicated network and publishes no host ports" diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-linkedin/tasks/main.yml new file mode 100644 index 000000000..707bc5a39 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/tasks/main.yml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- tags: + - setup-all + - setup-mautrix-linkedin + - install-all + - install-mautrix-linkedin + block: + - when: matrix_bridge_mautrix_linkedin_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" + + - when: matrix_bridge_mautrix_linkedin_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" + +- tags: + - setup-all + - setup-mautrix-linkedin + block: + - when: not matrix_bridge_mautrix_linkedin_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-linkedin/tasks/setup_install.yml new file mode 100644 index 000000000..32957b60c --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/tasks/setup_install.yml @@ -0,0 +1,186 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- ansible.builtin.set_fact: + matrix_bridge_mautrix_linkedin_migration_requires_restart: false + +- when: "matrix_bridge_mautrix_linkedin_database_engine == 'postgres'" + block: + - name: Check if an SQLite database already exists + ansible.builtin.stat: + path: "{{ matrix_bridge_mautrix_linkedin_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_linkedin_sqlite_database_path_local_stat_result + + - when: "matrix_bridge_mautrix_linkedin_sqlite_database_path_local_stat_result.stat.exists | bool" + block: + - ansible.builtin.include_role: + name: galaxy/postgres + tasks_from: migrate_db_to_postgres + vars: + postgres_db_migration_request: + src: "{{ matrix_bridge_mautrix_linkedin_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_linkedin_database_connection_string }}" + caller: "{{ role_path | basename }}" + engine_variable_name: 'matrix_bridge_mautrix_linkedin_database_engine' + engine_old: 'sqlite' + systemd_services_to_stop: ['matrix-mautrix-linkedin.service'] + pgloader_options: ['--with "quote identifiers"'] + + - ansible.builtin.set_fact: + matrix_bridge_mautrix_linkedin_migration_requires_restart: true + +- name: Ensure Mautrix linkedin paths exists + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + mode: '0750' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - {path: "{{ matrix_bridge_mautrix_linkedin_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_linkedin_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_linkedin_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_linkedin_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_linkedin_container_image_self_build }}"} + when: item.when | bool + +- name: Ensure Mautrix linkedin image is pulled + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_linkedin_container_image }}" + pull: always + when: not matrix_bridge_mautrix_linkedin_container_image_self_build + register: matrix_bridge_mautrix_linkedin_container_image_pull_result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: matrix_bridge_mautrix_linkedin_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix linkedin repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_linkedin_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_linkedin_container_image_self_build | bool" + +- name: Ensure Mautrix linkedin repository is present on self-build + ansible.builtin.git: + repo: "{{ matrix_bridge_mautrix_linkedin_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_mautrix_linkedin_container_src_files_path }}" + version: "{{ matrix_bridge_mautrix_linkedin_container_image_self_build_branch }}" + force: "yes" + become: true + become_user: "{{ matrix_user_name }}" + register: matrix_bridge_mautrix_linkedin_git_pull_results + when: "matrix_bridge_mautrix_linkedin_container_image_self_build | bool" + +- name: Ensure Mautrix linkedin Docker image is built + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_linkedin_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_linkedin_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_linkedin_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_linkedin_container_image_self_build | bool" + register: matrix_bridge_mautrix_linkedin_container_image_build_result + +- name: Check if an old database file exists + ansible.builtin.stat: + path: "{{ matrix_bridge_mautrix_linkedin_base_path }}/mautrix-linkedin.db" + register: matrix_bridge_mautrix_linkedin_stat_database + +- name: Check if an old Matrix state file exists + ansible.builtin.stat: + path: "{{ matrix_bridge_mautrix_linkedin_base_path }}/mx-state.json" + register: matrix_bridge_mautrix_linkedin_stat_mx_state + +- name: (Data relocation) Ensure matrix-mautrix-linkedin.service is stopped + ansible.builtin.service: + name: matrix-mautrix-linkedin + state: stopped + enabled: false + daemon_reload: true + failed_when: false + when: "matrix_bridge_mautrix_linkedin_stat_database.stat.exists" + +- name: (Data relocation) Move mautrix-linkedin database file to ./data directory + ansible.builtin.command: + cmd: "mv {{ matrix_bridge_mautrix_linkedin_base_path }}/mautrix-linkedin.db {{ matrix_bridge_mautrix_linkedin_data_path }}/mautrix-linkedin.db" + creates: "{{ matrix_bridge_mautrix_linkedin_data_path }}/mautrix-linkedin.db" + removes: "{{ matrix_bridge_mautrix_linkedin_base_path }}/mautrix-linkedin.db" + when: "matrix_bridge_mautrix_linkedin_stat_database.stat.exists" + +- name: (Data relocation) Move mautrix-linkedin mx-state file to ./data directory + ansible.builtin.command: + cmd: "mv {{ matrix_bridge_mautrix_linkedin_base_path }}/mx-state.json {{ matrix_bridge_mautrix_linkedin_data_path }}/mx-state.json" + creates: "{{ matrix_bridge_mautrix_linkedin_data_path }}/mx-state.json" + removes: "{{ matrix_bridge_mautrix_linkedin_base_path }}/mx-state.json" + when: "matrix_bridge_mautrix_linkedin_stat_mx_state.stat.exists" + +- name: Ensure mautrix-linkedin config.yaml installed + ansible.builtin.copy: + content: "{{ matrix_bridge_mautrix_linkedin_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_linkedin_config_path }}/config.yaml" + mode: '0644' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bridge_mautrix_linkedin_config_result + +- name: Ensure mautrix-linkedin registration.yaml installed + ansible.builtin.copy: + content: "{{ matrix_bridge_mautrix_linkedin_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_linkedin_config_path }}/registration.yaml" + mode: '0644' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bridge_mautrix_linkedin_registration_result + +- name: Ensure matrix-mautrix-linkedin.service installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-mautrix-linkedin.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-linkedin.service" + mode: '0644' + register: matrix_bridge_mautrix_linkedin_systemd_service_result + +- name: Ensure mautrix-linkedin support files installed + ansible.builtin.template: + src: "{{ role_path }}/templates/{{ item }}.j2" + dest: "{{ matrix_bridge_mautrix_linkedin_base_path }}/{{ item }}" + mode: '0640' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - labels + register: matrix_bridge_mautrix_linkedin_support_files_result + +- name: Ensure matrix-mautrix-linkedin container network is created + when: matrix_bridge_mautrix_linkedin_container_network != 'host' + community.general.docker_network: + enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" + name: "{{ matrix_bridge_mautrix_linkedin_container_network }}" + driver: bridge + driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" + +- name: Determine whether matrix-mautrix-linkedin needs a restart + ansible.builtin.set_fact: + matrix_bridge_mautrix_linkedin_restart_necessary: >- + {{ + matrix_bridge_mautrix_linkedin_migration_requires_restart | default(false) + or matrix_bridge_mautrix_linkedin_config_result.changed | default(false) + or matrix_bridge_mautrix_linkedin_registration_result.changed | default(false) + or matrix_bridge_mautrix_linkedin_support_files_result.changed | default(false) + or matrix_bridge_mautrix_linkedin_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_linkedin_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_linkedin_container_image_build_result.changed | default(false) + }} + +- name: Ensure matrix-mautrix-linkedin.service restarted, if necessary + ansible.builtin.service: + name: "matrix-mautrix-linkedin.service" + state: restarted + daemon_reload: true + when: "matrix_bridge_mautrix_linkedin_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-linkedin/tasks/setup_uninstall.yml new file mode 100644 index 000000000..88344e968 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/tasks/setup_uninstall.yml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Check existence of matrix-mautrix-linkedin service + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-linkedin.service" + register: matrix_bridge_mautrix_linkedin_service_stat + +- when: matrix_bridge_mautrix_linkedin_service_stat.stat.exists | bool + block: + - name: Ensure matrix-mautrix-linkedin is stopped + ansible.builtin.service: + name: matrix-mautrix-linkedin + state: stopped + enabled: false + daemon_reload: true + + - name: Ensure matrix-mautrix-linkedin.service doesn't exist + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-linkedin.service" + state: absent diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-linkedin/tasks/validate_config.yml new file mode 100644 index 000000000..b8ee4c774 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/tasks/validate_config.yml @@ -0,0 +1,49 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: (Deprecation) Catch and report renamed settings + ansible.builtin.fail: + msg: >- + Your configuration contains a variable, which now has a different name. + Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_bridge_mautrix_linkedin_metrics_enabled', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_metrics_proxying_enabled', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_metrics_proxying_hostname', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_metrics_proxying_path_prefix', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_container_labels_metrics_enabled', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_container_labels_metrics_traefik_rule', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_container_labels_metrics_traefik_priority', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_container_labels_metrics_traefik_entrypoints', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_container_labels_metrics_traefik_tls', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_container_labels_metrics_traefik_tls_certResolver', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (mautrix-linkedin does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_linkedin_container_labels_metrics_middleware_basic_auth_users', 'new': ' (mautrix-linkedin does not support metrics)'} + +- name: Fail if required mautrix-linkedin settings not defined + ansible.builtin.fail: + msg: >- + You need to define a required configuration setting (`{{ item.name }}`). + when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" + with_items: + - {'name': 'matrix_bridge_mautrix_linkedin_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_linkedin_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_linkedin_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_linkedin_database_hostname', when: "{{ matrix_bridge_mautrix_linkedin_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_linkedin_container_network', when: true} + +- name: Fail if the deprecated beeper-linkedin bridge is also enabled + ansible.builtin.fail: + msg: >- + Both `matrix_bridge_beeper_linkedin_enabled` and `matrix_bridge_mautrix_linkedin_enabled` are set. + Both register `@linkedinbot` and the `@linkedin_*` user range as exclusive appservice namespaces, + so running them together makes homeserver event routing for those users ambiguous and lets one + bridge act as the other's puppets. Disable the deprecated beeper-linkedin bridge + (`matrix_bridge_beeper_linkedin_enabled: false`) and re-run the playbook so its uninstall removes + the old registration, then enable this bridge. + when: "matrix_bridge_beeper_linkedin_enabled | default(false) | bool" diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-linkedin/templates/config.yaml.j2 new file mode 100644 index 000000000..c45f7c561 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/templates/config.yaml.j2 @@ -0,0 +1,420 @@ +#jinja2: lstrip_blocks: True +# Network-specific config options +network: + # Displayname template for LinkedIn contacts. + displayname_template: {{ matrix_bridge_mautrix_linkedin_network_displayname_template | to_json }} + sync: + # Number of most recently active dialogs to check when syncing chats. + # Set to 0 to remove limit. + update_limit: 0 + # Number of most recently active dialogs to create portals for when syncing chats. + # Set to 0 to remove limit. + create_limit: 10 + + +# Config options that affect the central bridge module. +bridge: + # The prefix for commands. Only required in non-management rooms. + command_prefix: {{ matrix_bridge_mautrix_linkedin_command_prefix | to_json }} + # Should the bridge create a space for each login containing the rooms that account is in? + personal_filtering_spaces: {{ matrix_bridge_mautrix_linkedin_bridge_personal_filtering_spaces | to_json }} + # Whether the bridge should set names and avatars explicitly for DM portals. + # This is only necessary when using clients that don't support MSC4171. + private_chat_portal_meta: false + # Should events be handled asynchronously within portal rooms? + # If true, events may end up being out of order, but slow events won't block other ones. + async_events: false + # Should every user have their own portals rather than sharing them? + # By default, users who are in the same group on the remote network will be + # in the same Matrix room bridged to that group. If this is set to true, + # every user will get their own Matrix room instead. + split_portals: false + # Should the bridge resend `m.bridge` events to all portals on startup? + resend_bridge_info: false + + # Should leaving Matrix rooms be bridged as leaving groups on the remote network? + bridge_matrix_leave: false + # Should room tags only be synced when creating the portal? Tags mean things like favorite/pin and archive/low priority. + # Tags currently can't be synced back to the remote network, so a continuous sync means tagging from Matrix will be undone. + tag_only_on_create: true + # Should room mute status only be synced when creating the portal? + # Like tags, mutes can't currently be synced back to the remote network. + mute_only_on_create: true + + # What should be done to portal rooms when a user logs out or is logged out? + # Permitted values: + # nothing - Do nothing, let the user stay in the portals + # kick - Remove the user from the portal rooms, but don't delete them + # unbridge - Remove all ghosts in the room and disassociate it from the remote chat + # delete - Remove all ghosts and users from the room (i.e. delete it) + cleanup_on_logout: + # Should cleanup on logout be enabled at all? + enabled: false + # Settings for manual logouts (explicitly initiated by the Matrix user) + manual: + # Action for private portals which will never be shared with other Matrix users. + private: nothing + # Action for portals with a relay user configured. + relayed: nothing + # Action for portals which may be shared, but don't currently have any other Matrix users. + shared_no_users: nothing + # Action for portals which have other logged-in Matrix users. + shared_has_users: nothing + # Settings for credentials being invalidated (initiated by the remote network, possibly through user action). + # Keys have the same meanings as in the manual section. + bad_credentials: + private: nothing + relayed: nothing + shared_no_users: nothing + shared_has_users: nothing + + # Settings for relay mode + relay: + # Whether relay mode should be allowed. If allowed, the set-relay command can be used to turn any + # authenticated user into a relaybot for that chat. + enabled: false + # Should only admins be allowed to set themselves as relay users? + # If true, non-admins can only set users listed in default_relays as relays in a room. + admin_only: true + # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. + default_relays: [] + # The formats to use when sending messages via the relaybot. + # Available variables: + # .Sender.UserID - The Matrix user ID of the sender. + # .Sender.Displayname - The display name of the sender (if set). + # .Sender.RequiresDisambiguation - Whether the sender's name may be confused with the name of another user in the room. + # .Sender.DisambiguatedName - The disambiguated name of the sender. This will be the displayname if set, + # plus the user ID in parentheses if the displayname is not unique. + # If the displayname is not set, this is just the user ID. + # .Message - The `formatted_body` field of the message. + # .Caption - The `formatted_body` field of the message, if it's a caption. Otherwise an empty string. + # .FileName - The name of the file being sent. + message_formats: + m.text: "{% raw %}{{ .Sender.DisambiguatedName }}: {{ .Message }}{% endraw %}" + m.notice: "{% raw %}{{ .Sender.DisambiguatedName }}: {{ .Message }}{% endraw %}" + m.emote: "{% raw %}* {{ .Sender.DisambiguatedName }} {{ .Message }}{% endraw %}" + m.file: "{% raw %}{{ .Sender.DisambiguatedName }} sent a file{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.image: "{% raw %}{{ .Sender.DisambiguatedName }} sent an image{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.audio: "{% raw %}{{ .Sender.DisambiguatedName }} sent an audio file{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.video: "{% raw %}{{ .Sender.DisambiguatedName }} sent a video{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.location: "{% raw %}{{ .Sender.DisambiguatedName }} sent a location{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + # For networks that support per-message displaynames (i.e. Slack and Discord), the template for those names. + # This has all the Sender variables available under message_formats (but without the .Sender prefix). + # Note that you need to manually remove the displayname from message_formats above. + displayname_format: "{% raw %}{{ .DisambiguatedName }}{% endraw %}" + + # Permissions for using the bridge. + # Permitted values: + # relay - Talk through the relaybot (if enabled), no access otherwise + # commands - Access to use commands in the bridge, but not login. + # user - Access to use the bridge with puppeting. + # admin - Full access, user level with some additional administration tools. + # Permitted keys: + # * - All Matrix users + # domain - All users on that homeserver + # mxid - Specific user + permissions: {{ matrix_bridge_mautrix_linkedin_bridge_permissions|to_json }} + +# Config for the bridge's database. +database: + # The database type. "sqlite3-fk-wal" and "postgres" are supported. + type: postgres + # The database URI. + # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. + # https://github.com/mattn/go-sqlite3#connection-string + # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable + # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql + uri: {{ matrix_bridge_mautrix_linkedin_appservice_database_uri|to_json }} + # Maximum number of connections. + max_open_conns: 5 + max_idle_conns: 1 + # Maximum connection idle time and lifetime before they're closed. Disabled if null. + # Parsed with https://pkg.go.dev/time#ParseDuration + max_conn_idle_time: null + max_conn_lifetime: null + +# Homeserver details. +homeserver: + # The address that this appservice can use to connect to the homeserver. + # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, + # but https also works if they run on different machines. + address: {{ matrix_bridge_mautrix_linkedin_homeserver_address | to_json }} + # The domain of the homeserver (also known as server_name, used for MXIDs, etc). + domain: {{ matrix_bridge_mautrix_linkedin_homeserver_domain | to_json }} + + # What software is the homeserver running? + # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. + software: standard + # The URL to push real-time bridge status to. + # If set, the bridge will make POST requests to this URL whenever a user's remote network connection state changes. + # The bridge will use the appservice as_token to authorize requests. + status_endpoint: + # Endpoint for reporting per-message status. + # If set, the bridge will make POST requests to this URL when processing a message from Matrix. + # It will make one request when receiving the message (step BRIDGE), one after decrypting if applicable + # (step DECRYPTED) and one after sending to the remote network (step REMOTE). Errors will also be reported. + # The bridge will use the appservice as_token to authorize requests. + message_send_checkpoint_endpoint: + # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? + async_media: {{ matrix_bridge_mautrix_linkedin_homeserver_async_media | to_json }} + + # Should the bridge use a websocket for connecting to the homeserver? + # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, + # mautrix-asmux (deprecated), and hungryserv (proprietary). + websocket: false + # How often should the websocket be pinged? Pinging will be disabled if this is zero. + ping_interval_seconds: 0 + +# Application service host/registration related details. +# Changing these values requires regeneration of the registration (except when noted otherwise) +appservice: + # The address that the homeserver can use to connect to this appservice. + address: {{ matrix_bridge_mautrix_linkedin_appservice_address }} + # A public address that external services can use to reach this appservice. + # This value doesn't affect the registration file. + public_address: {{ matrix_bridge_mautrix_linkedin_bridge_public_address | to_json }} + + # The hostname and port where this appservice should listen. + # For Docker, you generally have to change the hostname to 0.0.0.0. + hostname: 0.0.0.0 + port: 8080 + + # The unique ID of this appservice. + id: linkedin + # Appservice bot details. + bot: + # Username of the appservice bot. + username: {{ matrix_bridge_mautrix_linkedin_appservice_bot_username|to_json }} + # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty + # to leave display name/avatar as-is. + displayname: LinkedIn bridge bot + avatar: mxc://maunium.net/CqzBEHjrLsfdqixWZgNHMlRT + + # Whether to receive ephemeral events via appservice transactions. + ephemeral_events: true + # Should incoming events be handled asynchronously? + # This may be necessary for large public instances with lots of messages going through. + # However, messages will not be guaranteed to be bridged in the same order they were sent in. + # This value doesn't affect the registration file. + async_transactions: false + + # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. + as_token: {{ matrix_bridge_mautrix_linkedin_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_linkedin_homeserver_token | to_json }} + + # Localpart template of MXIDs for remote users. + # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. + username_template: {{ matrix_bridge_mautrix_linkedin_appservice_username_template | to_json }} + +# Config options that affect the Matrix connector of the bridge. +matrix: + # Whether the bridge should send the message status as a custom com.beeper.message_send_status event. + message_status_events: false + # Whether the bridge should send a read receipt after successfully bridging a message. + delivery_receipts: false + # Whether the bridge should send error notices via m.notice events when a message fails to bridge. + message_error_notices: true + # Whether the bridge should update the m.direct account data event when double puppeting is enabled. + sync_direct_chat_list: false + # Whether created rooms should have federation enabled. If false, created portal rooms + # will never be federated. Changing this option requires recreating rooms. + federate_rooms: {{ matrix_bridge_mautrix_linkedin_federate_rooms | to_json }} + # The threshold as bytes after which the bridge should roundtrip uploads via the disk + # rather than keeping the whole file in memory. + upload_file_threshold: 5242880 + +# Segment-compatible analytics endpoint for tracking some events, like provisioning API login and encryption errors. +analytics: + # API key to send with tracking requests. Tracking is disabled if this is null. + token: null + # Address to send tracking requests to. + url: https://api.segment.io/v1/track + # Optional user ID for tracking events. If null, defaults to using Matrix user ID. + user_id: null + +# Settings for provisioning API +provisioning: + # Prefix for the provisioning API paths. + prefix: /_matrix/provision + # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, + # or if set to "disable", the provisioning API will be disabled. + shared_secret: {{ matrix_bridge_mautrix_linkedin_provisioning_shared_secret | to_json }} + # Whether to allow provisioning API requests to be authed using Matrix access tokens. + # This follows the same rules as double puppeting to determine which server to contact to check the token, + # which means that by default, it only works for users on the same server as the bridge. + allow_matrix_auth: true + # Enable debug API at /debug with provisioning authentication. + debug_endpoints: false + +# Some networks require publicly accessible media download links (e.g. for user avatars when using Discord webhooks). +# These settings control whether the bridge will provide such public media access. +public_media: + # Should public media be enabled at all? + # The public_address field under the appservice section MUST be set when enabling public media. + enabled: false + # A key for signing public media URLs. + # If set to "generate", a random key will be generated. + signing_key: {{ matrix_bridge_mautrix_linkedin_public_media_signing_key | to_json }} + # Number of seconds that public media URLs are valid for. + # If set to 0, URLs will never expire. + expiry: 0 + # Length of hash to use for public media URLs. Must be between 0 and 32. + hash_length: 32 + +# Settings for converting remote media to custom mxc:// URIs instead of reuploading. +# More details can be found at https://docs.mau.fi/bridges/go/discord/direct-media.html +direct_media: + # Should custom mxc:// URIs be used instead of reuploading media? + enabled: false + # The server name to use for the custom mxc:// URIs. + # This server name will effectively be a real Matrix server, it just won't implement anything other than media. + # You must either set up .well-known delegation from this domain to the bridge, or proxy the domain directly to the bridge. + server_name: media.example.com + # Optionally a custom .well-known response. This defaults to `server_name:443` + well_known_response: + # Optionally specify a custom prefix for the media ID part of the MXC URI. + media_id_prefix: + # If the remote network supports media downloads over HTTP, then the bridge will use MSC3860/MSC3916 + # media download redirects if the requester supports it. Optionally, you can force redirects + # and not allow proxying at all by setting this to false. + # This option does nothing if the remote network does not support media downloads over HTTP. + allow_proxy: true + # Matrix server signing key to make the federation tester pass, same format as synapse's .signing.key file. + # This key is also used to sign the mxc:// URIs to ensure only the bridge can generate them. + server_key: "" + +# Settings for backfilling messages. +# Note that the exact way settings are applied depends on the network connector. +# See https://docs.mau.fi/bridges/general/backfill.html for more details. +backfill: + # Whether to do backfilling at all. + enabled: {{ matrix_bridge_mautrix_linkedin_backfill_enabled | to_json }} + # Maximum number of messages to backfill in empty rooms. + max_initial_messages: {{ matrix_bridge_mautrix_linkedin_backfill_max_initial_messages | to_json }} + # Maximum number of missed messages to backfill after bridge restarts. + max_catchup_messages: {{ matrix_bridge_mautrix_linkedin_backfill_max_catchup_messages | to_json }} + # If a backfilled chat is older than this number of hours, + # mark it as read even if it's unread on the remote network. + unread_hours_threshold: {{ matrix_bridge_mautrix_linkedin_backfill_unread_hours_threshold | to_json }} + # Settings for backfilling threads within other backfills. + threads: + # Maximum number of messages to backfill in a new thread. + max_initial_messages: {{ matrix_bridge_mautrix_linkedin_backfill_threads_max_initial_messages | to_json }} + # Settings for the backwards backfill queue. This only applies when connecting to + # Beeper as standard Matrix servers don't support inserting messages into history. + queue: + # Should the backfill queue be enabled? + enabled: false + # Number of messages to backfill in one batch. + batch_size: 100 + # Delay between batches in seconds. + batch_delay: 20 + # Maximum number of batches to backfill per portal. + # If set to -1, all available messages will be backfilled. + max_batches: -1 + # Optional network-specific overrides for max batches. + # Interpretation of this field depends on the network connector. + max_batches_override: {} + +# Settings for enabling double puppeting +double_puppet: + # Servers to always allow double puppeting from. + # This is only for other servers and should NOT contain the server the bridge is on. + servers: {} + # Whether to allow client API URL discovery for other servers. When using this option, + # users on other servers can use double puppeting even if their server URLs aren't + # explicitly added to the servers map above. + allow_discovery: false + # Shared secrets for automatic double puppeting. + # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. + secrets: {{ matrix_bridge_mautrix_linkedin_double_puppet_secrets | to_json }} + +# End-to-bridge encryption support options. +# +# See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. +encryption: + # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. + allow: {{ matrix_bridge_mautrix_linkedin_bridge_encryption_allow | to_json }} + # Whether to force-enable encryption in all bridged rooms. + default: {{ matrix_bridge_mautrix_linkedin_bridge_encryption_default | to_json }} + # Whether to require all messages to be encrypted and drop any unencrypted messages. + require: {{ matrix_bridge_mautrix_linkedin_bridge_encryption_require | to_json }} + # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. + # This option is not yet compatible with standard Matrix servers like Synapse and should not be used. + appservice: {{ matrix_bridge_mautrix_linkedin_bridge_encryption_appservice | to_json }} + # Whether to use MSC4190 instead of appservice login to create the bridge bot device. + # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. + # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). + # Changing this option requires updating the appservice registration file. + msc4190: {{ matrix_bridge_mautrix_linkedin_msc4190_enabled | to_json }} + # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) + # Requires msc4190 to replace keys on reset + self_sign: {{ matrix_bridge_mautrix_linkedin_self_sign_enabled | to_json }} + # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. + # You must use a client that supports requesting keys from other users to use this feature. + allow_key_sharing: {{ matrix_bridge_mautrix_linkedin_bridge_encryption_key_sharing_allow | to_json }} + # Pickle key for encrypting encryption keys in the bridge database. + # If set to generate, a random key will be generated. + pickle_key: {{ matrix_bridge_mautrix_linkedin_bridge_encryption_pickle_key | to_json }} + # Options for deleting megolm sessions from the bridge. + delete_keys: + # Beeper-specific: delete outbound sessions when hungryserv confirms + # that the user has uploaded the key to key backup. + delete_outbound_on_ack: false + # Don't store outbound sessions in the inbound table. + dont_store_outbound: false + # Ratchet megolm sessions forward after decrypting messages. + ratchet_on_decrypt: false + # Delete fully used keys (index >= max_messages) after decrypting messages. + delete_fully_used_on_decrypt: false + # Delete previous megolm sessions from same device when receiving a new one. + delete_prev_on_new_session: false + # Delete megolm sessions received from a device when the device is deleted. + delete_on_device_delete: false + # Periodically delete megolm sessions when 2x max_age has passed since receiving the session. + periodically_delete_expired: false + # Delete inbound megolm sessions that don't have the received_at field used for + # automatic ratcheting and expired session deletion. This is meant as a migration + # to delete old keys prior to the bridge update. + delete_outdated_inbound: false + # What level of device verification should be required from users? + # + # Valid levels: + # unverified - Send keys to all device in the room. + # cross-signed-untrusted - Require valid cross-signing, but trust all cross-signing keys. + # cross-signed-tofu - Require valid cross-signing, trust cross-signing keys on first use (and reject changes). + # cross-signed-verified - Require valid cross-signing, plus a valid user signature from the bridge bot. + # Note that creating user signatures from the bridge bot is not currently possible. + # verified - Require manual per-device verification + # (currently only possible by modifying the `trust` column in the `crypto_device` database table). + verification_levels: + # Minimum level for which the bridge should send keys to when bridging messages from the remote network to Matrix. + receive: unverified + # Minimum level that the bridge should accept for incoming Matrix messages. + send: unverified + # Minimum level that the bridge should require for accepting key requests. + share: cross-signed-tofu + # Options for Megolm room key rotation. These options allow you to configure the m.room.encryption event content. + # See https://spec.matrix.org/v1.10/client-server-api/#mroomencryption for more information about that event. + rotation: + # Enable custom Megolm room key rotation settings. Note that these + # settings will only apply to rooms created after this option is set. + enable_custom: false + # The maximum number of milliseconds a session should be used + # before changing it. The Matrix spec recommends 604800000 (a week) + # as the default. + milliseconds: 604800000 + # The maximum number of messages that should be sent with a given a + # session before changing it. The Matrix spec recommends 100 as the + # default. + messages: 100 + # Disable rotating keys when a user's devices change? + # You should not enable this option unless you understand all the implications. + disable_device_change_key_rotation: false + +# Logging config. See https://github.com/tulir/zeroconfig for details. +logging: + min_level: {{ matrix_bridge_mautrix_linkedin_logging_level }} + writers: + - type: stdout + format: pretty diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/templates/config.yaml.j2.license b/roles/custom/matrix-bridge-mautrix-linkedin/templates/config.yaml.j2.license new file mode 100644 index 000000000..bd628c0b6 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/templates/config.yaml.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-linkedin/templates/labels.j2 new file mode 100644 index 000000000..3761cdd54 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/templates/labels.j2 @@ -0,0 +1,51 @@ +{# +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later +#} + +{% if matrix_bridge_mautrix_linkedin_container_labels_traefik_enabled %} +traefik.enable=true + +{% if matrix_bridge_mautrix_linkedin_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_linkedin_container_labels_traefik_docker_network }} +{% endif %} + +{% if matrix_bridge_mautrix_linkedin_container_labels_exposure_enabled %} +############################################################ +# # +# Bridge API exposure # +# # +############################################################ + +traefik.http.services.matrix-mautrix-linkedin-exposure.loadbalancer.server.port=8080 + +traefik.http.middlewares.matrix-mautrix-linkedin-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_linkedin_exposure_path_prefix }} +traefik.http.routers.matrix-mautrix-linkedin-exposure.middlewares=matrix-mautrix-linkedin-exposure-strip-prefix + +traefik.http.routers.matrix-mautrix-linkedin-exposure.rule={{ matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_rule }} + +{% if matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-linkedin-exposure.priority={{ matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-mautrix-linkedin-exposure.service=matrix-mautrix-linkedin-exposure +traefik.http.routers.matrix-mautrix-linkedin-exposure.entrypoints={{ matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_entrypoints }} + +traefik.http.routers.matrix-mautrix-linkedin-exposure.tls={{ matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-mautrix-linkedin-exposure.tls.certResolver={{ matrix_bridge_mautrix_linkedin_container_labels_exposure_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Bridge API exposure # +# # +############################################################ +{% endif %} + + +{% endif %} + +{{ matrix_bridge_mautrix_linkedin_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/templates/systemd/matrix-mautrix-linkedin.service.j2 b/roles/custom/matrix-bridge-mautrix-linkedin/templates/systemd/matrix-mautrix-linkedin.service.j2 new file mode 100644 index 000000000..edba7621d --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/templates/systemd/matrix-mautrix-linkedin.service.j2 @@ -0,0 +1,51 @@ +#jinja2: lstrip_blocks: True +[Unit] +Description=Matrix Mautrix LinkedIn bridge +{% for service in matrix_bridge_mautrix_linkedin_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_bridge_mautrix_linkedin_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-mautrix-linkedin 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-mautrix-linkedin 2>/dev/null || true' + +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ + --rm \ + --name=matrix-mautrix-linkedin \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --network={{ matrix_bridge_mautrix_linkedin_container_network }} \ + --mount type=bind,src={{ matrix_bridge_mautrix_linkedin_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_linkedin_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_linkedin_base_path }}/labels \ + --workdir=/data \ + {% for arg in matrix_bridge_mautrix_linkedin_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_bridge_mautrix_linkedin_container_image }} \ + /usr/bin/mautrix-linkedin -c /config/config.yaml -r /config/registration.yaml --no-update + +{% if matrix_bridge_mautrix_linkedin_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_linkedin_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-linkedin +{% endfor %} +{% endif %} + +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-linkedin + +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-mautrix-linkedin 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-mautrix-linkedin 2>/dev/null || true' +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-mautrix-linkedin + +[Install] +WantedBy=multi-user.target diff --git a/roles/custom/matrix-bridge-mautrix-linkedin/templates/systemd/matrix-mautrix-linkedin.service.j2.license b/roles/custom/matrix-bridge-mautrix-linkedin/templates/systemd/matrix-mautrix-linkedin.service.j2.license new file mode 100644 index 000000000..bd628c0b6 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-linkedin/templates/systemd/matrix-mautrix-linkedin.service.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/README.md b/roles/custom/matrix-bridge-mautrix-meta-instagram/README.md index a8755d41a..5a1ef2905 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-instagram/README.md +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/README.md @@ -1,11 +1,12 @@ # matrix-mautrix-meta-instagram -This bridge role is derived from the matrix-mautrix-meta-messenger Ansible role via automatic changes (see `just rebuild-mautrix-meta-instagram` or `bin/rebuild-mautrix-meta-instagram.sh`). +This role installs the Instagram bridge developed in the [mautrix-meta](https://github.com/mautrix/meta) repository. -If you'd like to make a change to this role, consider making it to the `matrix-mautrix-meta-messenger` role instead. +This role used to be auto-generated from the `matrix-bridge-mautrix-meta-messenger` role, back when a single mautrix-meta binary served both Messenger and Instagram depending on a `mode` configuration setting. +Since mautrix-meta v26.07, Instagram is a separate binary with its own container image (`ig-` prefixed tags) and its own configuration schema, so the two roles are maintained independently. diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-meta-instagram/defaults/main.yml index d674726db..f5df6f4d3 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-instagram/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/defaults/main.yml @@ -7,308 +7,254 @@ --- -# mautrix-meta is a Matrix <-> Facebook/Messenger/Instagram bridge +# mautrix-instagram is a Matrix <-> Instagram bridge # Project source code URL: https://github.com/mautrix/meta # -# WARNING: this bridge role is used for both Messenger and Instagram. -# This Messenger role acts as a source and auto-generates matrix-bridge-mautrix-meta-instagram -# thanks to `just rebuild-mautrix-meta-instagram` (`bin/rebuild-mautrix-meta-instagram.sh`). -# If you'd like to make changes to the Instagram role, consider making your changes to the Messenger role instead. +# Since v26.07, upstream develops the Instagram bridge in the mautrix-meta repository, but ships it as a separate binary and a separate container image (with `ig-` prefixed tags). +# The Messenger side of mautrix-meta is covered by the matrix-bridge-mautrix-meta-messenger role. -matrix_mautrix_meta_instagram_enabled: true +matrix_bridge_mautrix_meta_instagram_enabled: true -matrix_mautrix_meta_instagram_identifier: matrix-mautrix-meta-instagram +matrix_bridge_mautrix_meta_instagram_identifier: matrix-mautrix-meta-instagram # renovate: datasource=docker depName=dock.mau.dev/mautrix/meta -matrix_mautrix_meta_instagram_version: v0.2602.0 - -matrix_mautrix_meta_instagram_base_path: "{{ matrix_base_data_path }}/mautrix-meta-instagram" -matrix_mautrix_meta_instagram_config_path: "{{ matrix_mautrix_meta_instagram_base_path }}/config" -matrix_mautrix_meta_instagram_data_path: "{{ matrix_mautrix_meta_instagram_base_path }}/data" -matrix_mautrix_meta_instagram_container_src_files_path: "{{ matrix_mautrix_meta_instagram_base_path }}/container-src" - -matrix_mautrix_meta_instagram_container_image_self_build: false -matrix_mautrix_meta_instagram_container_image_self_build_repo: "https://github.com/mautrix/meta.git" - -matrix_mautrix_meta_instagram_container_image: "{{ matrix_mautrix_meta_instagram_container_image_registry_prefix }}mautrix/meta:{{ matrix_mautrix_meta_instagram_container_image_tag }}" -matrix_mautrix_meta_instagram_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_meta_instagram_container_image_self_build else matrix_mautrix_meta_instagram_container_image_registry_prefix_upstream }}" -matrix_mautrix_meta_instagram_container_image_registry_prefix_upstream: "{{ matrix_mautrix_meta_instagram_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_meta_instagram_container_image_registry_prefix_upstream_default: "dock.mau.dev/" +matrix_bridge_mautrix_meta_instagram_version: v0.2608.0 + +matrix_bridge_mautrix_meta_instagram_base_path: "{{ matrix_base_data_path }}/mautrix-meta-instagram" +matrix_bridge_mautrix_meta_instagram_config_path: "{{ matrix_bridge_mautrix_meta_instagram_base_path }}/config" +matrix_bridge_mautrix_meta_instagram_data_path: "{{ matrix_bridge_mautrix_meta_instagram_base_path }}/data" +matrix_bridge_mautrix_meta_instagram_container_src_files_path: "{{ matrix_bridge_mautrix_meta_instagram_base_path }}/container-src" + +matrix_bridge_mautrix_meta_instagram_container_image_self_build: false +matrix_bridge_mautrix_meta_instagram_container_image_self_build_repo: "https://github.com/mautrix/meta.git" + +# The path to the bridge binary inside the container image. +# The prebuilt image is built by upstream's CI, whose Dockerfile copies the Instagram binary to a fixed `/usr/bin/mautrix-meta` destination. +# Self-building uses the `Dockerfile.ig` file from the source tree, which produces `/usr/bin/mautrix-instagram`. +matrix_bridge_mautrix_meta_instagram_container_binary_path: "{{ '/usr/bin/mautrix-instagram' if matrix_bridge_mautrix_meta_instagram_container_image_self_build else '/usr/bin/mautrix-meta' }}" + +matrix_bridge_mautrix_meta_instagram_container_image: "{{ matrix_bridge_mautrix_meta_instagram_container_image_registry_prefix }}mautrix/meta:{{ matrix_bridge_mautrix_meta_instagram_container_image_tag }}" +matrix_bridge_mautrix_meta_instagram_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_meta_instagram_container_image_self_build else matrix_bridge_mautrix_meta_instagram_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_meta_instagram_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_meta_instagram_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_meta_instagram_container_image_registry_prefix_upstream_default: "dock.mau.dev/" +# Since v26.07, Instagram is a separate bridge upstream (its own binary and its own container image). +# Both bridges are published to the same container image repository, with Instagram's tags carrying an `ig-` prefix. +# See: https://mau.fi/blog/2026-07-mautrix-release/#new-instagram-bridge +# # Prebuilt container images for specific commit hashes are tagged with an architecture suffix (e.g. `HASH-amd64`). -matrix_mautrix_meta_instagram_container_image_tag: "{{ matrix_mautrix_meta_instagram_version }}{{ ('-' ~ matrix_architecture) if (matrix_mautrix_meta_instagram_version | length == 40) else '' }}" -matrix_mautrix_meta_instagram_container_image_force_pull: "{{ matrix_mautrix_meta_instagram_container_image.endswith(':latest') }}" +matrix_bridge_mautrix_meta_instagram_container_image_tag: "ig-{{ matrix_bridge_mautrix_meta_instagram_version }}{{ ('-' ~ matrix_architecture) if (matrix_bridge_mautrix_meta_instagram_version | length == 40) else '' }}" -matrix_mautrix_meta_instagram_container_network: "" +matrix_bridge_mautrix_meta_instagram_container_network: "" -matrix_mautrix_meta_instagram_container_additional_networks: "{{ matrix_mautrix_meta_instagram_container_additional_networks_auto + matrix_mautrix_meta_instagram_container_additional_networks_custom }}" -matrix_mautrix_meta_instagram_container_additional_networks_auto: [] -matrix_mautrix_meta_instagram_container_additional_networks_custom: [] +matrix_bridge_mautrix_meta_instagram_container_additional_networks: "{{ matrix_bridge_mautrix_meta_instagram_container_additional_networks_auto + matrix_bridge_mautrix_meta_instagram_container_additional_networks_custom }}" +matrix_bridge_mautrix_meta_instagram_container_additional_networks_auto: [] +matrix_bridge_mautrix_meta_instagram_container_additional_networks_custom: [] -# matrix_mautrix_meta_instagram_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_mautrix_meta_instagram_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_meta_instagram_container_labels_additional_labels`. -matrix_mautrix_meta_instagram_container_labels_traefik_enabled: true -matrix_mautrix_meta_instagram_container_labels_traefik_docker_network: "{{ matrix_mautrix_meta_instagram_container_network }}" -matrix_mautrix_meta_instagram_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_meta_instagram_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose the bridge's metrics -matrix_mautrix_meta_instagram_container_labels_metrics_enabled: "{{ matrix_mautrix_meta_instagram_metrics_enabled and matrix_mautrix_meta_instagram_metrics_proxying_enabled }}" -matrix_mautrix_meta_instagram_container_labels_metrics_traefik_rule: "Host(`{{ matrix_mautrix_meta_instagram_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_mautrix_meta_instagram_metrics_proxying_path_prefix }}`)" -matrix_mautrix_meta_instagram_container_labels_metrics_traefik_priority: 0 -matrix_mautrix_meta_instagram_container_labels_metrics_traefik_entrypoints: "{{ matrix_mautrix_meta_instagram_container_labels_traefik_entrypoints }}" -matrix_mautrix_meta_instagram_container_labels_metrics_traefik_tls: "{{ matrix_mautrix_meta_instagram_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_mautrix_meta_instagram_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_mautrix_meta_instagram_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_mautrix_meta_instagram_container_labels_metrics_middleware_basic_auth_enabled: false -# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_mautrix_meta_instagram_container_labels_metrics_middleware_basic_auth_users: '' - -# matrix_mautrix_meta_instagram_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# To inject your own other container labels, see `matrix_bridge_mautrix_meta_instagram_container_labels_additional_labels`. +matrix_bridge_mautrix_meta_instagram_container_labels_traefik_enabled: true +matrix_bridge_mautrix_meta_instagram_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_meta_instagram_container_network }}" +matrix_bridge_mautrix_meta_instagram_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_meta_instagram_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-meta-instagram's HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_meta_instagram_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_meta_instagram_exposure_enabled }}" +matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_meta_instagram_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_meta_instagram_exposure_path_prefix }}`)" +matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_meta_instagram_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_meta_instagram_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_meta_instagram_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_meta_instagram_container_labels_additional_labels: | +# matrix_bridge_mautrix_meta_instagram_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_meta_instagram_container_labels_additional_labels: '' +matrix_bridge_mautrix_meta_instagram_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_meta_instagram_container_extra_arguments: [] +matrix_bridge_mautrix_meta_instagram_container_extra_arguments: [] # List of systemd services that the systemd service depends on. -matrix_mautrix_meta_instagram_systemd_required_services_list: "{{ matrix_mautrix_meta_instagram_systemd_required_services_list_default + matrix_mautrix_meta_instagram_systemd_required_services_list_auto + matrix_mautrix_meta_instagram_systemd_required_services_list_custom }}" -matrix_mautrix_meta_instagram_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_meta_instagram_systemd_required_services_list_auto: [] -matrix_mautrix_meta_instagram_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_meta_instagram_systemd_required_services_list: "{{ matrix_bridge_mautrix_meta_instagram_systemd_required_services_list_default + matrix_bridge_mautrix_meta_instagram_systemd_required_services_list_auto + matrix_bridge_mautrix_meta_instagram_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_meta_instagram_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_meta_instagram_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_meta_instagram_systemd_required_services_list_custom: [] # List of systemd services that the systemd service wants -matrix_mautrix_meta_instagram_systemd_wanted_services_list: [] +matrix_bridge_mautrix_meta_instagram_systemd_wanted_services_list: [] # Controls whether the bridge container exposes its HTTP port. # # Takes an ":" or "" value (e.g. "127.0.0.1:29319"), or empty string to not expose. -matrix_mautrix_meta_instagram_container_http_host_bind_port: '' +matrix_bridge_mautrix_meta_instagram_container_http_host_bind_port: '' # Database-related configuration fields -matrix_mautrix_meta_instagram_database_engine: sqlite3-fk-wal - -matrix_mautrix_meta_instagram_sqlite_database_path_local: "{{ matrix_mautrix_meta_instagram_data_path }}/mautrix-meta.db" -matrix_mautrix_meta_instagram_sqlite_database_path_in_container: "/data/mautrix-meta.db" +matrix_bridge_mautrix_meta_instagram_database_engine: sqlite3-fk-wal -matrix_mautrix_meta_instagram_database_suffix: |- - {{ - ({ - 'facebook': '_facebook', - 'facebook-tor': '_facebook', - 'messenger': '_messenger', - 'instagram': '_instagram', - })[matrix_mautrix_meta_instagram_meta_mode] - }} +matrix_bridge_mautrix_meta_instagram_sqlite_database_path_local: "{{ matrix_bridge_mautrix_meta_instagram_data_path }}/mautrix-meta.db" +matrix_bridge_mautrix_meta_instagram_sqlite_database_path_in_container: "/data/mautrix-meta.db" -matrix_mautrix_meta_instagram_database_username: "matrix_mautrix_meta{{ matrix_mautrix_meta_instagram_database_suffix }}" -matrix_mautrix_meta_instagram_database_password: '' -matrix_mautrix_meta_instagram_database_hostname: '' -matrix_mautrix_meta_instagram_database_port: 5432 -matrix_mautrix_meta_instagram_database_name: "matrix_mautrix_meta{{ matrix_mautrix_meta_instagram_database_suffix }}" -matrix_mautrix_meta_instagram_database_sslmode: disable +matrix_bridge_mautrix_meta_instagram_database_username: matrix_mautrix_meta_instagram +matrix_bridge_mautrix_meta_instagram_database_password: '' +matrix_bridge_mautrix_meta_instagram_database_hostname: '' +matrix_bridge_mautrix_meta_instagram_database_port: 5432 +matrix_bridge_mautrix_meta_instagram_database_name: matrix_mautrix_meta_instagram +matrix_bridge_mautrix_meta_instagram_database_sslmode: disable -matrix_mautrix_meta_instagram_database_connection_string: 'postgres://{{ matrix_mautrix_meta_instagram_database_username }}:{{ matrix_mautrix_meta_instagram_database_password }}@{{ matrix_mautrix_meta_instagram_database_hostname }}:{{ matrix_mautrix_meta_instagram_database_port }}/{{ matrix_mautrix_meta_instagram_database_name }}?sslmode={{ matrix_mautrix_meta_instagram_database_sslmode }}' +matrix_bridge_mautrix_meta_instagram_database_connection_string: 'postgres://{{ matrix_bridge_mautrix_meta_instagram_database_username }}:{{ matrix_bridge_mautrix_meta_instagram_database_password }}@{{ matrix_bridge_mautrix_meta_instagram_database_hostname }}:{{ matrix_bridge_mautrix_meta_instagram_database_port }}/{{ matrix_bridge_mautrix_meta_instagram_database_name }}?sslmode={{ matrix_bridge_mautrix_meta_instagram_database_sslmode }}' -matrix_mautrix_meta_instagram_homeserver_address: "" +matrix_bridge_mautrix_meta_instagram_homeserver_address: "" +matrix_bridge_mautrix_meta_instagram_homeserver_domain: '{{ matrix_domain }}' # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_mautrix_meta_instagram_homeserver_async_media: false -matrix_mautrix_meta_instagram_homeserver_domain: '{{ matrix_domain }}' -matrix_mautrix_meta_instagram_homeserver_token: '' +matrix_bridge_mautrix_meta_instagram_homeserver_async_media: false +matrix_bridge_mautrix_meta_instagram_homeserver_token: '' -matrix_mautrix_meta_instagram_appservice_address: "http://{{ matrix_mautrix_meta_instagram_identifier }}:29319" +matrix_bridge_mautrix_meta_instagram_appservice_address: "http://{{ matrix_bridge_mautrix_meta_instagram_identifier }}:29319" -matrix_mautrix_meta_instagram_appservice_id: "{{ matrix_mautrix_meta_instagram_meta_mode }}" +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_meta_instagram_bridge_public_address`). +matrix_bridge_mautrix_meta_instagram_scheme: https -matrix_mautrix_meta_instagram_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" -matrix_mautrix_meta_instagram_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" +# The public base URL at which this bridge's HTTP API is reachable from outside (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_meta_instagram_bridge_public_address: "{{ (matrix_bridge_mautrix_meta_instagram_scheme + '://' + matrix_bridge_mautrix_meta_instagram_exposure_hostname + matrix_bridge_mautrix_meta_instagram_exposure_path_prefix) if matrix_bridge_mautrix_meta_instagram_exposure_enabled else '' }}" -# For Facebook/Messenger, we use the same `@messengerbot:example.com` username regardless of how bridging happens for multiple reasons: -# - it's consistent - regardless of how bridging happens, the bridged service is actually Messenger -# - it's easy for users - you may change the mode, but the bot is always at `@messengerbot:example.com` -# - it doesn't conflict with mautrix-facebook which uses `@facebookbot:example.com` -# - `matrix_mautrix_meta_instagram_appservice_avatar` only has icons for Messenger and Instagram, not Facebook -matrix_mautrix_meta_instagram_appservice_username_prefix: |- - {{ - ({ - 'facebook': 'messenger', - 'facebook-tor': 'messenger', - 'messenger': 'messenger', - 'instagram': 'instagram', - })[matrix_mautrix_meta_instagram_meta_mode] - }} -matrix_mautrix_meta_instagram_appservice_username: "{{ matrix_mautrix_meta_instagram_appservice_username_prefix }}bot" -matrix_mautrix_meta_instagram_appservice_displayname: "{{ matrix_mautrix_meta_instagram_meta_mode | capitalize }} bridge bot" -matrix_mautrix_meta_instagram_appservice_avatar: "{{ 'mxc://maunium.net/JxjlbZUlCPULEeHZSwleUXQv' if matrix_mautrix_meta_instagram_meta_mode == 'instagram' else 'mxc://maunium.net/ygtkteZsXnGJLJHRchUwYWak' }}" +matrix_bridge_mautrix_meta_instagram_appservice_id: instagram + +matrix_bridge_mautrix_meta_instagram_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_meta_instagram_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" -matrix_mautrix_meta_instagram_appservice_database_type: "{{ matrix_mautrix_meta_instagram_database_engine }}" +matrix_bridge_mautrix_meta_instagram_appservice_username: instagrambot +matrix_bridge_mautrix_meta_instagram_appservice_displayname: Instagram bridge bot +matrix_bridge_mautrix_meta_instagram_appservice_avatar: mxc://maunium.net/JxjlbZUlCPULEeHZSwleUXQv -matrix_mautrix_meta_instagram_appservice_database_uri: |- +matrix_bridge_mautrix_meta_instagram_appservice_database_type: "{{ matrix_bridge_mautrix_meta_instagram_database_engine }}" + +matrix_bridge_mautrix_meta_instagram_appservice_database_uri: |- {{ { - 'sqlite3-fk-wal': ('sqlite:///' + matrix_mautrix_meta_instagram_sqlite_database_path_in_container), - 'postgres': matrix_mautrix_meta_instagram_database_connection_string, - }[matrix_mautrix_meta_instagram_database_engine] + 'sqlite3-fk-wal': matrix_bridge_mautrix_meta_instagram_sqlite_database_path_in_container, + 'postgres': matrix_bridge_mautrix_meta_instagram_database_connection_string, + }[matrix_bridge_mautrix_meta_instagram_database_engine] }} -matrix_mautrix_meta_instagram_appservice_token: '' - -# Controls which service this bridge is for. -# Valid options: -# * facebook - connect to FB Messenger via facebook.com -# * facebook-tor - connect to FB Messenger via facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion -# (note: does not currently proxy media downloads) -# * messenger - connect to FB Messenger via messenger.com (can be used with the facebook side deactivated) -# * instagram - connect to Instagram DMs via instagram.com -matrix_mautrix_meta_instagram_meta_mode: instagram - -# When in `instagram` mode (see `matrix_mautrix_meta_instagram_meta_mode`), should the bridge connect to WhatsApp servers for encrypted chats? -matrix_mautrix_meta_instagram_meta_ig_e2ee: false +matrix_bridge_mautrix_meta_instagram_appservice_token: '' -matrix_mautrix_meta_instagram_provisioning_shared_secret: disable +matrix_bridge_mautrix_meta_instagram_provisioning_shared_secret: disable -# Whether or not metrics endpoint should be enabled. -# Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_mautrix_meta_instagram_metrics_proxying_enabled`. -matrix_mautrix_meta_instagram_metrics_enabled: false +# Controls whether mautrix-meta-instagram's HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_meta_instagram_exposure_enabled: false +matrix_bridge_mautrix_meta_instagram_exposure_hostname: '' +matrix_bridge_mautrix_meta_instagram_exposure_path_prefix: '' -# Controls whether metrics should be exposed on a public URL. -matrix_mautrix_meta_instagram_metrics_proxying_enabled: false -matrix_mautrix_meta_instagram_metrics_proxying_hostname: '' -matrix_mautrix_meta_instagram_metrics_proxying_path_prefix: '' - -matrix_mautrix_meta_instagram_bridge_username_prefix: |- - {{ - ({ - 'facebook': 'facebook_', - 'facebook-tor': 'facebook_', - 'messenger': 'messenger_', - 'instagram': 'instagram_', - })[matrix_mautrix_meta_instagram_meta_mode] - }} +matrix_bridge_mautrix_meta_instagram_bridge_username_prefix: instagram_ -# Localpart template of MXIDs for FB/IG users. +# Localpart template of MXIDs for IG users. # {{.}} is replaced with the internal ID of the FB/IG user. # Changing this may require that you change the regex in the appservice. -matrix_mautrix_meta_instagram_bridge_username_template: "{{ matrix_mautrix_meta_instagram_bridge_username_prefix + '{{.}}' }}" +matrix_bridge_mautrix_meta_instagram_bridge_username_template: "{{ matrix_bridge_mautrix_meta_instagram_bridge_username_prefix + '{{.}}' }}" -matrix_mautrix_meta_instagram_bridge_displayname_suffix: |- - {{ - ({ - 'facebook': '(FB)', - 'facebook-tor': '(FB)', - 'messenger': '(FB)', - 'instagram': '(IG)', - })[matrix_mautrix_meta_instagram_meta_mode] - }} +matrix_bridge_mautrix_meta_instagram_bridge_displayname_suffix: '(IG)' -matrix_mautrix_meta_instagram_bridge_displayname_template: '{% raw %}{{or .DisplayName .Username "Unknown user"}}{% endraw %}{{ (" " ~ matrix_mautrix_meta_instagram_bridge_displayname_suffix) if matrix_mautrix_meta_instagram_bridge_displayname_suffix else "" }}' +matrix_bridge_mautrix_meta_instagram_bridge_displayname_template: '{% raw %}{{or .DisplayName .Username "Unknown user"}}{% endraw %}{{ (" " ~ matrix_bridge_mautrix_meta_instagram_bridge_displayname_suffix) if matrix_bridge_mautrix_meta_instagram_bridge_displayname_suffix else "" }}' # The prefix for commands. Only required in non-management rooms. -matrix_mautrix_meta_instagram_bridge_command_prefix: |- - {{ - ({ - 'facebook': '!fb', - 'facebook-tor': '!fb', - 'messenger': '!fb', - 'instagram': '!ig', - })[matrix_mautrix_meta_instagram_meta_mode] - }} +matrix_bridge_mautrix_meta_instagram_bridge_command_prefix: '!ig' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_mautrix_meta_instagram_bridge_federate_rooms: true +matrix_bridge_mautrix_meta_instagram_bridge_federate_rooms: true # Should the bridge create a space for each logged-in user and add bridged rooms to it? # Users who logged in before turning this on should run `!meta sync-space` to create and fill the space for the first time. -matrix_mautrix_meta_instagram_bridge_personal_filtering_spaces: true +matrix_bridge_mautrix_meta_instagram_bridge_personal_filtering_spaces: true # Enable End-to-bridge encryption -matrix_mautrix_meta_instagram_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_meta_instagram_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_mautrix_meta_instagram_bridge_encryption_allow_key_sharing: "{{ matrix_mautrix_meta_instagram_bridge_encryption_allow }}" -matrix_mautrix_meta_instagram_bridge_encryption_appservice: false -matrix_mautrix_meta_instagram_bridge_encryption_require: false +matrix_bridge_mautrix_meta_instagram_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_meta_instagram_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_meta_instagram_bridge_encryption_allow_key_sharing: "{{ matrix_bridge_mautrix_meta_instagram_bridge_encryption_allow }}" +matrix_bridge_mautrix_meta_instagram_bridge_encryption_appservice: false +matrix_bridge_mautrix_meta_instagram_bridge_encryption_require: false -matrix_mautrix_meta_instagram_double_puppet_secrets: "{{ matrix_mautrix_meta_instagram_double_puppet_secrets_auto | combine(matrix_mautrix_meta_instagram_double_puppet_secrets_custom) }}" -matrix_mautrix_meta_instagram_double_puppet_secrets_auto: {} -matrix_mautrix_meta_instagram_double_puppet_secrets_custom: {} +matrix_bridge_mautrix_meta_instagram_double_puppet_secrets: "{{ matrix_bridge_mautrix_meta_instagram_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_meta_instagram_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_meta_instagram_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_meta_instagram_double_puppet_secrets_custom: {} -matrix_mautrix_meta_instagram_bridge_permissions: "{{ matrix_mautrix_meta_instagram_bridge_permissions_default | combine(matrix_mautrix_meta_instagram_bridge_permissions_custom) }}" +matrix_bridge_mautrix_meta_instagram_bridge_permissions: "{{ matrix_bridge_mautrix_meta_instagram_bridge_permissions_default | combine(matrix_bridge_mautrix_meta_instagram_bridge_permissions_custom) }}" -matrix_mautrix_meta_instagram_bridge_permissions_default: |- +matrix_bridge_mautrix_meta_instagram_bridge_permissions_default: |- {{ - {'*': 'relay', matrix_mautrix_meta_instagram_homeserver_domain: 'user'} + {'*': 'relay', matrix_bridge_mautrix_meta_instagram_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} -matrix_mautrix_meta_instagram_bridge_permissions_custom: {} +matrix_bridge_mautrix_meta_instagram_bridge_permissions_custom: {} # Enable bridge relay bot functionality -matrix_mautrix_meta_instagram_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" -matrix_mautrix_meta_instagram_bridge_relay_admin_only: true -matrix_mautrix_meta_instagram_bridge_relay_default_relays: [] +matrix_bridge_mautrix_meta_instagram_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" +matrix_bridge_mautrix_meta_instagram_bridge_relay_admin_only: true +matrix_bridge_mautrix_meta_instagram_bridge_relay_default_relays: [] -matrix_mautrix_meta_instagram_backfill_enabled: true -matrix_mautrix_meta_instagram_backfill_max_initial_messages: 50 -matrix_mautrix_meta_instagram_backfill_max_catchup_messages: 500 -matrix_mautrix_meta_instagram_backfill_unread_hours_threshold: 720 -matrix_mautrix_meta_instagram_backfill_threads_max_initial_messages: 50 +matrix_bridge_mautrix_meta_instagram_backfill_enabled: true +matrix_bridge_mautrix_meta_instagram_backfill_max_initial_messages: 50 +matrix_bridge_mautrix_meta_instagram_backfill_max_catchup_messages: 500 +matrix_bridge_mautrix_meta_instagram_backfill_unread_hours_threshold: 720 +matrix_bridge_mautrix_meta_instagram_backfill_threads_max_initial_messages: 50 -matrix_mautrix_meta_instagram_public_media_signing_key: '' +matrix_bridge_mautrix_meta_instagram_public_media_signing_key: '' # Specifies the default log level. # This bridge uses zerolog, so valid levels are: panic, fatal, error, warn, info, debug, trace -matrix_mautrix_meta_instagram_logging_min_level: warn +matrix_bridge_mautrix_meta_instagram_logging_min_level: warn # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_meta_instagram_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_meta_instagram_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_meta_instagram_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_meta_instagram_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_meta_instagram_configuration_extension_yaml: | +matrix_bridge_mautrix_meta_instagram_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_meta_instagram_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_meta_instagram_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_meta_instagram_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_meta_instagram_configuration_yaml`. -matrix_mautrix_meta_instagram_configuration_extension: "{{ matrix_mautrix_meta_instagram_configuration_extension_yaml | from_yaml if matrix_mautrix_meta_instagram_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_meta_instagram_configuration_extension: "{{ matrix_bridge_mautrix_meta_instagram_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_meta_instagram_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_meta_instagram_configuration_yaml`. -matrix_mautrix_meta_instagram_configuration: "{{ matrix_mautrix_meta_instagram_configuration_yaml | from_yaml | combine(matrix_mautrix_meta_instagram_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_meta_instagram_configuration_yaml`. +matrix_bridge_mautrix_meta_instagram_configuration: "{{ matrix_bridge_mautrix_meta_instagram_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_meta_instagram_configuration_extension, recursive=True) }}" -matrix_mautrix_meta_instagram_registration_yaml: | - id: {{ matrix_mautrix_meta_instagram_appservice_id | to_json }} - as_token: {{ matrix_mautrix_meta_instagram_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_meta_instagram_homeserver_token | to_json }} +matrix_bridge_mautrix_meta_instagram_registration_yaml: | + id: {{ matrix_bridge_mautrix_meta_instagram_appservice_id | to_json }} + as_token: {{ matrix_bridge_mautrix_meta_instagram_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_meta_instagram_homeserver_token | to_json }} namespaces: users: - exclusive: true - regex: '^@{{ matrix_mautrix_meta_instagram_bridge_username_prefix }}.+:{{ matrix_mautrix_meta_instagram_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_mautrix_meta_instagram_bridge_username_prefix | regex_escape }}.+:{{ matrix_bridge_mautrix_meta_instagram_homeserver_domain | regex_escape }}$' - exclusive: true - regex: '^@{{ matrix_mautrix_meta_instagram_appservice_username | regex_escape }}:{{ matrix_mautrix_meta_instagram_homeserver_domain | regex_escape }}$' - url: {{ matrix_mautrix_meta_instagram_appservice_address }} - sender_localpart: _bot_{{ matrix_mautrix_meta_instagram_appservice_username }} + regex: '^@{{ matrix_bridge_mautrix_meta_instagram_appservice_username | regex_escape }}:{{ matrix_bridge_mautrix_meta_instagram_homeserver_domain | regex_escape }}$' + url: {{ matrix_bridge_mautrix_meta_instagram_appservice_address }} + sender_localpart: _bot_{{ matrix_bridge_mautrix_meta_instagram_appservice_username }} rate_limited: false de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_mautrix_meta_instagram_msc4190_enabled | to_json }} + io.element.msc4190: {{ matrix_bridge_mautrix_meta_instagram_msc4190_enabled | to_json }} -matrix_mautrix_meta_instagram_registration: "{{ matrix_mautrix_meta_instagram_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_meta_instagram_registration: "{{ matrix_bridge_mautrix_meta_instagram_registration_yaml | from_yaml }}" -# matrix_mautrix_meta_instagram_restart_necessary controls whether the service +# matrix_bridge_mautrix_meta_instagram_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -316,4 +262,4 @@ matrix_mautrix_meta_instagram_registration: "{{ matrix_mautrix_meta_instagram_re # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_meta_instagram_restart_necessary: false +matrix_bridge_mautrix_meta_instagram_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/converge.yml new file mode 100644 index 000000000..9e618ac9f --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-meta-instagram Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-meta-instagram Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-meta-instagram is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-meta-instagram systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-meta-instagram.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/molecule.yml new file mode 100644 index 000000000..96333d762 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/molecule.yml @@ -0,0 +1,94 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-meta-instagram-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_meta_instagram_container_network: mautrix-meta-instagram-molecule + + # The stub in prepare.yml. The scenario exercises startup and appservice readiness, + # but deliberately never supplies an Instagram account or contacts Instagram. + matrix_bridge_mautrix_meta_instagram_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_meta_instagram_homeserver_domain: molecule.local + + # Postgres is the normal deployment path selected by group_vars/matrix_servers. + # The non-default database and user names make a migrated schema evidence that the + # bridge used the connection string this role composed, rather than an image default. + matrix_bridge_mautrix_meta_instagram_database_engine: postgres + matrix_bridge_mautrix_meta_instagram_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_meta_instagram_database_name: molecule_meta_instagram + matrix_bridge_mautrix_meta_instagram_database_username: molecule_meta_instagram + matrix_bridge_mautrix_meta_instagram_database_password: molecule_pg_password_82bd17 + + # Test-only placeholders that have to reach both config.yaml and registration.yaml. + matrix_bridge_mautrix_meta_instagram_appservice_token: molecule_instagram_as_token_f51aa8 + matrix_bridge_mautrix_meta_instagram_homeserver_token: molecule_instagram_hs_token_0f92c7 + + # These differ from the role and component defaults. They cover Instagram's separate + # post-v26.07 configuration schema rather than relying on the old shared Meta mode. + matrix_bridge_mautrix_meta_instagram_appservice_id: molecule-instagram + matrix_bridge_mautrix_meta_instagram_appservice_username: molecule-instagrambot + matrix_bridge_mautrix_meta_instagram_bridge_username_prefix: molecule_ig_ + matrix_bridge_mautrix_meta_instagram_bridge_command_prefix: "!molecule-ig" + matrix_bridge_mautrix_meta_instagram_bridge_displayname_suffix: "(Molecule IG)" + matrix_bridge_mautrix_meta_instagram_bridge_personal_filtering_spaces: false + matrix_bridge_mautrix_meta_instagram_bridge_federate_rooms: false + matrix_bridge_mautrix_meta_instagram_backfill_enabled: false + matrix_bridge_mautrix_meta_instagram_backfill_max_initial_messages: 23 + matrix_bridge_mautrix_meta_instagram_provisioning_shared_secret: molecule_instagram_provisioning_57f2ca + matrix_bridge_mautrix_meta_instagram_logging_min_level: debug + + # Traefik is not deployed. The scenario verifies both the public address the bridge + # reads and the labels the role attaches to the container. + matrix_bridge_mautrix_meta_instagram_exposure_enabled: true + matrix_bridge_mautrix_meta_instagram_exposure_hostname: bridges.molecule.local + matrix_bridge_mautrix_meta_instagram_exposure_path_prefix: /bridges/meta-instagram + matrix_bridge_mautrix_meta_instagram_scheme: https + matrix_bridge_mautrix_meta_instagram_container_labels_additional_labels: | + molecule.scenario=matrix-bridge-mautrix-meta-instagram + + # verify.yml is a separate play, so pin the paths that it reads there. + matrix_bridge_mautrix_meta_instagram_base_path: /matrix/mautrix-meta-instagram + matrix_bridge_mautrix_meta_instagram_config_path: /matrix/mautrix-meta-instagram/config + matrix_bridge_mautrix_meta_instagram_data_path: /matrix/mautrix-meta-instagram/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/prepare.yml new file mode 100644 index 000000000..dceac5f73 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/prepare.yml @@ -0,0 +1,91 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-meta-instagram Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks resolve owner and group by name; matrix-base creates these + # accounts in a real deployment. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role also creates this network during converge. It must exist first so that the + # Postgres helper and homeserver stub can share the bridge's real private network. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_meta_instagram_container_network }}" + register: mautrix_meta_instagram_molecule_network + changed_when: mautrix_meta_instagram_molecule_network.rc == 0 + failed_when: + - mautrix_meta_instagram_molecule_network.rc != 0 + - "'already exists' not in mautrix_meta_instagram_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_meta_instagram_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_meta_instagram_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_meta_instagram_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_meta_instagram_database_password }}" + + # The bridge calls /whoami before opening its listener and refuses an unexpected bot MXID. + # This provides only that homeserver-side startup contract; it never bridges traffic. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_meta_instagram_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_meta_instagram_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_meta_instagram_appservice_username }}:{{ matrix_bridge_mautrix_meta_instagram_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/verify.yml new file mode 100644 index 000000000..a5f2aad8b --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/molecule/default/verify.yml @@ -0,0 +1,349 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the separate Instagram bridge image starts, reads the role's configuration and +# registration, reaches real Postgres, migrates it and exposes a ready appservice listener. +# No Instagram credentials are present and no traffic is sent to Instagram. +- name: Verify mautrix-meta-instagram + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + # Keep these lazy. config.yaml contains upstream Go templates whose braces would otherwise + # be evaluated as Jinja again when a stored fact was referenced. + vars: + mautrix_meta_instagram_config: "{{ mautrix_meta_instagram_config_file.content | b64decode | from_yaml }}" + mautrix_meta_instagram_registration: "{{ mautrix_meta_instagram_registration_file.content | b64decode | from_yaml }}" + mautrix_meta_instagram_labels_rendered: "{{ mautrix_meta_instagram_labels_file.content | b64decode }}" + gather_facts: false + + tasks: + # Read the shipped version from the role itself rather than pinning a duplicate in the + # scenario. A Renovate version bump must change what this assertion expects. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_meta_instagram_role_defaults + + - name: Wait for the mautrix-meta-instagram service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-meta-instagram.service + register: mautrix_meta_instagram_service + until: mautrix_meta_instagram_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always leaves a crash-looping service active, hence the independent restart + # counter condition. `is defined` prevents a missing property being coerced to zero. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_meta_instagram_service.status.ActiveState == 'active' + - mautrix_meta_instagram_service.status.NRestarts is defined + - mautrix_meta_instagram_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-meta-instagram.service is + {{ mautrix_meta_instagram_service.status.ActiveState | default('unknown') }} + after {{ mautrix_meta_instagram_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-mautrix-meta-instagram.service is active and has not restarted" + + # A 200 from the bridge's own liveness endpoint means it finished configuration parsing, + # the homeserver /whoami handshake and database initialization, then opened its listener. + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_meta_instagram_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - "http://matrix-mautrix-meta-instagram:29319/_matrix/mau/live" + register: mautrix_meta_instagram_live + changed_when: false + until: mautrix_meta_instagram_live.rc == 0 and mautrix_meta_instagram_live.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge liveness endpoint is ready + ansible.builtin.assert: + that: + - mautrix_meta_instagram_live.rc == 0 + - mautrix_meta_instagram_live.stdout == 'HTTP_STATUS=200' + fail_msg: >- + The bridge liveness endpoint did not return HTTP 200 + (rc={{ mautrix_meta_instagram_live.rc | default('?') }}, + output={{ mautrix_meta_instagram_live.stdout | default('none') }}) + success_msg: "The bridge liveness endpoint returns HTTP 200" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_meta_instagram_config_path }}/config.yaml" + register: mautrix_meta_instagram_config_file + + - name: Assert the rendered configuration carries the homeserver and appservice identity + ansible.builtin.assert: + that: + - mautrix_meta_instagram_config.homeserver.address == matrix_bridge_mautrix_meta_instagram_homeserver_address + - mautrix_meta_instagram_config.homeserver.domain == matrix_bridge_mautrix_meta_instagram_homeserver_domain + - mautrix_meta_instagram_config.appservice.id == matrix_bridge_mautrix_meta_instagram_appservice_id + - mautrix_meta_instagram_config.appservice.bot.username == matrix_bridge_mautrix_meta_instagram_appservice_username + - mautrix_meta_instagram_config.appservice.as_token == matrix_bridge_mautrix_meta_instagram_appservice_token + - mautrix_meta_instagram_config.appservice.hs_token == matrix_bridge_mautrix_meta_instagram_homeserver_token + fail_msg: "The rendered configuration does not carry the scenario's homeserver and appservice identity" + success_msg: "The rendered configuration carries the scenario's homeserver and appservice identity" + + # These values exercise the standalone Instagram bridge's own schema and all differ + # from the defaults shipped by either the role or the component. + - name: Assert the rendered configuration carries the bridge and Matrix behavior + ansible.builtin.assert: + that: + - mautrix_meta_instagram_config.bridge.command_prefix == matrix_bridge_mautrix_meta_instagram_bridge_command_prefix + - mautrix_meta_instagram_config.bridge.personal_filtering_spaces == matrix_bridge_mautrix_meta_instagram_bridge_personal_filtering_spaces + - mautrix_meta_instagram_config.matrix.federate_rooms == matrix_bridge_mautrix_meta_instagram_bridge_federate_rooms + - matrix_bridge_mautrix_meta_instagram_bridge_displayname_suffix in mautrix_meta_instagram_config.network.displayname_template + fail_msg: "The rendered configuration does not carry the scenario's bridge and Matrix behavior" + success_msg: "The rendered configuration carries the scenario's bridge and Matrix behavior" + + - name: Assert the rendered configuration carries the configured backfill policy + ansible.builtin.assert: + that: + - mautrix_meta_instagram_config.backfill.enabled == matrix_bridge_mautrix_meta_instagram_backfill_enabled + - mautrix_meta_instagram_config.backfill.max_initial_messages == matrix_bridge_mautrix_meta_instagram_backfill_max_initial_messages + fail_msg: "The rendered configuration does not carry the configured backfill policy" + success_msg: "The rendered configuration carries the configured backfill policy" + + - name: Assert the rendered configuration carries the provisioning secret + ansible.builtin.assert: + that: + - mautrix_meta_instagram_config.provisioning.shared_secret == matrix_bridge_mautrix_meta_instagram_provisioning_shared_secret + fail_msg: "The rendered configuration does not carry the provisioning secret" + success_msg: "The rendered configuration carries the provisioning secret" + + - name: Assert the rendered configuration carries the configured log level + ansible.builtin.assert: + that: + - mautrix_meta_instagram_config.logging.min_level == matrix_bridge_mautrix_meta_instagram_logging_min_level + fail_msg: "The rendered configuration does not carry the configured log level" + success_msg: "The rendered configuration carries the configured log level" + + # The new standalone Instagram bridge no longer has the old shared Meta `mode` switch. + - name: Assert the rendered configuration does not resurrect the legacy Meta mode + ansible.builtin.assert: + that: + - "'mode' not in mautrix_meta_instagram_config.network" + fail_msg: "The rendered configuration unexpectedly contains legacy network.mode" + success_msg: "The rendered configuration does not contain legacy network.mode" + + - name: Assert the configuration points at the database the role derived + ansible.builtin.assert: + that: + - mautrix_meta_instagram_config.database.type == matrix_bridge_mautrix_meta_instagram_database_engine + - matrix_bridge_mautrix_meta_instagram_database_username in mautrix_meta_instagram_config.database.uri + - matrix_bridge_mautrix_meta_instagram_database_name in mautrix_meta_instagram_config.database.uri + - matrix_bridge_mautrix_meta_instagram_database_hostname in mautrix_meta_instagram_config.database.uri + fail_msg: >- + database.uri is {{ mautrix_meta_instagram_config.database.uri | default('unset') }}, + which was not built from the scenario's connection settings + success_msg: "The configuration points at the database the role derived" + + - name: Assert the configuration carries the public address implied by exposure settings + ansible.builtin.assert: + that: + - mautrix_meta_instagram_config.appservice.public_address == matrix_bridge_mautrix_meta_instagram_scheme + '://' + matrix_bridge_mautrix_meta_instagram_exposure_hostname + matrix_bridge_mautrix_meta_instagram_exposure_path_prefix + fail_msg: >- + appservice.public_address is + {{ mautrix_meta_instagram_config.appservice.public_address | default('unset') }} + success_msg: "The configuration carries the public address implied by exposure settings" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_meta_instagram_config_path }}/registration.yaml" + register: mautrix_meta_instagram_registration_file + + - name: Assert the registration carries the configured handshake values + ansible.builtin.assert: + that: + - mautrix_meta_instagram_registration.id == matrix_bridge_mautrix_meta_instagram_appservice_id + - mautrix_meta_instagram_registration.as_token == matrix_bridge_mautrix_meta_instagram_appservice_token + - mautrix_meta_instagram_registration.hs_token == matrix_bridge_mautrix_meta_instagram_homeserver_token + - mautrix_meta_instagram_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_meta_instagram_appservice_username + - mautrix_meta_instagram_registration.url == 'http://matrix-mautrix-meta-instagram:29319' + fail_msg: "The appservice registration does not carry the configured handshake values" + success_msg: "The appservice registration carries the configured handshake values" + + # Exercise the generated regexes by matching representative MXIDs instead of repeating + # their implementation as expected strings. + - name: Assert the registration namespaces cover only Instagram ghosts and the bridge bot + ansible.builtin.assert: + that: + - mautrix_meta_instagram_ghost_regex | length > 0 + - mautrix_meta_instagram_bot_regex | length > 0 + - mautrix_meta_instagram_ghost_mxid is match(mautrix_meta_instagram_ghost_regex) + - mautrix_meta_instagram_messenger_mxid is not match(mautrix_meta_instagram_ghost_regex) + - mautrix_meta_instagram_bot_mxid is match(mautrix_meta_instagram_bot_regex) + fail_msg: "The registration namespaces do not cover only Instagram ghosts and the bridge bot" + success_msg: "The registration namespaces cover only Instagram ghosts and the bridge bot" + vars: + mautrix_meta_instagram_user_regexes: "{{ mautrix_meta_instagram_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_meta_instagram_ghost_regex: "{{ mautrix_meta_instagram_user_regexes | select('search', 'molecule_ig_') | first | default('') }}" + mautrix_meta_instagram_bot_regex: "{{ mautrix_meta_instagram_user_regexes | reject('search', 'molecule_ig_') | first | default('') }}" + mautrix_meta_instagram_ghost_mxid: "@molecule_ig_1234567890:{{ matrix_bridge_mautrix_meta_instagram_homeserver_domain }}" + mautrix_meta_instagram_messenger_mxid: "@messenger_1234567890:{{ matrix_bridge_mautrix_meta_instagram_homeserver_domain }}" + mautrix_meta_instagram_bot_mxid: "@{{ matrix_bridge_mautrix_meta_instagram_appservice_username }}:{{ matrix_bridge_mautrix_meta_instagram_homeserver_domain }}" + + # Tables can exist only after DNS resolution, authentication and genuine migrations. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_meta_instagram_database_username }} + - --dbname={{ matrix_bridge_mautrix_meta_instagram_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: mautrix_meta_instagram_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - mautrix_meta_instagram_tables.rc == 0 + - "'version' in mautrix_meta_instagram_table_names" + - "'portal' in mautrix_meta_instagram_table_names" + - "'user_login' in mautrix_meta_instagram_table_names" + - "'meta_thread' in mautrix_meta_instagram_table_names" + - "'meta_instagram_user_id' in mautrix_meta_instagram_table_names" + - mautrix_meta_instagram_table_names | length > 20 + fail_msg: >- + The bridge did not migrate its schema into + {{ matrix_bridge_mautrix_meta_instagram_database_name }} + (found {{ mautrix_meta_instagram_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + mautrix_meta_instagram_table_names: "{{ mautrix_meta_instagram_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_meta_instagram_base_path }}/labels" + register: mautrix_meta_instagram_labels_file + + - name: Assert the rendered labels route the exposure endpoint to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_meta_instagram_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_meta_instagram_container_network in mautrix_meta_instagram_labels_rendered" + - "'traefik.http.services.matrix-mautrix-meta-instagram-appservice.loadbalancer.server.port=29319' in mautrix_meta_instagram_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-meta-instagram-exposure.rule=Host(`bridges.molecule.local`) && PathPrefix(`/bridges/meta-instagram`)' in mautrix_meta_instagram_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-meta-instagram-exposure-strip-prefix.stripprefix.prefixes=/bridges/meta-instagram' in mautrix_meta_instagram_labels_rendered" + - "'molecule.scenario=matrix-bridge-mautrix-meta-instagram' in mautrix_meta_instagram_labels_rendered" + fail_msg: "The rendered labels do not route the exposure endpoint to the appservice port" + success_msg: "The rendered labels route the exposure endpoint to the appservice port" + + - name: Inspect the running bridge container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-meta-instagram + register: mautrix_meta_instagram_container_inspect + changed_when: false + + - name: Parse the running bridge container inspection + ansible.builtin.set_fact: + mautrix_meta_instagram_container: "{{ (mautrix_meta_instagram_container_inspect.stdout | from_json) | first }}" + + - name: Assert the running container uses the exact pinned Instagram image + ansible.builtin.assert: + that: + - mautrix_meta_instagram_container.Config.Image == mautrix_meta_instagram_expected_image + fail_msg: >- + The running container uses {{ mautrix_meta_instagram_container.Config.Image }}, + expected {{ mautrix_meta_instagram_expected_image }} + success_msg: "The running container uses the exact ig-prefixed image defaults/main.yml pins" + vars: + mautrix_meta_instagram_expected_image: >- + {{ mautrix_meta_instagram_role_defaults.matrix_bridge_mautrix_meta_instagram_container_image_registry_prefix_upstream_default }}mautrix/meta:ig-{{ mautrix_meta_instagram_role_defaults.matrix_bridge_mautrix_meta_instagram_version }} + + - name: Assert the running container uses the playbook-supplied identity + ansible.builtin.assert: + that: + - mautrix_meta_instagram_container.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + fail_msg: "The running container does not use the {{ matrix_user_uid }}:{{ matrix_user_gid }} identity" + success_msg: "The running container uses the playbook-supplied identity" + + - name: Assert the running container drops all capabilities and is unprivileged + ansible.builtin.assert: + that: + - "'ALL' in mautrix_meta_instagram_container.HostConfig.CapDrop" + - not mautrix_meta_instagram_container.HostConfig.Privileged + fail_msg: "The running container does not have the intended capability isolation" + success_msg: "The running container has the intended capability isolation" + + - name: Assert the running container mounts its configuration read-only + ansible.builtin.assert: + that: + - mautrix_meta_instagram_config_mount | length > 0 + - mautrix_meta_instagram_config_mount.Source == matrix_bridge_mautrix_meta_instagram_config_path + - not mautrix_meta_instagram_config_mount.RW | default(true) + fail_msg: "The running container does not mount the rendered configuration read-only" + success_msg: "The running container mounts the rendered configuration read-only" + vars: + mautrix_meta_instagram_config_mount: >- + {{ mautrix_meta_instagram_container.Mounts + | selectattr('Destination', 'equalto', '/config') + | first | default({}) }} + + - name: Assert the running container mounts its data directory writable + ansible.builtin.assert: + that: + - mautrix_meta_instagram_data_mount | length > 0 + - mautrix_meta_instagram_data_mount.Source == matrix_bridge_mautrix_meta_instagram_data_path + - mautrix_meta_instagram_data_mount.RW | default(false) + fail_msg: "The running container does not mount its data directory writable" + success_msg: "The running container mounts its data directory writable" + vars: + mautrix_meta_instagram_data_mount: >- + {{ mautrix_meta_instagram_container.Mounts + | selectattr('Destination', 'equalto', '/data') + | first | default({}) }} + + - name: Assert the rendered labels are attached to the running container + ansible.builtin.assert: + that: + - mautrix_meta_instagram_container.Config.Labels['traefik.enable'] == 'true' + - mautrix_meta_instagram_container.Config.Labels['traefik.docker.network'] == matrix_bridge_mautrix_meta_instagram_container_network + - mautrix_meta_instagram_container.Config.Labels['traefik.http.services.matrix-mautrix-meta-instagram-appservice.loadbalancer.server.port'] == '29319' + - mautrix_meta_instagram_container.Config.Labels['molecule.scenario'] == 'matrix-bridge-mautrix-meta-instagram' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The running container carries the labels the role rendered" + + - name: Assert the running container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_bridge_mautrix_meta_instagram_container_network in mautrix_meta_instagram_container.NetworkSettings.Networks + - mautrix_meta_instagram_container.NetworkSettings.Networks | length == 1 + fail_msg: >- + The running container has unexpected network attachments: + {{ mautrix_meta_instagram_container.NetworkSettings.Networks.keys() | list }} + success_msg: "The running container is attached only to its dedicated network" + + - name: Assert the running container publishes no host ports + ansible.builtin.assert: + that: + - mautrix_meta_instagram_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: "The running container unexpectedly publishes a host port" + success_msg: "The running container publishes no host ports" diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/install.yml b/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/install.yml index 22a4e8553..7da752b7c 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/install.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/install.yml @@ -6,43 +6,41 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_meta_instagram_migration_requires_restart: false + matrix_bridge_mautrix_meta_instagram_migration_requires_restart: false -- when: "matrix_mautrix_meta_instagram_database_engine == 'postgres'" +- when: "matrix_bridge_mautrix_meta_instagram_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mautrix_meta_instagram_sqlite_database_path_local }}" - register: matrix_mautrix_meta_instagram_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mautrix_meta_instagram_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_meta_instagram_sqlite_database_path_local_stat_result - - when: "matrix_mautrix_meta_instagram_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mautrix_meta_instagram_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mautrix_meta_instagram_sqlite_database_path_local }}" - dst: "{{ matrix_mautrix_meta_instagram_database_connection_string }}" + src: "{{ matrix_bridge_mautrix_meta_instagram_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_meta_instagram_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mautrix_meta_instagram_database_engine' + engine_variable_name: 'matrix_bridge_mautrix_meta_instagram_database_engine' engine_old: 'sqlite' - systemd_services_to_stop: "{{ [matrix_mautrix_meta_instagram_identifier + '.service'] }}" + systemd_services_to_stop: "{{ [matrix_bridge_mautrix_meta_instagram_identifier + '.service'] }}" - ansible.builtin.set_fact: - matrix_mautrix_meta_instagram_migration_requires_restart: true + matrix_bridge_mautrix_meta_instagram_migration_requires_restart: true - name: Ensure mautrix-meta-instagram container image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_meta_instagram_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_meta_instagram_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_meta_instagram_container_image_force_pull }}" - when: not matrix_mautrix_meta_instagram_container_image_self_build - register: matrix_mautrix_meta_instagram_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_meta_instagram_container_image }}" + pull: always + when: not matrix_bridge_mautrix_meta_instagram_container_image_self_build + register: matrix_bridge_mautrix_meta_instagram_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_meta_instagram_container_image_pull_result is not failed + until: matrix_bridge_mautrix_meta_instagram_container_image_pull_result is not failed - name: Ensure mautrix-meta-instagram paths exist ansible.builtin.file: @@ -52,93 +50,102 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_meta_instagram_base_path }}", when: true} - - {path: "{{ matrix_mautrix_meta_instagram_config_path }}", when: true} - - {path: "{{ matrix_mautrix_meta_instagram_data_path }}", when: true} - - {path: "{{ matrix_mautrix_meta_instagram_container_src_files_path }}", when: "{{ matrix_mautrix_meta_instagram_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_meta_instagram_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_meta_instagram_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_meta_instagram_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_meta_instagram_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_meta_instagram_container_image_self_build }}"} when: item.when | bool -- when: matrix_mautrix_meta_instagram_container_image_self_build | bool +- when: matrix_bridge_mautrix_meta_instagram_container_image_self_build | bool block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure mautrix-meta-instagram repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_meta_instagram_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure mautrix-meta-instagram repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_mautrix_meta_instagram_container_image_self_build_repo }}" - dest: "{{ matrix_mautrix_meta_instagram_container_src_files_path }}" - version: "{{ matrix_mautrix_meta_instagram_container_image.split(':')[1] }}" + repo: "{{ matrix_bridge_mautrix_meta_instagram_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_mautrix_meta_instagram_container_src_files_path }}" + version: "{{ matrix_bridge_mautrix_meta_instagram_version }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_meta_instagram_git_pull_results + register: matrix_bridge_mautrix_meta_instagram_git_pull_results - name: Ensure mautrix-meta-instagram container image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_meta_instagram_container_image }}" - source: build - force_source: "{{ matrix_mautrix_meta_instagram_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_meta_instagram_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_meta_instagram_container_src_files_path }}" - pull: true + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_meta_instagram_container_image }}" + dockerfile: Dockerfile.ig + path: "{{ matrix_bridge_mautrix_meta_instagram_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_meta_instagram_git_pull_results.changed | bool else 'never' }}" + register: matrix_bridge_mautrix_meta_instagram_container_image_build_result - name: Ensure mautrix-meta-instagram config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_meta_instagram_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_meta_instagram_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_meta_instagram_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_meta_instagram_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_meta_instagram_config_result + register: matrix_bridge_mautrix_meta_instagram_config_result - name: Ensure mautrix-meta-instagram registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_meta_instagram_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_meta_instagram_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_meta_instagram_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_meta_instagram_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_meta_instagram_registration_result + register: matrix_bridge_mautrix_meta_instagram_registration_result - name: Ensure mautrix-meta-instagram support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_meta_instagram_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_meta_instagram_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_mautrix_meta_instagram_support_files_result + register: matrix_bridge_mautrix_meta_instagram_support_files_result - name: Ensure mautrix-meta-instagram container network is created + when: matrix_bridge_mautrix_meta_instagram_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_meta_instagram_container_network }}" + name: "{{ matrix_bridge_mautrix_meta_instagram_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - name: Ensure mautrix-meta-instagram.service installed ansible.builtin.template: - src: "{{ role_path }}/templates/systemd/matrix-mautrix-meta.service.j2" - dest: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_mautrix_meta_instagram_identifier }}.service" + src: "{{ role_path }}/templates/systemd/matrix-mautrix-meta-instagram.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_bridge_mautrix_meta_instagram_identifier }}.service" mode: '0644' - register: matrix_mautrix_meta_instagram_systemd_service_result + register: matrix_bridge_mautrix_meta_instagram_systemd_service_result - name: Determine whether mautrix-meta-instagram needs a restart ansible.builtin.set_fact: - matrix_mautrix_meta_instagram_restart_necessary: >- + matrix_bridge_mautrix_meta_instagram_restart_necessary: >- {{ - matrix_mautrix_meta_instagram_migration_requires_restart | default(false) - or matrix_mautrix_meta_instagram_config_result.changed | default(false) - or matrix_mautrix_meta_instagram_registration_result.changed | default(false) - or matrix_mautrix_meta_instagram_support_files_result.changed | default(false) - or matrix_mautrix_meta_instagram_systemd_service_result.changed | default(false) - or matrix_mautrix_meta_instagram_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_meta_instagram_migration_requires_restart | default(false) + or matrix_bridge_mautrix_meta_instagram_config_result.changed | default(false) + or matrix_bridge_mautrix_meta_instagram_registration_result.changed | default(false) + or matrix_bridge_mautrix_meta_instagram_support_files_result.changed | default(false) + or matrix_bridge_mautrix_meta_instagram_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_meta_instagram_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_meta_instagram_container_image_build_result.changed | default(false) }} - name: Ensure mautrix-meta-instagram.service restarted, if necessary ansible.builtin.service: - name: "{{ matrix_mautrix_meta_instagram_identifier }}.service" + name: "{{ matrix_bridge_mautrix_meta_instagram_identifier }}.service" state: restarted daemon_reload: true - when: "matrix_mautrix_meta_instagram_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_meta_instagram_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/main.yml index f06937433..c87656d24 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/main.yml @@ -10,15 +10,15 @@ - install-all - install-mautrix-meta-instagram block: - - when: matrix_mautrix_meta_instagram_enabled | bool + - when: matrix_bridge_mautrix_meta_instagram_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_meta_instagram_enabled | bool + - when: matrix_bridge_mautrix_meta_instagram_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/install.yml" - tags: - setup-all - setup-mautrix-meta-instagram block: - - when: not matrix_mautrix_meta_instagram_enabled | bool + - when: not matrix_bridge_mautrix_meta_instagram_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/uninstall.yml b/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/uninstall.yml index 794607e04..38da9e7af 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/uninstall.yml @@ -6,19 +6,19 @@ - name: Check existence of mautrix-meta-instagram service ansible.builtin.stat: - path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_mautrix_meta_instagram_identifier }}.service" - register: matrix_mautrix_meta_instagram_service_stat + path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_bridge_mautrix_meta_instagram_identifier }}.service" + register: matrix_bridge_mautrix_meta_instagram_service_stat -- when: matrix_mautrix_meta_instagram_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_meta_instagram_service_stat.stat.exists | bool block: - name: Ensure mautrix-meta-instagram is stopped ansible.builtin.service: - name: "{{ matrix_mautrix_meta_instagram_identifier }}" + name: "{{ matrix_bridge_mautrix_meta_instagram_identifier }}" state: stopped enabled: false daemon_reload: true - name: Ensure mautrix-meta-instagram.service doesn't exist ansible.builtin.file: - path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_mautrix_meta_instagram_identifier }}.service" + path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_bridge_mautrix_meta_instagram_identifier }}.service" state: absent diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/validate_config.yml index 6df63b15c..55c6d101e 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/tasks/validate_config.yml @@ -11,14 +11,12 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_meta_instagram_metrics_proxying_hostname', when: "{{ matrix_mautrix_meta_instagram_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_meta_instagram_metrics_proxying_path_prefix', when: "{{ matrix_mautrix_meta_instagram_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_meta_instagram_appservice_token', when: true} - - {'name': 'matrix_mautrix_meta_instagram_homeserver_token', when: true} - - {'name': 'matrix_mautrix_meta_instagram_container_network', when: true} - - {'name': 'matrix_mautrix_meta_instagram_homeserver_address', when: true} - - {'name': 'matrix_mautrix_meta_instagram_database_hostname', when: "{{ matrix_mautrix_meta_instagram_database_engine == 'postgres' }}"} - - {'name': 'matrix_mautrix_meta_instagram_database_password', when: "{{ matrix_mautrix_meta_instagram_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_meta_instagram_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_meta_instagram_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_meta_instagram_container_network', when: true} + - {'name': 'matrix_bridge_mautrix_meta_instagram_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_meta_instagram_database_hostname', when: "{{ matrix_bridge_mautrix_meta_instagram_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_meta_instagram_database_password', when: "{{ matrix_bridge_mautrix_meta_instagram_database_engine == 'postgres' }}"} - name: (Deprecation) Catch and report renamed mautrix-meta-instagram variables ansible.builtin.fail: @@ -27,7 +25,24 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_meta_instagram_bridge_login_shared_secret', 'new': ''} - - {'old': 'matrix_mautrix_meta_instagram_bridge_login_shared_secret_map_custom', 'new': ''} - - {'old': 'matrix_mautrix_meta_instagram_bridge_management_room_text_welcome', 'new': ''} - - {'old': 'matrix_mautrix_meta_instagram_container_image_name_prefix', 'new': 'matrix_mautrix_meta_instagram_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_bridge_login_shared_secret', 'new': ''} + - {'old': 'matrix_bridge_mautrix_meta_instagram_bridge_login_shared_secret_map_custom', 'new': ''} + - {'old': 'matrix_bridge_mautrix_meta_instagram_bridge_management_room_text_welcome', 'new': ''} + - {'old': 'matrix_bridge_mautrix_meta_instagram_container_image_name_prefix', 'new': 'matrix_bridge_mautrix_meta_instagram_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_metrics_enabled', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_metrics_proxying_enabled', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_metrics_proxying_hostname', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_metrics_proxying_path_prefix', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_container_labels_metrics_enabled', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_container_labels_metrics_traefik_rule', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_container_labels_metrics_traefik_priority', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_container_labels_metrics_traefik_entrypoints', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_container_labels_metrics_traefik_tls', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_container_labels_metrics_traefik_tls_certResolver', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_container_labels_metrics_middleware_basic_auth_users', 'new': ' (mautrix-meta-instagram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_meta_ig_e2ee', 'new': ' (mautrix-meta no longer has an `ig_e2ee` configuration option)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_meta_mode', 'new': ' (since v0.2608.0, upstream ships Instagram as a separate bridge without a `mode` configuration option)'} + - {'old': 'matrix_bridge_mautrix_meta_instagram_appservice_username_prefix', 'new': ''} + - {'old': 'matrix_bridge_mautrix_meta_instagram_database_suffix', 'new': ' (the database name is controlled directly by matrix_bridge_mautrix_meta_instagram_database_name)'} diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/config.yaml.j2 index 968d4eda9..be8452be8 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/config.yaml.j2 @@ -1,48 +1,50 @@ #jinja2: lstrip_blocks: True # Network-specific config options network: - # Which service is this bridge for? Available options: - # * unset - allow users to pick any service when logging in (except facebook-tor) - # * facebook - connect to FB Messenger via facebook.com - # * facebook-tor - connect to FB Messenger via facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion - # (note: does not currently proxy media downloads) - # * messenger - connect to FB Messenger via messenger.com (can be used with the facebook side deactivated) - # * instagram - connect to Instagram DMs via instagram.com - # - # Remember to change the appservice ID, bot profile info, bridge username_template and management_room_text too. - mode: {{ matrix_mautrix_meta_instagram_meta_mode | to_json }} - - # When in Instagram mode, should the bridge connect to WhatsApp servers for encrypted chats? - # In FB/Messenger mode encryption is always enabled, this option only affects Instagram mode. - ig_e2ee: {{ matrix_mautrix_meta_instagram_meta_ig_e2ee | to_json }} - - # Displayname template for FB/IG users. Available variables: + # Displayname template for IG users. Available variables: # .DisplayName - The display name set by the user. # .Username - The username set by the user. # .ID - The internal user ID of the user. - displayname_template: {{ matrix_mautrix_meta_instagram_bridge_displayname_template | to_json }} + displayname_template: {{ matrix_bridge_mautrix_meta_instagram_bridge_displayname_template | to_json }} - # Static proxy address (HTTP or SOCKS5) for connecting to Meta. + # Static proxy address (HTTP or SOCKS5) for connecting to Instagram. proxy: # HTTP endpoint to request new proxy address from, for dynamically assigned proxies. # The endpoint must return a JSON body with a string field called proxy_url. get_proxy_from: + # Should media be proxied too? + proxy_media: false + # Should other traffic, not configured here, be proxied? + proxy_other: true # Minimum interval between full reconnects in seconds, default is 1 hour min_full_reconnect_interval_seconds: 3600 # Interval to force refresh the connection (full reconnect), default is 20 hours. Set 0 to disable force refreshes. force_refresh_interval_seconds: 72000 + # Should connection state be cached to allow quicker restarts? + cache_connection_state: true # Disable fetching XMA media (reels, stories, etc) when backfilling. disable_xma_backfill: true # Disable fetching XMA media entirely. disable_xma_always: false + # Should typing notification bridging be disabled? + disable_typing: false + # Should view-once messages be disabled entirely? + disable_view_once: false + + # Thread backfill settings for syncing older conversations + thread_backfill: + # Number of batches (pages) to backfill (-1 for unlimited, 0 to disable) + batch_count: 0 + # Delay between fetching each batch of threads (to avoid rate limiting) + batch_delay: 2s # Config options that affect the central bridge module. bridge: # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_mautrix_meta_instagram_bridge_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_mautrix_meta_instagram_bridge_command_prefix | to_json }} # Should the bridge create a space for each login containing the rooms that account is in? - personal_filtering_spaces: {{ matrix_mautrix_meta_instagram_bridge_personal_filtering_spaces | to_json }} + personal_filtering_spaces: {{ matrix_bridge_mautrix_meta_instagram_bridge_personal_filtering_spaces | to_json }} # Whether the bridge should set names and avatars explicitly for DM portals. # This is only necessary when using clients that don't support MSC4171. private_chat_portal_meta: false @@ -97,12 +99,12 @@ bridge: relay: # Whether relay mode should be allowed. If allowed, the set-relay command can be used to turn any # authenticated user into a relaybot for that chat. - enabled: {{ matrix_mautrix_meta_instagram_bridge_relay_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_meta_instagram_bridge_relay_enabled | to_json }} # Should only admins be allowed to set themselves as relay users? # If true, non-admins can only set users listed in default_relays as relays in a room. - admin_only: {{ matrix_mautrix_meta_instagram_bridge_relay_admin_only | to_json }} + admin_only: {{ matrix_bridge_mautrix_meta_instagram_bridge_relay_admin_only | to_json }} # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. - default_relays: {{ matrix_mautrix_meta_instagram_bridge_relay_default_relays | to_json }} + default_relays: {{ matrix_bridge_mautrix_meta_instagram_bridge_relay_default_relays | to_json }} # The formats to use when sending messages via the relaybot. # Available variables: # .Sender.UserID - The Matrix user ID of the sender. @@ -138,18 +140,18 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_meta_instagram_bridge_permissions | to_json }} + permissions: {{ matrix_bridge_mautrix_meta_instagram_bridge_permissions | to_json }} # Config for the bridge's database. database: # The database type. "sqlite3-fk-wal" and "postgres" are supported. - type: {{ matrix_mautrix_meta_instagram_appservice_database_type | to_json }} + type: {{ matrix_bridge_mautrix_meta_instagram_appservice_database_type | to_json }} # The database URI. # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. # https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_mautrix_meta_instagram_appservice_database_uri | to_json }} + uri: {{ matrix_bridge_mautrix_meta_instagram_appservice_database_uri | to_json }} # Maximum number of connections. max_open_conns: 5 max_idle_conns: 1 @@ -163,9 +165,9 @@ homeserver: # The address that this appservice can use to connect to the homeserver. # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, # but https also works if they run on different machines. - address: {{ matrix_mautrix_meta_instagram_homeserver_address | to_json }} + address: {{ matrix_bridge_mautrix_meta_instagram_homeserver_address | to_json }} # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: {{ matrix_mautrix_meta_instagram_homeserver_domain | to_json }} + domain: {{ matrix_bridge_mautrix_meta_instagram_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -181,7 +183,7 @@ homeserver: # The bridge will use the appservice as_token to authorize requests. message_send_checkpoint_endpoint: # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_mautrix_meta_instagram_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_mautrix_meta_instagram_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -194,10 +196,10 @@ homeserver: # Changing these values requires regeneration of the registration (except when noted otherwise) appservice: # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_mautrix_meta_instagram_appservice_address | to_json }} + address: {{ matrix_bridge_mautrix_meta_instagram_appservice_address | to_json }} # A public address that external services can use to reach this appservice. # This value doesn't affect the registration file. - public_address: https://bridge.example.com + public_address: {{ matrix_bridge_mautrix_meta_instagram_bridge_public_address | to_json }} # The hostname and port where this appservice should listen. # For Docker, you generally have to change the hostname to 0.0.0.0. @@ -205,15 +207,15 @@ appservice: port: 29319 # The unique ID of this appservice. - id: {{ matrix_mautrix_meta_instagram_appservice_id | to_json }} + id: {{ matrix_bridge_mautrix_meta_instagram_appservice_id | to_json }} # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_mautrix_meta_instagram_appservice_username | to_json }} + username: {{ matrix_bridge_mautrix_meta_instagram_appservice_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. - displayname: {{ matrix_mautrix_meta_instagram_appservice_displayname | to_json(ensure_ascii=False) }} - avatar: {{ matrix_mautrix_meta_instagram_appservice_avatar | to_json }} + displayname: {{ matrix_bridge_mautrix_meta_instagram_appservice_displayname | to_json(ensure_ascii=False) }} + avatar: {{ matrix_bridge_mautrix_meta_instagram_appservice_avatar | to_json }} # Whether to receive ephemeral events via appservice transactions. ephemeral_events: true @@ -224,12 +226,12 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_mautrix_meta_instagram_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_meta_instagram_homeserver_token | to_json }} + as_token: {{ matrix_bridge_mautrix_meta_instagram_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_meta_instagram_homeserver_token | to_json }} # Localpart template of MXIDs for remote users. # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. - username_template: {{ matrix_mautrix_meta_instagram_bridge_username_template | to_json }} + username_template: {{ matrix_bridge_mautrix_meta_instagram_bridge_username_template | to_json }} # Config options that affect the Matrix connector of the bridge. matrix: @@ -243,7 +245,7 @@ matrix: sync_direct_chat_list: false # Whether created rooms should have federation enabled. If false, created portal rooms # will never be federated. Changing this option requires recreating rooms. - federate_rooms: {{ matrix_mautrix_meta_instagram_bridge_federate_rooms | to_json }} + federate_rooms: {{ matrix_bridge_mautrix_meta_instagram_bridge_federate_rooms | to_json }} # The threshold as bytes after which the bridge should roundtrip uploads via the disk # rather than keeping the whole file in memory. upload_file_threshold: 5242880 @@ -263,7 +265,7 @@ provisioning: prefix: /_matrix/provision # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, # or if set to "disable", the provisioning API will be disabled. - shared_secret: {{ matrix_mautrix_meta_instagram_provisioning_shared_secret | to_json }} + shared_secret: {{ matrix_bridge_mautrix_meta_instagram_provisioning_shared_secret | to_json }} # Whether to allow provisioning API requests to be authed using Matrix access tokens. # This follows the same rules as double puppeting to determine which server to contact to check the token, # which means that by default, it only works for users on the same server as the bridge. @@ -279,7 +281,7 @@ public_media: enabled: false # A key for signing public media URLs. # If set to "generate", a random key will be generated. - signing_key: {{ matrix_mautrix_meta_instagram_public_media_signing_key | to_json }} + signing_key: {{ matrix_bridge_mautrix_meta_instagram_public_media_signing_key | to_json }} # Number of seconds that public media URLs are valid for. # If set to 0, URLs will never expire. expiry: 0 @@ -313,18 +315,18 @@ direct_media: # See https://docs.mau.fi/bridges/general/backfill.html for more details. backfill: # Whether to do backfilling at all. - enabled: {{ matrix_mautrix_meta_instagram_backfill_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_meta_instagram_backfill_enabled | to_json }} # Maximum number of messages to backfill in empty rooms. - max_initial_messages: {{ matrix_mautrix_meta_instagram_backfill_max_initial_messages | to_json}} + max_initial_messages: {{ matrix_bridge_mautrix_meta_instagram_backfill_max_initial_messages | to_json}} # Maximum number of missed messages to backfill after bridge restarts. - max_catchup_messages: {{ matrix_mautrix_meta_instagram_backfill_max_catchup_messages | to_json }} + max_catchup_messages: {{ matrix_bridge_mautrix_meta_instagram_backfill_max_catchup_messages | to_json }} # If a backfilled chat is older than this number of hours, # mark it as read even if it's unread on the remote network. - unread_hours_threshold: {{ matrix_mautrix_meta_instagram_backfill_unread_hours_threshold | to_json }} + unread_hours_threshold: {{ matrix_bridge_mautrix_meta_instagram_backfill_unread_hours_threshold | to_json }} # Settings for backfilling threads within other backfills. threads: # Maximum number of messages to backfill in a new thread. - max_initial_messages: {{ matrix_mautrix_meta_instagram_backfill_threads_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_mautrix_meta_instagram_backfill_threads_max_initial_messages | to_json }} # Settings for the backwards backfill queue. This only applies when connecting to # Beeper as standard Matrix servers don't support inserting messages into history. queue: @@ -352,32 +354,32 @@ double_puppet: allow_discovery: false # Shared secrets for automatic double puppeting. # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. - secrets: {{ matrix_mautrix_meta_instagram_double_puppet_secrets | to_json }} + secrets: {{ matrix_bridge_mautrix_meta_instagram_double_puppet_secrets | to_json }} # End-to-bridge encryption support options. # # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. - allow: {{ matrix_mautrix_meta_instagram_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_mautrix_meta_instagram_bridge_encryption_allow | to_json }} # Whether to force-enable encryption in all bridged rooms. - default: {{ matrix_mautrix_meta_instagram_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_mautrix_meta_instagram_bridge_encryption_default | to_json }} # Whether to require all messages to be encrypted and drop any unencrypted messages. - require: {{ matrix_mautrix_meta_instagram_bridge_encryption_require | to_json }} + require: {{ matrix_bridge_mautrix_meta_instagram_bridge_encryption_require | to_json }} # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. # This option is not yet compatible with standard Matrix servers like Synapse and should not be used. - appservice: {{ matrix_mautrix_meta_instagram_bridge_encryption_appservice | to_json }} + appservice: {{ matrix_bridge_mautrix_meta_instagram_bridge_encryption_appservice | to_json }} # Whether to use MSC4190 instead of appservice login to create the bridge bot device. # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_mautrix_meta_instagram_msc4190_enabled | to_json }} + msc4190: {{ matrix_bridge_mautrix_meta_instagram_msc4190_enabled | to_json }} # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) # Requires msc4190 to replace keys on reset - self_sign: {{ matrix_mautrix_meta_instagram_self_sign_enabled | to_json }} + self_sign: {{ matrix_bridge_mautrix_meta_instagram_self_sign_enabled | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_mautrix_meta_instagram_bridge_encryption_allow_key_sharing | to_json }} + allow_key_sharing: {{ matrix_bridge_mautrix_meta_instagram_bridge_encryption_allow_key_sharing | to_json }} # Pickle key for encrypting encryption keys in the bridge database. # If set to generate, a random key will be generated. pickle_key: mautrix.bridge.e2ee @@ -439,7 +441,7 @@ encryption: # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_mautrix_meta_instagram_logging_min_level | to_json }} + min_level: {{ matrix_bridge_mautrix_meta_instagram_logging_min_level | to_json }} writers: - type: stdout format: pretty diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/labels.j2 index 42ba3e6a7..5cfcfc677 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/labels.j2 @@ -4,51 +4,48 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_meta_instagram_container_labels_traefik_enabled and matrix_mautrix_meta_instagram_container_labels_metrics_enabled %} +{% if matrix_bridge_mautrix_meta_instagram_container_labels_traefik_enabled and matrix_bridge_mautrix_meta_instagram_container_labels_exposure_enabled %} traefik.enable=true -{% if matrix_mautrix_meta_instagram_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_meta_instagram_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_meta_instagram_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_meta_instagram_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.{{ matrix_mautrix_meta_instagram_identifier }}-appservice.loadbalancer.server.port=29319 -traefik.http.services.{{ matrix_mautrix_meta_instagram_identifier }}-metrics.loadbalancer.server.port=8000 - +{% if matrix_bridge_mautrix_meta_instagram_container_labels_exposure_enabled %} +traefik.http.services.{{ matrix_bridge_mautrix_meta_instagram_identifier }}-appservice.loadbalancer.server.port=29319 +{% endif %} -{% if matrix_mautrix_meta_instagram_container_labels_metrics_enabled %} +{% if matrix_bridge_mautrix_meta_instagram_container_labels_exposure_enabled %} ############################################################ # # -# Metrics # +# Bridge API exposure # # # ############################################################ -{% if matrix_mautrix_meta_instagram_container_labels_metrics_middleware_basic_auth_enabled %} -traefik.http.middlewares.{{ matrix_mautrix_meta_instagram_identifier }}-metrics-basic-auth.basicauth.users={{ matrix_mautrix_meta_instagram_container_labels_metrics_middleware_basic_auth_users }} -traefik.http.routers.{{ matrix_mautrix_meta_instagram_identifier }}-metrics.middlewares={{ matrix_mautrix_meta_instagram_identifier }}-metrics-basic-auth -{% endif %} +traefik.http.middlewares.{{ matrix_bridge_mautrix_meta_instagram_identifier }}-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_meta_instagram_exposure_path_prefix }} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_instagram_identifier }}-exposure.middlewares={{ matrix_bridge_mautrix_meta_instagram_identifier }}-exposure-strip-prefix -traefik.http.routers.{{ matrix_mautrix_meta_instagram_identifier }}-metrics.rule={{ matrix_mautrix_meta_instagram_container_labels_metrics_traefik_rule }} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_instagram_identifier }}-exposure.rule={{ matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_rule }} -{% if matrix_mautrix_meta_instagram_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.{{ matrix_mautrix_meta_instagram_identifier }}-metrics.priority={{ matrix_mautrix_meta_instagram_container_labels_metrics_traefik_priority }} +{% if matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_instagram_identifier }}-exposure.priority={{ matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_priority }} {% endif %} -traefik.http.routers.{{ matrix_mautrix_meta_instagram_identifier }}-metrics.service={{ matrix_mautrix_meta_instagram_identifier }}-metrics -traefik.http.routers.{{ matrix_mautrix_meta_instagram_identifier }}-metrics.entrypoints={{ matrix_mautrix_meta_instagram_container_labels_metrics_traefik_entrypoints }} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_instagram_identifier }}-exposure.service={{ matrix_bridge_mautrix_meta_instagram_identifier }}-appservice +traefik.http.routers.{{ matrix_bridge_mautrix_meta_instagram_identifier }}-exposure.entrypoints={{ matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_entrypoints }} -traefik.http.routers.{{ matrix_mautrix_meta_instagram_identifier }}-metrics.tls={{ matrix_mautrix_meta_instagram_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_mautrix_meta_instagram_container_labels_metrics_traefik_tls %} -traefik.http.routers.{{ matrix_mautrix_meta_instagram_identifier }}-metrics.tls.certResolver={{ matrix_mautrix_meta_instagram_container_labels_metrics_traefik_tls_certResolver }} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_instagram_identifier }}-exposure.tls={{ matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_tls %} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_instagram_identifier }}-exposure.tls.certResolver={{ matrix_bridge_mautrix_meta_instagram_container_labels_exposure_traefik_tls_certResolver }} {% endif %} ############################################################ # # -# /Metrics # +# /Bridge API exposure # # # ############################################################ {% endif %} - {% endif %} -{{ matrix_mautrix_meta_instagram_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_meta_instagram_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/systemd/matrix-mautrix-meta-instagram.service.j2 b/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/systemd/matrix-mautrix-meta-instagram.service.j2 new file mode 100644 index 000000000..824c9401a --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/systemd/matrix-mautrix-meta-instagram.service.j2 @@ -0,0 +1,53 @@ +#jinja2: lstrip_blocks: True +[Unit] +Description=mautrix-meta bridge ({{ matrix_bridge_mautrix_meta_instagram_identifier }}) +{% for service in matrix_bridge_mautrix_meta_instagram_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_bridge_mautrix_meta_instagram_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_bridge_mautrix_meta_instagram_identifier }} 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_bridge_mautrix_meta_instagram_identifier }} 2>/dev/null || true' + +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ + --rm \ + --name={{ matrix_bridge_mautrix_meta_instagram_identifier }} \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --network={{ matrix_bridge_mautrix_meta_instagram_container_network }} \ + {% if matrix_bridge_mautrix_meta_instagram_container_http_host_bind_port %} + -p {{ matrix_bridge_mautrix_meta_instagram_container_http_host_bind_port }}:29319 \ + {% endif %} + --mount type=bind,src={{ matrix_bridge_mautrix_meta_instagram_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_meta_instagram_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_meta_instagram_base_path }}/labels \ + {% for arg in matrix_bridge_mautrix_meta_instagram_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_bridge_mautrix_meta_instagram_container_image }} \ + {{ matrix_bridge_mautrix_meta_instagram_container_binary_path }} -c /config/config.yaml -r /config/registration.yaml --no-update + +{% if matrix_bridge_mautrix_meta_instagram_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_meta_instagram_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_bridge_mautrix_meta_instagram_identifier }} +{% endfor %} +{% endif %} + +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_bridge_mautrix_meta_instagram_identifier }} + +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_bridge_mautrix_meta_instagram_identifier }} 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_bridge_mautrix_meta_instagram_identifier }} 2>/dev/null || true' +Restart=always +RestartSec=30 +SyslogIdentifier={{ matrix_bridge_mautrix_meta_instagram_identifier }} + +[Install] +WantedBy=multi-user.target diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/systemd/matrix-mautrix-meta.service.j2.license b/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/systemd/matrix-mautrix-meta-instagram.service.j2.license similarity index 100% rename from roles/custom/matrix-bridge-mautrix-meta-instagram/templates/systemd/matrix-mautrix-meta.service.j2.license rename to roles/custom/matrix-bridge-mautrix-meta-instagram/templates/systemd/matrix-mautrix-meta-instagram.service.j2.license diff --git a/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/systemd/matrix-mautrix-meta.service.j2 b/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/systemd/matrix-mautrix-meta.service.j2 deleted file mode 100644 index e9fc2eccb..000000000 --- a/roles/custom/matrix-bridge-mautrix-meta-instagram/templates/systemd/matrix-mautrix-meta.service.j2 +++ /dev/null @@ -1,51 +0,0 @@ -#jinja2: lstrip_blocks: True -[Unit] -Description=mautrix-meta bridge ({{ matrix_mautrix_meta_instagram_identifier }}) -{% for service in matrix_mautrix_meta_instagram_systemd_required_services_list %} -Requires={{ service }} -After={{ service }} -{% endfor %} -{% for service in matrix_mautrix_meta_instagram_systemd_wanted_services_list %} -Wants={{ service }} -{% endfor %} -DefaultDependencies=no - -[Service] -Type=simple -Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_mautrix_meta_instagram_identifier }} 2>/dev/null || true' -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_mautrix_meta_instagram_identifier }} 2>/dev/null || true' - -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ - --rm \ - --name={{ matrix_mautrix_meta_instagram_identifier }} \ - --log-driver=none \ - --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ - --cap-drop=ALL \ - --network={{ matrix_mautrix_meta_instagram_container_network }} \ - {% if matrix_mautrix_meta_instagram_container_http_host_bind_port %} - -p {{ matrix_mautrix_meta_instagram_container_http_host_bind_port }}:29319 \ - {% endif %} - --mount type=bind,src={{ matrix_mautrix_meta_instagram_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_mautrix_meta_instagram_data_path }},dst=/data \ - --label-file={{ matrix_mautrix_meta_instagram_base_path }}/labels \ - {% for arg in matrix_mautrix_meta_instagram_container_extra_arguments %} - {{ arg }} \ - {% endfor %} - {{ matrix_mautrix_meta_instagram_container_image }} \ - /usr/bin/mautrix-meta -c /config/config.yaml -r /config/registration.yaml --no-update - -{% for network in matrix_mautrix_meta_instagram_container_additional_networks %} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_mautrix_meta_instagram_identifier }} -{% endfor %} - -ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_mautrix_meta_instagram_identifier }} - -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_mautrix_meta_instagram_identifier }} 2>/dev/null || true' -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_mautrix_meta_instagram_identifier }} 2>/dev/null || true' -Restart=always -RestartSec=30 -SyslogIdentifier={{ matrix_mautrix_meta_instagram_identifier }} - -[Install] -WantedBy=multi-user.target diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/defaults/main.yml index 6c2f79a5a..ca2279132 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-messenger/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/defaults/main.yml @@ -7,308 +7,284 @@ --- -# mautrix-meta is a Matrix <-> Facebook/Messenger/Instagram bridge +# mautrix-meta is a Matrix <-> Facebook/Messenger bridge # Project source code URL: https://github.com/mautrix/meta # -# WARNING: this bridge role is used for both Messenger and Instagram. -# This Messenger role acts as a source and auto-generates matrix-bridge-mautrix-meta-instagram -# thanks to `just rebuild-mautrix-meta-instagram` (`bin/rebuild-mautrix-meta-instagram.sh`). -# If you'd like to make changes to the Instagram role, consider making your changes to the Messenger role instead. +# Since v26.07, upstream ships the Instagram side of mautrix-meta as a separate binary and a separate container image. +# It is covered by the matrix-bridge-mautrix-meta-instagram role. -matrix_mautrix_meta_messenger_enabled: true +matrix_bridge_mautrix_meta_messenger_enabled: true -matrix_mautrix_meta_messenger_identifier: matrix-mautrix-meta-messenger +matrix_bridge_mautrix_meta_messenger_identifier: matrix-mautrix-meta-messenger # renovate: datasource=docker depName=dock.mau.dev/mautrix/meta -matrix_mautrix_meta_messenger_version: v0.2602.0 - -matrix_mautrix_meta_messenger_base_path: "{{ matrix_base_data_path }}/mautrix-meta-messenger" -matrix_mautrix_meta_messenger_config_path: "{{ matrix_mautrix_meta_messenger_base_path }}/config" -matrix_mautrix_meta_messenger_data_path: "{{ matrix_mautrix_meta_messenger_base_path }}/data" -matrix_mautrix_meta_messenger_container_src_files_path: "{{ matrix_mautrix_meta_messenger_base_path }}/container-src" - -matrix_mautrix_meta_messenger_container_image_self_build: false -matrix_mautrix_meta_messenger_container_image_self_build_repo: "https://github.com/mautrix/meta.git" - -matrix_mautrix_meta_messenger_container_image: "{{ matrix_mautrix_meta_messenger_container_image_registry_prefix }}mautrix/meta:{{ matrix_mautrix_meta_messenger_container_image_tag }}" -matrix_mautrix_meta_messenger_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_meta_messenger_container_image_self_build else matrix_mautrix_meta_messenger_container_image_registry_prefix_upstream }}" -matrix_mautrix_meta_messenger_container_image_registry_prefix_upstream: "{{ matrix_mautrix_meta_messenger_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_meta_messenger_container_image_registry_prefix_upstream_default: "dock.mau.dev/" +matrix_bridge_mautrix_meta_messenger_version: v0.2608.0 + +matrix_bridge_mautrix_meta_messenger_base_path: "{{ matrix_base_data_path }}/mautrix-meta-messenger" +matrix_bridge_mautrix_meta_messenger_config_path: "{{ matrix_bridge_mautrix_meta_messenger_base_path }}/config" +matrix_bridge_mautrix_meta_messenger_data_path: "{{ matrix_bridge_mautrix_meta_messenger_base_path }}/data" +matrix_bridge_mautrix_meta_messenger_container_src_files_path: "{{ matrix_bridge_mautrix_meta_messenger_base_path }}/container-src" + +matrix_bridge_mautrix_meta_messenger_container_image_self_build: false +matrix_bridge_mautrix_meta_messenger_container_image_self_build_repo: "https://github.com/mautrix/meta.git" + +matrix_bridge_mautrix_meta_messenger_container_image: "{{ matrix_bridge_mautrix_meta_messenger_container_image_registry_prefix }}mautrix/meta:{{ matrix_bridge_mautrix_meta_messenger_container_image_tag }}" +matrix_bridge_mautrix_meta_messenger_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_meta_messenger_container_image_self_build else matrix_bridge_mautrix_meta_messenger_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_meta_messenger_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_meta_messenger_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_meta_messenger_container_image_registry_prefix_upstream_default: "dock.mau.dev/" +# Since v26.07, Instagram is a separate bridge upstream (its own binary and its own container image), +# handled by the matrix-bridge-mautrix-meta-instagram role. +# Both bridges are published to the same container image repository, with Instagram's tags carrying an `ig-` prefix, +# so an `ig-` prefix on a tag here would mean this role had pulled the other bridge's image. +# See: https://mau.fi/blog/2026-07-mautrix-release/#new-instagram-bridge +# # Prebuilt container images for specific commit hashes are tagged with an architecture suffix (e.g. `HASH-amd64`). -matrix_mautrix_meta_messenger_container_image_tag: "{{ matrix_mautrix_meta_messenger_version }}{{ ('-' ~ matrix_architecture) if (matrix_mautrix_meta_messenger_version | length == 40) else '' }}" -matrix_mautrix_meta_messenger_container_image_force_pull: "{{ matrix_mautrix_meta_messenger_container_image.endswith(':latest') }}" +matrix_bridge_mautrix_meta_messenger_container_image_tag: "{{ matrix_bridge_mautrix_meta_messenger_version }}{{ ('-' ~ matrix_architecture) if (matrix_bridge_mautrix_meta_messenger_version | length == 40) else '' }}" -matrix_mautrix_meta_messenger_container_network: "" +matrix_bridge_mautrix_meta_messenger_container_network: "" -matrix_mautrix_meta_messenger_container_additional_networks: "{{ matrix_mautrix_meta_messenger_container_additional_networks_auto + matrix_mautrix_meta_messenger_container_additional_networks_custom }}" -matrix_mautrix_meta_messenger_container_additional_networks_auto: [] -matrix_mautrix_meta_messenger_container_additional_networks_custom: [] +matrix_bridge_mautrix_meta_messenger_container_additional_networks: "{{ matrix_bridge_mautrix_meta_messenger_container_additional_networks_auto + matrix_bridge_mautrix_meta_messenger_container_additional_networks_custom }}" +matrix_bridge_mautrix_meta_messenger_container_additional_networks_auto: [] +matrix_bridge_mautrix_meta_messenger_container_additional_networks_custom: [] -# matrix_mautrix_meta_messenger_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_mautrix_meta_messenger_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_meta_messenger_container_labels_additional_labels`. -matrix_mautrix_meta_messenger_container_labels_traefik_enabled: true -matrix_mautrix_meta_messenger_container_labels_traefik_docker_network: "{{ matrix_mautrix_meta_messenger_container_network }}" -matrix_mautrix_meta_messenger_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_meta_messenger_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose the bridge's metrics -matrix_mautrix_meta_messenger_container_labels_metrics_enabled: "{{ matrix_mautrix_meta_messenger_metrics_enabled and matrix_mautrix_meta_messenger_metrics_proxying_enabled }}" -matrix_mautrix_meta_messenger_container_labels_metrics_traefik_rule: "Host(`{{ matrix_mautrix_meta_messenger_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_mautrix_meta_messenger_metrics_proxying_path_prefix }}`)" -matrix_mautrix_meta_messenger_container_labels_metrics_traefik_priority: 0 -matrix_mautrix_meta_messenger_container_labels_metrics_traefik_entrypoints: "{{ matrix_mautrix_meta_messenger_container_labels_traefik_entrypoints }}" -matrix_mautrix_meta_messenger_container_labels_metrics_traefik_tls: "{{ matrix_mautrix_meta_messenger_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_mautrix_meta_messenger_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_mautrix_meta_messenger_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_mautrix_meta_messenger_container_labels_metrics_middleware_basic_auth_enabled: false -# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_mautrix_meta_messenger_container_labels_metrics_middleware_basic_auth_users: '' - -# matrix_mautrix_meta_messenger_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# To inject your own other container labels, see `matrix_bridge_mautrix_meta_messenger_container_labels_additional_labels`. +matrix_bridge_mautrix_meta_messenger_container_labels_traefik_enabled: true +matrix_bridge_mautrix_meta_messenger_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_meta_messenger_container_network }}" +matrix_bridge_mautrix_meta_messenger_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_meta_messenger_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-meta-messenger's HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_meta_messenger_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_meta_messenger_exposure_enabled }}" +matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_meta_messenger_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_meta_messenger_exposure_path_prefix }}`)" +matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_meta_messenger_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_meta_messenger_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_meta_messenger_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_meta_messenger_container_labels_additional_labels: | +# matrix_bridge_mautrix_meta_messenger_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_meta_messenger_container_labels_additional_labels: '' +matrix_bridge_mautrix_meta_messenger_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_meta_messenger_container_extra_arguments: [] +matrix_bridge_mautrix_meta_messenger_container_extra_arguments: [] # List of systemd services that the systemd service depends on. -matrix_mautrix_meta_messenger_systemd_required_services_list: "{{ matrix_mautrix_meta_messenger_systemd_required_services_list_default + matrix_mautrix_meta_messenger_systemd_required_services_list_auto + matrix_mautrix_meta_messenger_systemd_required_services_list_custom }}" -matrix_mautrix_meta_messenger_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_meta_messenger_systemd_required_services_list_auto: [] -matrix_mautrix_meta_messenger_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_meta_messenger_systemd_required_services_list: "{{ matrix_bridge_mautrix_meta_messenger_systemd_required_services_list_default + matrix_bridge_mautrix_meta_messenger_systemd_required_services_list_auto + matrix_bridge_mautrix_meta_messenger_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_meta_messenger_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_meta_messenger_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_meta_messenger_systemd_required_services_list_custom: [] # List of systemd services that the systemd service wants -matrix_mautrix_meta_messenger_systemd_wanted_services_list: [] +matrix_bridge_mautrix_meta_messenger_systemd_wanted_services_list: [] # Controls whether the bridge container exposes its HTTP port. # # Takes an ":" or "" value (e.g. "127.0.0.1:29319"), or empty string to not expose. -matrix_mautrix_meta_messenger_container_http_host_bind_port: '' +matrix_bridge_mautrix_meta_messenger_container_http_host_bind_port: '' # Database-related configuration fields -matrix_mautrix_meta_messenger_database_engine: sqlite3-fk-wal +matrix_bridge_mautrix_meta_messenger_database_engine: sqlite3-fk-wal -matrix_mautrix_meta_messenger_sqlite_database_path_local: "{{ matrix_mautrix_meta_messenger_data_path }}/mautrix-meta.db" -matrix_mautrix_meta_messenger_sqlite_database_path_in_container: "/data/mautrix-meta.db" +matrix_bridge_mautrix_meta_messenger_sqlite_database_path_local: "{{ matrix_bridge_mautrix_meta_messenger_data_path }}/mautrix-meta.db" +matrix_bridge_mautrix_meta_messenger_sqlite_database_path_in_container: "/data/mautrix-meta.db" -matrix_mautrix_meta_messenger_database_suffix: |- +matrix_bridge_mautrix_meta_messenger_database_suffix: |- {{ ({ 'facebook': '_facebook', 'facebook-tor': '_facebook', 'messenger': '_messenger', - 'instagram': '_instagram', - })[matrix_mautrix_meta_messenger_meta_mode] + })[matrix_bridge_mautrix_meta_messenger_meta_mode] }} -matrix_mautrix_meta_messenger_database_username: "matrix_mautrix_meta{{ matrix_mautrix_meta_messenger_database_suffix }}" -matrix_mautrix_meta_messenger_database_password: '' -matrix_mautrix_meta_messenger_database_hostname: '' -matrix_mautrix_meta_messenger_database_port: 5432 -matrix_mautrix_meta_messenger_database_name: "matrix_mautrix_meta{{ matrix_mautrix_meta_messenger_database_suffix }}" -matrix_mautrix_meta_messenger_database_sslmode: disable +matrix_bridge_mautrix_meta_messenger_database_username: "matrix_mautrix_meta{{ matrix_bridge_mautrix_meta_messenger_database_suffix }}" +matrix_bridge_mautrix_meta_messenger_database_password: '' +matrix_bridge_mautrix_meta_messenger_database_hostname: '' +matrix_bridge_mautrix_meta_messenger_database_port: 5432 +matrix_bridge_mautrix_meta_messenger_database_name: "matrix_mautrix_meta{{ matrix_bridge_mautrix_meta_messenger_database_suffix }}" +matrix_bridge_mautrix_meta_messenger_database_sslmode: disable -matrix_mautrix_meta_messenger_database_connection_string: 'postgres://{{ matrix_mautrix_meta_messenger_database_username }}:{{ matrix_mautrix_meta_messenger_database_password }}@{{ matrix_mautrix_meta_messenger_database_hostname }}:{{ matrix_mautrix_meta_messenger_database_port }}/{{ matrix_mautrix_meta_messenger_database_name }}?sslmode={{ matrix_mautrix_meta_messenger_database_sslmode }}' +matrix_bridge_mautrix_meta_messenger_database_connection_string: 'postgres://{{ matrix_bridge_mautrix_meta_messenger_database_username }}:{{ matrix_bridge_mautrix_meta_messenger_database_password }}@{{ matrix_bridge_mautrix_meta_messenger_database_hostname }}:{{ matrix_bridge_mautrix_meta_messenger_database_port }}/{{ matrix_bridge_mautrix_meta_messenger_database_name }}?sslmode={{ matrix_bridge_mautrix_meta_messenger_database_sslmode }}' -matrix_mautrix_meta_messenger_homeserver_address: "" -matrix_mautrix_meta_messenger_homeserver_domain: '{{ matrix_domain }}' +matrix_bridge_mautrix_meta_messenger_homeserver_address: "" +matrix_bridge_mautrix_meta_messenger_homeserver_domain: '{{ matrix_domain }}' # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_mautrix_meta_messenger_homeserver_async_media: false -matrix_mautrix_meta_messenger_homeserver_token: '' +matrix_bridge_mautrix_meta_messenger_homeserver_async_media: false +matrix_bridge_mautrix_meta_messenger_homeserver_token: '' + +matrix_bridge_mautrix_meta_messenger_appservice_address: "http://{{ matrix_bridge_mautrix_meta_messenger_identifier }}:29319" -matrix_mautrix_meta_messenger_appservice_address: "http://{{ matrix_mautrix_meta_messenger_identifier }}:29319" +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_meta_messenger_bridge_public_address`). +matrix_bridge_mautrix_meta_messenger_scheme: https -matrix_mautrix_meta_messenger_appservice_id: "{{ matrix_mautrix_meta_messenger_meta_mode }}" +# The public base URL at which this bridge's HTTP API is reachable from outside (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_meta_messenger_bridge_public_address: "{{ (matrix_bridge_mautrix_meta_messenger_scheme + '://' + matrix_bridge_mautrix_meta_messenger_exposure_hostname + matrix_bridge_mautrix_meta_messenger_exposure_path_prefix) if matrix_bridge_mautrix_meta_messenger_exposure_enabled else '' }}" -matrix_mautrix_meta_messenger_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" -matrix_mautrix_meta_messenger_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" +matrix_bridge_mautrix_meta_messenger_appservice_id: "{{ matrix_bridge_mautrix_meta_messenger_meta_mode }}" -# For Facebook/Messenger, we use the same `@messengerbot:example.com` username regardless of how bridging happens for multiple reasons: +matrix_bridge_mautrix_meta_messenger_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_meta_messenger_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" + +# We use the same `@messengerbot:example.com` username regardless of how bridging happens for multiple reasons: # - it's consistent - regardless of how bridging happens, the bridged service is actually Messenger # - it's easy for users - you may change the mode, but the bot is always at `@messengerbot:example.com` # - it doesn't conflict with mautrix-facebook which uses `@facebookbot:example.com` -# - `matrix_mautrix_meta_messenger_appservice_avatar` only has icons for Messenger and Instagram, not Facebook -matrix_mautrix_meta_messenger_appservice_username_prefix: |- - {{ - ({ - 'facebook': 'messenger', - 'facebook-tor': 'messenger', - 'messenger': 'messenger', - 'instagram': 'instagram', - })[matrix_mautrix_meta_messenger_meta_mode] - }} -matrix_mautrix_meta_messenger_appservice_username: "{{ matrix_mautrix_meta_messenger_appservice_username_prefix }}bot" -matrix_mautrix_meta_messenger_appservice_displayname: "{{ matrix_mautrix_meta_messenger_meta_mode | capitalize }} bridge bot" -matrix_mautrix_meta_messenger_appservice_avatar: "{{ 'mxc://maunium.net/JxjlbZUlCPULEeHZSwleUXQv' if matrix_mautrix_meta_messenger_meta_mode == 'instagram' else 'mxc://maunium.net/ygtkteZsXnGJLJHRchUwYWak' }}" +# - `matrix_bridge_mautrix_meta_messenger_appservice_avatar` only has an icon for Messenger, not Facebook +matrix_bridge_mautrix_meta_messenger_appservice_username: messengerbot +matrix_bridge_mautrix_meta_messenger_appservice_displayname: "{{ matrix_bridge_mautrix_meta_messenger_meta_mode | capitalize }} bridge bot" +matrix_bridge_mautrix_meta_messenger_appservice_avatar: mxc://maunium.net/ygtkteZsXnGJLJHRchUwYWak -matrix_mautrix_meta_messenger_appservice_database_type: "{{ matrix_mautrix_meta_messenger_database_engine }}" +matrix_bridge_mautrix_meta_messenger_appservice_database_type: "{{ matrix_bridge_mautrix_meta_messenger_database_engine }}" -matrix_mautrix_meta_messenger_appservice_database_uri: |- +matrix_bridge_mautrix_meta_messenger_appservice_database_uri: |- {{ { - 'sqlite3-fk-wal': ('sqlite:///' + matrix_mautrix_meta_messenger_sqlite_database_path_in_container), - 'postgres': matrix_mautrix_meta_messenger_database_connection_string, - }[matrix_mautrix_meta_messenger_database_engine] + 'sqlite3-fk-wal': matrix_bridge_mautrix_meta_messenger_sqlite_database_path_in_container, + 'postgres': matrix_bridge_mautrix_meta_messenger_database_connection_string, + }[matrix_bridge_mautrix_meta_messenger_database_engine] }} -matrix_mautrix_meta_messenger_appservice_token: '' +matrix_bridge_mautrix_meta_messenger_appservice_token: '' -# Controls which service this bridge is for. +# Controls how the bridge connects to Messenger. # Valid options: # * facebook - connect to FB Messenger via facebook.com # * facebook-tor - connect to FB Messenger via facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion # (note: does not currently proxy media downloads) # * messenger - connect to FB Messenger via messenger.com (can be used with the facebook side deactivated) -# * instagram - connect to Instagram DMs via instagram.com -matrix_mautrix_meta_messenger_meta_mode: messenger - -# When in `instagram` mode (see `matrix_mautrix_meta_messenger_meta_mode`), should the bridge connect to WhatsApp servers for encrypted chats? -matrix_mautrix_meta_messenger_meta_ig_e2ee: false - -matrix_mautrix_meta_messenger_provisioning_shared_secret: disable +# +# Since v0.2608.0, the bridge itself no longer has a `mode` configuration option. +# This variable controls playbook-level naming (database name, bridged user prefix, command prefix, etc.) and whether the bridge's `tor` configuration option gets enabled (for `facebook-tor`). +# Bridging to Instagram is done by the separate matrix-bridge-mautrix-meta-instagram role. +matrix_bridge_mautrix_meta_messenger_meta_mode: messenger -# Whether or not metrics endpoint should be enabled. -# Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_mautrix_meta_messenger_metrics_proxying_enabled`. -matrix_mautrix_meta_messenger_metrics_enabled: false +matrix_bridge_mautrix_meta_messenger_provisioning_shared_secret: disable -# Controls whether metrics should be exposed on a public URL. -matrix_mautrix_meta_messenger_metrics_proxying_enabled: false -matrix_mautrix_meta_messenger_metrics_proxying_hostname: '' -matrix_mautrix_meta_messenger_metrics_proxying_path_prefix: '' +# Controls whether mautrix-meta-messenger's HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_meta_messenger_exposure_enabled: false +matrix_bridge_mautrix_meta_messenger_exposure_hostname: '' +matrix_bridge_mautrix_meta_messenger_exposure_path_prefix: '' -matrix_mautrix_meta_messenger_bridge_username_prefix: |- +matrix_bridge_mautrix_meta_messenger_bridge_username_prefix: |- {{ ({ 'facebook': 'facebook_', 'facebook-tor': 'facebook_', 'messenger': 'messenger_', - 'instagram': 'instagram_', - })[matrix_mautrix_meta_messenger_meta_mode] + })[matrix_bridge_mautrix_meta_messenger_meta_mode] }} -# Localpart template of MXIDs for FB/IG users. -# {{.}} is replaced with the internal ID of the FB/IG user. +# Localpart template of MXIDs for FB users. +# {{.}} is replaced with the internal ID of the FB user. # Changing this may require that you change the regex in the appservice. -matrix_mautrix_meta_messenger_bridge_username_template: "{{ matrix_mautrix_meta_messenger_bridge_username_prefix + '{{.}}' }}" +matrix_bridge_mautrix_meta_messenger_bridge_username_template: "{{ matrix_bridge_mautrix_meta_messenger_bridge_username_prefix + '{{.}}' }}" -matrix_mautrix_meta_messenger_bridge_displayname_suffix: |- - {{ - ({ - 'facebook': '(FB)', - 'facebook-tor': '(FB)', - 'messenger': '(FB)', - 'instagram': '(IG)', - })[matrix_mautrix_meta_messenger_meta_mode] - }} +matrix_bridge_mautrix_meta_messenger_bridge_displayname_suffix: '(FB)' -matrix_mautrix_meta_messenger_bridge_displayname_template: '{% raw %}{{or .DisplayName .Username "Unknown user"}}{% endraw %}{{ (" " ~ matrix_mautrix_meta_messenger_bridge_displayname_suffix) if matrix_mautrix_meta_messenger_bridge_displayname_suffix else "" }}' +matrix_bridge_mautrix_meta_messenger_bridge_displayname_template: '{% raw %}{{or .DisplayName .Username "Unknown user"}}{% endraw %}{{ (" " ~ matrix_bridge_mautrix_meta_messenger_bridge_displayname_suffix) if matrix_bridge_mautrix_meta_messenger_bridge_displayname_suffix else "" }}' # The prefix for commands. Only required in non-management rooms. -matrix_mautrix_meta_messenger_bridge_command_prefix: |- - {{ - ({ - 'facebook': '!fb', - 'facebook-tor': '!fb', - 'messenger': '!fb', - 'instagram': '!ig', - })[matrix_mautrix_meta_messenger_meta_mode] - }} +matrix_bridge_mautrix_meta_messenger_bridge_command_prefix: '!fb' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_mautrix_meta_messenger_bridge_federate_rooms: true +matrix_bridge_mautrix_meta_messenger_bridge_federate_rooms: true # Should the bridge create a space for each logged-in user and add bridged rooms to it? # Users who logged in before turning this on should run `!meta sync-space` to create and fill the space for the first time. -matrix_mautrix_meta_messenger_bridge_personal_filtering_spaces: true +matrix_bridge_mautrix_meta_messenger_bridge_personal_filtering_spaces: true # Enable End-to-bridge encryption -matrix_mautrix_meta_messenger_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_meta_messenger_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_mautrix_meta_messenger_bridge_encryption_allow_key_sharing: "{{ matrix_mautrix_meta_messenger_bridge_encryption_allow }}" -matrix_mautrix_meta_messenger_bridge_encryption_appservice: false -matrix_mautrix_meta_messenger_bridge_encryption_require: false +matrix_bridge_mautrix_meta_messenger_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_meta_messenger_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_meta_messenger_bridge_encryption_allow_key_sharing: "{{ matrix_bridge_mautrix_meta_messenger_bridge_encryption_allow }}" +matrix_bridge_mautrix_meta_messenger_bridge_encryption_appservice: false +matrix_bridge_mautrix_meta_messenger_bridge_encryption_require: false -matrix_mautrix_meta_messenger_double_puppet_secrets: "{{ matrix_mautrix_meta_messenger_double_puppet_secrets_auto | combine(matrix_mautrix_meta_messenger_double_puppet_secrets_custom) }}" -matrix_mautrix_meta_messenger_double_puppet_secrets_auto: {} -matrix_mautrix_meta_messenger_double_puppet_secrets_custom: {} +matrix_bridge_mautrix_meta_messenger_double_puppet_secrets: "{{ matrix_bridge_mautrix_meta_messenger_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_meta_messenger_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_meta_messenger_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_meta_messenger_double_puppet_secrets_custom: {} -matrix_mautrix_meta_messenger_bridge_permissions: "{{ matrix_mautrix_meta_messenger_bridge_permissions_default | combine(matrix_mautrix_meta_messenger_bridge_permissions_custom) }}" +matrix_bridge_mautrix_meta_messenger_bridge_permissions: "{{ matrix_bridge_mautrix_meta_messenger_bridge_permissions_default | combine(matrix_bridge_mautrix_meta_messenger_bridge_permissions_custom) }}" -matrix_mautrix_meta_messenger_bridge_permissions_default: |- +matrix_bridge_mautrix_meta_messenger_bridge_permissions_default: |- {{ - {'*': 'relay', matrix_mautrix_meta_messenger_homeserver_domain: 'user'} + {'*': 'relay', matrix_bridge_mautrix_meta_messenger_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} -matrix_mautrix_meta_messenger_bridge_permissions_custom: {} +matrix_bridge_mautrix_meta_messenger_bridge_permissions_custom: {} # Enable bridge relay bot functionality -matrix_mautrix_meta_messenger_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" -matrix_mautrix_meta_messenger_bridge_relay_admin_only: true -matrix_mautrix_meta_messenger_bridge_relay_default_relays: [] +matrix_bridge_mautrix_meta_messenger_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" +matrix_bridge_mautrix_meta_messenger_bridge_relay_admin_only: true +matrix_bridge_mautrix_meta_messenger_bridge_relay_default_relays: [] -matrix_mautrix_meta_messenger_backfill_enabled: true -matrix_mautrix_meta_messenger_backfill_max_initial_messages: 50 -matrix_mautrix_meta_messenger_backfill_max_catchup_messages: 500 -matrix_mautrix_meta_messenger_backfill_unread_hours_threshold: 720 -matrix_mautrix_meta_messenger_backfill_threads_max_initial_messages: 50 +matrix_bridge_mautrix_meta_messenger_backfill_enabled: true +matrix_bridge_mautrix_meta_messenger_backfill_max_initial_messages: 50 +matrix_bridge_mautrix_meta_messenger_backfill_max_catchup_messages: 500 +matrix_bridge_mautrix_meta_messenger_backfill_unread_hours_threshold: 720 +matrix_bridge_mautrix_meta_messenger_backfill_threads_max_initial_messages: 50 -matrix_mautrix_meta_messenger_public_media_signing_key: '' +matrix_bridge_mautrix_meta_messenger_public_media_signing_key: '' # Specifies the default log level. # This bridge uses zerolog, so valid levels are: panic, fatal, error, warn, info, debug, trace -matrix_mautrix_meta_messenger_logging_min_level: warn +matrix_bridge_mautrix_meta_messenger_logging_min_level: warn # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_meta_messenger_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_meta_messenger_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_meta_messenger_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_meta_messenger_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_meta_messenger_configuration_extension_yaml: | +matrix_bridge_mautrix_meta_messenger_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_meta_messenger_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_meta_messenger_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_meta_messenger_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_meta_messenger_configuration_yaml`. -matrix_mautrix_meta_messenger_configuration_extension: "{{ matrix_mautrix_meta_messenger_configuration_extension_yaml | from_yaml if matrix_mautrix_meta_messenger_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_meta_messenger_configuration_extension: "{{ matrix_bridge_mautrix_meta_messenger_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_meta_messenger_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_meta_messenger_configuration_yaml`. -matrix_mautrix_meta_messenger_configuration: "{{ matrix_mautrix_meta_messenger_configuration_yaml | from_yaml | combine(matrix_mautrix_meta_messenger_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_meta_messenger_configuration_yaml`. +matrix_bridge_mautrix_meta_messenger_configuration: "{{ matrix_bridge_mautrix_meta_messenger_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_meta_messenger_configuration_extension, recursive=True) }}" -matrix_mautrix_meta_messenger_registration_yaml: | - id: {{ matrix_mautrix_meta_messenger_appservice_id | to_json }} - as_token: {{ matrix_mautrix_meta_messenger_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_meta_messenger_homeserver_token | to_json }} +matrix_bridge_mautrix_meta_messenger_registration_yaml: | + id: {{ matrix_bridge_mautrix_meta_messenger_appservice_id | to_json }} + as_token: {{ matrix_bridge_mautrix_meta_messenger_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_meta_messenger_homeserver_token | to_json }} namespaces: users: - exclusive: true - regex: '^@{{ matrix_mautrix_meta_messenger_bridge_username_prefix }}.+:{{ matrix_mautrix_meta_messenger_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_mautrix_meta_messenger_bridge_username_prefix | regex_escape }}.+:{{ matrix_bridge_mautrix_meta_messenger_homeserver_domain | regex_escape }}$' - exclusive: true - regex: '^@{{ matrix_mautrix_meta_messenger_appservice_username | regex_escape }}:{{ matrix_mautrix_meta_messenger_homeserver_domain | regex_escape }}$' - url: {{ matrix_mautrix_meta_messenger_appservice_address }} - sender_localpart: _bot_{{ matrix_mautrix_meta_messenger_appservice_username }} + regex: '^@{{ matrix_bridge_mautrix_meta_messenger_appservice_username | regex_escape }}:{{ matrix_bridge_mautrix_meta_messenger_homeserver_domain | regex_escape }}$' + url: {{ matrix_bridge_mautrix_meta_messenger_appservice_address }} + sender_localpart: _bot_{{ matrix_bridge_mautrix_meta_messenger_appservice_username }} rate_limited: false de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_mautrix_meta_messenger_msc4190_enabled | to_json }} + io.element.msc4190: {{ matrix_bridge_mautrix_meta_messenger_msc4190_enabled | to_json }} -matrix_mautrix_meta_messenger_registration: "{{ matrix_mautrix_meta_messenger_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_meta_messenger_registration: "{{ matrix_bridge_mautrix_meta_messenger_registration_yaml | from_yaml }}" -# matrix_mautrix_meta_messenger_restart_necessary controls whether the service +# matrix_bridge_mautrix_meta_messenger_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -316,4 +292,4 @@ matrix_mautrix_meta_messenger_registration: "{{ matrix_mautrix_meta_messenger_re # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_meta_messenger_restart_necessary: false +matrix_bridge_mautrix_meta_messenger_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/converge.yml new file mode 100644 index 000000000..629f4d392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-meta-messenger Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-meta-messenger Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-meta-messenger is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-meta-messenger systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-meta-messenger.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/molecule.yml new file mode 100644 index 000000000..657128429 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/molecule.yml @@ -0,0 +1,98 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-meta-messenger-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_meta_messenger_container_network: mautrix-meta-messenger-molecule + + # The stub prepare.yml stands up. Not a real homeserver, and nothing is asserted + # about it. + matrix_bridge_mautrix_meta_messenger_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_meta_messenger_homeserver_domain: molecule.local + + # Postgres, because that is what `group_vars/matrix_servers` selects whenever postgres + # is enabled - which is the default, so it is what essentially every real deployment + # runs. prepare.yml stands one up. Name and user differ from the role's defaults, so + # reaching the database proves the role built its connection string out of these. + matrix_bridge_mautrix_meta_messenger_database_engine: postgres + matrix_bridge_mautrix_meta_messenger_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_meta_messenger_database_name: molecule_meta_messenger + matrix_bridge_mautrix_meta_messenger_database_username: molecule_meta_messenger + matrix_bridge_mautrix_meta_messenger_database_password: molecule_pg_password_d24e70 + + # Here these only have to reach the rendered configuration and the registration. + matrix_bridge_mautrix_meta_messenger_appservice_token: molecule_meta_as_token_5c81de + matrix_bridge_mautrix_meta_messenger_homeserver_token: molecule_meta_hs_token_a70f24 + + # What makes this role family unusual: one upstream codebase serves several Meta + # networks, and this variable picks which. It reaches the rendered configuration in + # four places at once - appservice id, ghost username prefix, bot displayname and the + # bridge's `tor` switch - so a value other than the role's default is what tells + # verify.yml the role propagated the choice rather than everything agreeing by accident. + # + # `facebook-tor` is used because it is the only mode that also flips a boolean. + # Nothing logs in during the scenario, so the bridge never connects to Meta. + matrix_bridge_mautrix_meta_messenger_meta_mode: facebook-tor + + # Different from the role's defaults and from what the bridge would pick on its own, + # so verify.yml can tell what the role rendered apart from a coincidence. + matrix_bridge_mautrix_meta_messenger_appservice_username: molecule-metabot + matrix_bridge_mautrix_meta_messenger_bridge_command_prefix: "!molecule-meta" + matrix_bridge_mautrix_meta_messenger_bridge_displayname_suffix: "(Molecule)" + matrix_bridge_mautrix_meta_messenger_logging_min_level: debug + + # Traefik is not deployed here, so nothing routes to it. What is tested is that the + # role turns these three variables into both the container's Traefik labels and the + # `appservice.public_address` the bridge itself reads. + matrix_bridge_mautrix_meta_messenger_exposure_enabled: true + matrix_bridge_mautrix_meta_messenger_exposure_hostname: bridges.molecule.local + matrix_bridge_mautrix_meta_messenger_exposure_path_prefix: /bridges/meta-messenger + matrix_bridge_mautrix_meta_messenger_scheme: https + + # verify.yml runs as its own play, where the role's defaults are out of scope, + # so the paths it reads are pinned here to match what the role derives. + matrix_bridge_mautrix_meta_messenger_base_path: /matrix/mautrix-meta-messenger + matrix_bridge_mautrix_meta_messenger_config_path: /matrix/mautrix-meta-messenger/config + matrix_bridge_mautrix_meta_messenger_data_path: /matrix/mautrix-meta-messenger/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/prepare.yml new file mode 100644 index 000000000..40258a75d --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/prepare.yml @@ -0,0 +1,92 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-meta-messenger Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks set owner/group by name, which Ansible resolves through the + # passwd database, so they have to exist first. `matrix-base` creates them for real. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role creates this network itself during converge, but the homeserver + # stub below has to be attached to it before that, so it is created here. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_meta_messenger_container_network }}" + register: mautrix_meta_messenger_molecule_network + changed_when: mautrix_meta_messenger_molecule_network.rc == 0 + failed_when: + - mautrix_meta_messenger_molecule_network.rc != 0 + - "'already exists' not in mautrix_meta_messenger_molecule_network.stderr" + + # The bridge calls /whoami before it will run at all, exiting if the id it gets back is + # not the bot user it was configured as. It is not being asked to bridge anything: there + # is no Meta account in this scenario, and deliberately never will be. + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_meta_messenger_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_meta_messenger_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_meta_messenger_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_meta_messenger_database_password }}" + + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_meta_messenger_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_meta_messenger_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_meta_messenger_appservice_username }}:{{ matrix_bridge_mautrix_meta_messenger_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/verify.yml new file mode 100644 index 000000000..4b6ea508b --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/molecule/default/verify.yml @@ -0,0 +1,277 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the bridge starts, reads the configuration and registration the role rendered, opens +# its appservice port, and is the Messenger-side image at the version the role pins. +# +# The extra thing worth proving here is that `..._meta_mode` reaches every place it feeds: one +# upstream codebase serves several Meta networks, and the mode picks which. The scenario runs +# `facebook-tor` rather than the role's default, so the assertions can tell the two apart. +# +# It does NOT bridge anything: no Facebook or Messenger account is on the other side, and +# deliberately never will be. See docs/molecule-testing.md. +- name: Verify mautrix-meta-messenger + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + # Lazily evaluated, so they resolve only in the tasks after the matching slurp. + # Deliberately not set_fact: the rendered configuration contains the bridge's own Go + # templates, and a stored fact gets templated again on every lookup, which would try to + # evaluate those as Jinja. + vars: + mautrix_meta_messenger_config: "{{ mautrix_meta_messenger_config_file.content | b64decode | from_yaml }}" + mautrix_meta_messenger_registration: "{{ mautrix_meta_messenger_registration_file.content | b64decode | from_yaml }}" + mautrix_meta_messenger_labels_rendered: "{{ mautrix_meta_messenger_labels.content | b64decode }}" + gather_facts: false + + tasks: + # From the role's own defaults rather than pinned in molecule.yml, so the version + # assertion compares the running image against what the role ships, not the scenario. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_meta_messenger_role_defaults + + - name: Wait for the mautrix-meta-messenger service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-meta-messenger.service + register: mautrix_meta_messenger_service + until: mautrix_meta_messenger_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # `Restart=always` means a bridge crash-looping on unreadable config still reports + # `active`, so the restart counter is checked too. Asserted `is defined` because + # `| int` turns a missing property into 0 and would pass vacuously. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_meta_messenger_service.status.ActiveState == 'active' + - mautrix_meta_messenger_service.status.NRestarts is defined + - mautrix_meta_messenger_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-meta-messenger.service is + {{ mautrix_meta_messenger_service.status.ActiveState | default('unknown') }} + after {{ mautrix_meta_messenger_service.status.NRestarts | default('?') }} + automatic restart(s) + success_msg: "matrix-mautrix-meta-messenger.service is active and has not restarted" + + # The appservice listener is where a homeserver would push transactions. It opening at all + # means the bridge got through reading its configuration, through its /whoami check, and + # through setting itself up. + - name: Wait for the bridge to open its appservice port + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_meta_messenger_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - "http://matrix-mautrix-meta-messenger:29319/_matrix/mau/live" + register: mautrix_meta_messenger_live + changed_when: false + until: "'HTTP_STATUS=000' not in mautrix_meta_messenger_live.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge answers on its appservice port + ansible.builtin.assert: + that: + - "'HTTP_STATUS=000' not in mautrix_meta_messenger_live.stdout" + fail_msg: >- + The bridge did not answer on its appservice port + ({{ mautrix_meta_messenger_live.stdout | default('no output') }}) + success_msg: "The bridge answers on its appservice port" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_meta_messenger_config_path }}/config.yaml" + register: mautrix_meta_messenger_config_file + + # Each differs from what the bridge would use on its own, so their presence rules out + # a coincidence. + - name: Assert the rendered configuration carries this scenario's values + ansible.builtin.assert: + that: + - mautrix_meta_messenger_config.homeserver.address == matrix_bridge_mautrix_meta_messenger_homeserver_address + - mautrix_meta_messenger_config.homeserver.domain == matrix_bridge_mautrix_meta_messenger_homeserver_domain + - mautrix_meta_messenger_config.appservice.bot.username == matrix_bridge_mautrix_meta_messenger_appservice_username + - mautrix_meta_messenger_config.appservice.as_token == matrix_bridge_mautrix_meta_messenger_appservice_token + - mautrix_meta_messenger_config.appservice.hs_token == matrix_bridge_mautrix_meta_messenger_homeserver_token + - mautrix_meta_messenger_config.bridge.command_prefix == matrix_bridge_mautrix_meta_messenger_bridge_command_prefix + - mautrix_meta_messenger_config.logging.min_level == matrix_bridge_mautrix_meta_messenger_logging_min_level + # matrix_admin is empty in the shared context, so the only per-domain permission + # left is the one the role derives from the homeserver domain. + - mautrix_meta_messenger_config.bridge.permissions[matrix_bridge_mautrix_meta_messenger_homeserver_domain] == 'user' + # From the shared context rather than this scenario, but the role is what has to + # carry it into the configuration. + - mautrix_meta_messenger_config.encryption.allow == matrix_bridges_encryption_enabled + fail_msg: "The rendered configuration does not carry the scenario's values" + success_msg: "The rendered configuration carries the scenario's values" + + # The mode is not written into the configuration as-is: the role expands it into an + # appservice id, a ghost username prefix, a bot displayname and the bridge's `tor` switch. + # Each holds a different value under the role's default mode, so together they prove the + # choice propagated rather than being ignored. + - name: Assert the configuration reflects the Meta mode the scenario selected + ansible.builtin.assert: + that: + - mautrix_meta_messenger_config.appservice.id == 'facebook-tor' + - mautrix_meta_messenger_config.appservice.username_template.startswith('facebook_') + - not mautrix_meta_messenger_config.appservice.username_template.startswith('messenger_') + - mautrix_meta_messenger_config.network.tor + - mautrix_meta_messenger_config.appservice.bot.displayname == 'Facebook-tor bridge bot' + - matrix_bridge_mautrix_meta_messenger_bridge_displayname_suffix in mautrix_meta_messenger_config.network.displayname_template + fail_msg: >- + The rendered configuration does not reflect + matrix_bridge_mautrix_meta_messenger_meta_mode=facebook-tor + success_msg: "The rendered configuration reflects the Meta mode the scenario selected" + + - name: Assert the configuration points the bridge at the database the role derived + ansible.builtin.assert: + that: + - mautrix_meta_messenger_config.database.type == matrix_bridge_mautrix_meta_messenger_database_engine + - matrix_bridge_mautrix_meta_messenger_database_username in mautrix_meta_messenger_config.database.uri + - matrix_bridge_mautrix_meta_messenger_database_name in mautrix_meta_messenger_config.database.uri + - matrix_bridge_mautrix_meta_messenger_database_hostname in mautrix_meta_messenger_config.database.uri + fail_msg: >- + database.uri is {{ mautrix_meta_messenger_config.database.uri | default('unset') }}, + which was not built from the scenario's connection settings + success_msg: "The rendered configuration points the bridge at the database the role derived" + + # The public address is what the role builds out of the three exposure + # variables; it is the same endpoint the Traefik labels below route to. + - name: Assert the configuration carries the public address the exposure settings imply + ansible.builtin.assert: + that: + - mautrix_meta_messenger_config.appservice.public_address == 'https://bridges.molecule.local/bridges/meta-messenger' + fail_msg: >- + appservice.public_address is + {{ mautrix_meta_messenger_config.appservice.public_address | default('unset') }} + success_msg: "The rendered configuration carries the public address the exposure settings imply" + + # The role generates the registration; the bridge only consumes it. Worth checking on its + # own, as it is the half of the handshake the homeserver reads. + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_meta_messenger_config_path }}/registration.yaml" + register: mautrix_meta_messenger_registration_file + + - name: Assert the registration carries the scenario's tokens, id and bot user + ansible.builtin.assert: + that: + - mautrix_meta_messenger_registration.as_token == matrix_bridge_mautrix_meta_messenger_appservice_token + - mautrix_meta_messenger_registration.hs_token == matrix_bridge_mautrix_meta_messenger_homeserver_token + - mautrix_meta_messenger_registration.id == 'facebook-tor' + - mautrix_meta_messenger_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_meta_messenger_appservice_username + - mautrix_meta_messenger_registration.url == 'http://matrix-mautrix-meta-messenger:29319' + fail_msg: "The appservice registration does not carry the scenario's tokens, id and bot user" + success_msg: "The appservice registration carries the scenario's tokens, id and bot user" + + # The namespaces are regexes the role assembles. Comparing them as strings would only + # re-derive the role's own escaping, so they are checked by what they match: the bot, + # this mode's ghosts, and not the ghosts of the mode the role would have defaulted to. + - name: Assert the registration namespaces cover the bot and this mode's ghost users + ansible.builtin.assert: + that: + - mautrix_meta_messenger_ghost_regex | length > 0 + - mautrix_meta_messenger_bot_regex | length > 0 + - mautrix_meta_messenger_facebook_ghost_mxid is match(mautrix_meta_messenger_ghost_regex) + - mautrix_meta_messenger_messenger_ghost_mxid is not match(mautrix_meta_messenger_ghost_regex) + - mautrix_meta_messenger_bot_mxid is match(mautrix_meta_messenger_bot_regex) + fail_msg: "The appservice registration namespaces do not cover the bot and this mode's ghost users" + success_msg: "The appservice registration namespaces cover the bot and this mode's ghost users" + vars: + mautrix_meta_messenger_user_regexes: "{{ mautrix_meta_messenger_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_meta_messenger_ghost_regex: "{{ mautrix_meta_messenger_user_regexes | select('search', 'facebook_') | first | default('') }}" + mautrix_meta_messenger_bot_regex: "{{ mautrix_meta_messenger_user_regexes | reject('search', 'facebook_') | first | default('') }}" + mautrix_meta_messenger_facebook_ghost_mxid: "@facebook_1234567890:{{ matrix_bridge_mautrix_meta_messenger_homeserver_domain }}" + mautrix_meta_messenger_messenger_ghost_mxid: "@messenger_1234567890:{{ matrix_bridge_mautrix_meta_messenger_homeserver_domain }}" + mautrix_meta_messenger_bot_mxid: "@{{ matrix_bridge_mautrix_meta_messenger_appservice_username }}:{{ matrix_bridge_mautrix_meta_messenger_homeserver_domain }}" + + # The bridge can only have created tables here by resolving the hostname, authenticating + # with the credentials the role rendered, and running its migrations to completion. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_meta_messenger_database_username }} + - --dbname={{ matrix_bridge_mautrix_meta_messenger_database_name }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: mautrix_meta_messenger_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the database the role pointed it at + ansible.builtin.assert: + that: + - mautrix_meta_messenger_tables.rc == 0 + - "'version' in mautrix_meta_messenger_table_names" + - mautrix_meta_messenger_table_names | length > 5 + fail_msg: >- + The bridge did not create its schema in + {{ matrix_bridge_mautrix_meta_messenger_database_name }} + (found {{ mautrix_meta_messenger_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the database the role pointed it at" + vars: + mautrix_meta_messenger_table_names: "{{ mautrix_meta_messenger_tables.stdout_lines | select | list }}" + + - name: Read the image of the running container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-meta-messenger + - --format + - "{{ '{{' }} .Config.Image {{ '}}' }}" + register: mautrix_meta_messenger_image + changed_when: false + + # Both Meta bridges publish to the same image repository, with Instagram's tags carrying + # an `ig-` prefix. Compared whole rather than by substring, so pulling the other bridge's + # image would fail here. + - name: Assert the running container is the Messenger image at the version defaults/main.yml pins + ansible.builtin.assert: + that: + - mautrix_meta_messenger_image.stdout.endswith(':' + mautrix_meta_messenger_role_defaults.matrix_bridge_mautrix_meta_messenger_version) + fail_msg: >- + The running container is {{ mautrix_meta_messenger_image.stdout }}, which is not + the Messenger image at the pinned version + {{ mautrix_meta_messenger_role_defaults.matrix_bridge_mautrix_meta_messenger_version }} + success_msg: "The running container is the Messenger image at the version defaults/main.yml pins" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_meta_messenger_base_path }}/labels" + register: mautrix_meta_messenger_labels + + # Traefik is not running here, so this checks what the role wrote, not what a reverse + # proxy would do with it. The port matters: it is hardcoded in the role's templates rather + # than derived from a variable, so nothing else here would catch it drifting from the port + # the bridge actually listens on. + - name: Assert the labels route the exposure hostname and path prefix to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_meta_messenger_labels_rendered" + - "'traefik.http.services.matrix-mautrix-meta-messenger-appservice.loadbalancer.server.port=29319' in mautrix_meta_messenger_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-meta-messenger-exposure.rule=Host(`bridges.molecule.local`) && PathPrefix(`/bridges/meta-messenger`)' in mautrix_meta_messenger_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-meta-messenger-exposure-strip-prefix.stripprefix.prefixes=/bridges/meta-messenger' in mautrix_meta_messenger_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_meta_messenger_container_network in mautrix_meta_messenger_labels_rendered" + fail_msg: "The rendered labels do not route the exposure hostname and path prefix to the appservice port" + success_msg: "The rendered labels route the exposure hostname and path prefix to the appservice port" diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/install.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/install.yml index fa3965031..b18a6ef6a 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/install.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/install.yml @@ -6,43 +6,41 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_meta_messenger_migration_requires_restart: false + matrix_bridge_mautrix_meta_messenger_migration_requires_restart: false -- when: "matrix_mautrix_meta_messenger_database_engine == 'postgres'" +- when: "matrix_bridge_mautrix_meta_messenger_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mautrix_meta_messenger_sqlite_database_path_local }}" - register: matrix_mautrix_meta_messenger_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mautrix_meta_messenger_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_meta_messenger_sqlite_database_path_local_stat_result - - when: "matrix_mautrix_meta_messenger_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mautrix_meta_messenger_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mautrix_meta_messenger_sqlite_database_path_local }}" - dst: "{{ matrix_mautrix_meta_messenger_database_connection_string }}" + src: "{{ matrix_bridge_mautrix_meta_messenger_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_meta_messenger_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mautrix_meta_messenger_database_engine' + engine_variable_name: 'matrix_bridge_mautrix_meta_messenger_database_engine' engine_old: 'sqlite' - systemd_services_to_stop: "{{ [matrix_mautrix_meta_messenger_identifier + '.service'] }}" + systemd_services_to_stop: "{{ [matrix_bridge_mautrix_meta_messenger_identifier + '.service'] }}" - ansible.builtin.set_fact: - matrix_mautrix_meta_messenger_migration_requires_restart: true + matrix_bridge_mautrix_meta_messenger_migration_requires_restart: true - name: Ensure mautrix-meta-messenger container image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_meta_messenger_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_meta_messenger_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_meta_messenger_container_image_force_pull }}" - when: not matrix_mautrix_meta_messenger_container_image_self_build - register: matrix_mautrix_meta_messenger_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_meta_messenger_container_image }}" + pull: always + when: not matrix_bridge_mautrix_meta_messenger_container_image_self_build + register: matrix_bridge_mautrix_meta_messenger_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_meta_messenger_container_image_pull_result is not failed + until: matrix_bridge_mautrix_meta_messenger_container_image_pull_result is not failed - name: Ensure mautrix-meta-messenger paths exist ansible.builtin.file: @@ -52,93 +50,102 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_meta_messenger_base_path }}", when: true} - - {path: "{{ matrix_mautrix_meta_messenger_config_path }}", when: true} - - {path: "{{ matrix_mautrix_meta_messenger_data_path }}", when: true} - - {path: "{{ matrix_mautrix_meta_messenger_container_src_files_path }}", when: "{{ matrix_mautrix_meta_messenger_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_meta_messenger_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_meta_messenger_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_meta_messenger_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_meta_messenger_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_meta_messenger_container_image_self_build }}"} when: item.when | bool -- when: matrix_mautrix_meta_messenger_container_image_self_build | bool +- when: matrix_bridge_mautrix_meta_messenger_container_image_self_build | bool block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure mautrix-meta-messenger repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_meta_messenger_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure mautrix-meta-messenger repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_mautrix_meta_messenger_container_image_self_build_repo }}" - dest: "{{ matrix_mautrix_meta_messenger_container_src_files_path }}" - version: "{{ matrix_mautrix_meta_messenger_container_image.split(':')[1] }}" + repo: "{{ matrix_bridge_mautrix_meta_messenger_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_mautrix_meta_messenger_container_src_files_path }}" + version: "{{ matrix_bridge_mautrix_meta_messenger_version }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_meta_messenger_git_pull_results + register: matrix_bridge_mautrix_meta_messenger_git_pull_results - name: Ensure mautrix-meta-messenger container image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_meta_messenger_container_image }}" - source: build - force_source: "{{ matrix_mautrix_meta_messenger_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_meta_messenger_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_meta_messenger_container_src_files_path }}" - pull: true + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_meta_messenger_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_meta_messenger_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_meta_messenger_git_pull_results.changed | bool else 'never' }}" + register: matrix_bridge_mautrix_meta_messenger_container_image_build_result - name: Ensure mautrix-meta-messenger config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_meta_messenger_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_meta_messenger_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_meta_messenger_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_meta_messenger_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_meta_messenger_config_result + register: matrix_bridge_mautrix_meta_messenger_config_result - name: Ensure mautrix-meta-messenger registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_meta_messenger_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_meta_messenger_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_meta_messenger_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_meta_messenger_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_meta_messenger_registration_result + register: matrix_bridge_mautrix_meta_messenger_registration_result - name: Ensure mautrix-meta-messenger support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_meta_messenger_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_meta_messenger_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_mautrix_meta_messenger_support_files_result + register: matrix_bridge_mautrix_meta_messenger_support_files_result - name: Ensure mautrix-meta-messenger container network is created + when: matrix_bridge_mautrix_meta_messenger_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_meta_messenger_container_network }}" + name: "{{ matrix_bridge_mautrix_meta_messenger_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - name: Ensure mautrix-meta-messenger.service installed ansible.builtin.template: - src: "{{ role_path }}/templates/systemd/matrix-mautrix-meta.service.j2" - dest: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_mautrix_meta_messenger_identifier }}.service" + src: "{{ role_path }}/templates/systemd/matrix-mautrix-meta-messenger.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_bridge_mautrix_meta_messenger_identifier }}.service" mode: '0644' - register: matrix_mautrix_meta_messenger_systemd_service_result + register: matrix_bridge_mautrix_meta_messenger_systemd_service_result - name: Determine whether mautrix-meta-messenger needs a restart ansible.builtin.set_fact: - matrix_mautrix_meta_messenger_restart_necessary: >- + matrix_bridge_mautrix_meta_messenger_restart_necessary: >- {{ - matrix_mautrix_meta_messenger_migration_requires_restart | default(false) - or matrix_mautrix_meta_messenger_config_result.changed | default(false) - or matrix_mautrix_meta_messenger_registration_result.changed | default(false) - or matrix_mautrix_meta_messenger_support_files_result.changed | default(false) - or matrix_mautrix_meta_messenger_systemd_service_result.changed | default(false) - or matrix_mautrix_meta_messenger_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_meta_messenger_migration_requires_restart | default(false) + or matrix_bridge_mautrix_meta_messenger_config_result.changed | default(false) + or matrix_bridge_mautrix_meta_messenger_registration_result.changed | default(false) + or matrix_bridge_mautrix_meta_messenger_support_files_result.changed | default(false) + or matrix_bridge_mautrix_meta_messenger_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_meta_messenger_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_meta_messenger_container_image_build_result.changed | default(false) }} - name: Ensure mautrix-meta-messenger.service restarted, if necessary ansible.builtin.service: - name: "{{ matrix_mautrix_meta_messenger_identifier }}.service" + name: "{{ matrix_bridge_mautrix_meta_messenger_identifier }}.service" state: restarted daemon_reload: true - when: "matrix_mautrix_meta_messenger_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_meta_messenger_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/main.yml index c77b53fa0..e30cd30db 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/main.yml @@ -10,15 +10,15 @@ - install-all - install-mautrix-meta-messenger block: - - when: matrix_mautrix_meta_messenger_enabled | bool + - when: matrix_bridge_mautrix_meta_messenger_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_meta_messenger_enabled | bool + - when: matrix_bridge_mautrix_meta_messenger_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/install.yml" - tags: - setup-all - setup-mautrix-meta-messenger block: - - when: not matrix_mautrix_meta_messenger_enabled | bool + - when: not matrix_bridge_mautrix_meta_messenger_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/uninstall.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/uninstall.yml index 7ec36ad14..6b62bb967 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/uninstall.yml @@ -6,19 +6,19 @@ - name: Check existence of mautrix-meta-messenger service ansible.builtin.stat: - path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_mautrix_meta_messenger_identifier }}.service" - register: matrix_mautrix_meta_messenger_service_stat + path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_bridge_mautrix_meta_messenger_identifier }}.service" + register: matrix_bridge_mautrix_meta_messenger_service_stat -- when: matrix_mautrix_meta_messenger_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_meta_messenger_service_stat.stat.exists | bool block: - name: Ensure mautrix-meta-messenger is stopped ansible.builtin.service: - name: "{{ matrix_mautrix_meta_messenger_identifier }}" + name: "{{ matrix_bridge_mautrix_meta_messenger_identifier }}" state: stopped enabled: false daemon_reload: true - name: Ensure mautrix-meta-messenger.service doesn't exist ansible.builtin.file: - path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_mautrix_meta_messenger_identifier }}.service" + path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_bridge_mautrix_meta_messenger_identifier }}.service" state: absent diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/validate_config.yml index 5a005f1e2..99ef354dc 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/tasks/validate_config.yml @@ -11,14 +11,12 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_meta_messenger_metrics_proxying_hostname', when: "{{ matrix_mautrix_meta_messenger_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_meta_messenger_metrics_proxying_path_prefix', when: "{{ matrix_mautrix_meta_messenger_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_meta_messenger_appservice_token', when: true} - - {'name': 'matrix_mautrix_meta_messenger_homeserver_token', when: true} - - {'name': 'matrix_mautrix_meta_messenger_container_network', when: true} - - {'name': 'matrix_mautrix_meta_messenger_homeserver_address', when: true} - - {'name': 'matrix_mautrix_meta_messenger_database_hostname', when: "{{ matrix_mautrix_meta_messenger_database_engine == 'postgres' }}"} - - {'name': 'matrix_mautrix_meta_messenger_database_password', when: "{{ matrix_mautrix_meta_messenger_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_meta_messenger_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_meta_messenger_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_meta_messenger_container_network', when: true} + - {'name': 'matrix_bridge_mautrix_meta_messenger_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_meta_messenger_database_hostname', when: "{{ matrix_bridge_mautrix_meta_messenger_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_meta_messenger_database_password', when: "{{ matrix_bridge_mautrix_meta_messenger_database_engine == 'postgres' }}"} - name: (Deprecation) Catch and report renamed mautrix-meta-messenger variables ansible.builtin.fail: @@ -27,7 +25,22 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_meta_messenger_bridge_login_shared_secret', 'new': ''} - - {'old': 'matrix_mautrix_meta_messenger_bridge_login_shared_secret_map_custom', 'new': ''} - - {'old': 'matrix_mautrix_meta_messenger_bridge_management_room_text_welcome', 'new': ''} - - {'old': 'matrix_mautrix_meta_messenger_container_image_name_prefix', 'new': 'matrix_mautrix_meta_messenger_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_bridge_login_shared_secret', 'new': ''} + - {'old': 'matrix_bridge_mautrix_meta_messenger_bridge_login_shared_secret_map_custom', 'new': ''} + - {'old': 'matrix_bridge_mautrix_meta_messenger_bridge_management_room_text_welcome', 'new': ''} + - {'old': 'matrix_bridge_mautrix_meta_messenger_container_image_name_prefix', 'new': 'matrix_bridge_mautrix_meta_messenger_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_metrics_enabled', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_metrics_proxying_enabled', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_metrics_proxying_hostname', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_metrics_proxying_path_prefix', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_container_labels_metrics_enabled', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_container_labels_metrics_traefik_rule', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_container_labels_metrics_traefik_priority', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_container_labels_metrics_traefik_entrypoints', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_container_labels_metrics_traefik_tls', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_container_labels_metrics_traefik_tls_certResolver', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_container_labels_metrics_middleware_basic_auth_users', 'new': ' (mautrix-meta-messenger does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_meta_ig_e2ee', 'new': ' (mautrix-meta no longer has an `ig_e2ee` configuration option)'} + - {'old': 'matrix_bridge_mautrix_meta_messenger_appservice_username_prefix', 'new': ''} diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/config.yaml.j2 index 2af47d5f8..cdebfe3b0 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/config.yaml.j2 @@ -1,48 +1,59 @@ #jinja2: lstrip_blocks: True # Network-specific config options network: - # Which service is this bridge for? Available options: - # * unset - allow users to pick any service when logging in (except facebook-tor) - # * facebook - connect to FB Messenger via facebook.com - # * facebook-tor - connect to FB Messenger via facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion - # (note: does not currently proxy media downloads) - # * messenger - connect to FB Messenger via messenger.com (can be used with the facebook side deactivated) - # * instagram - connect to Instagram DMs via instagram.com - # - # Remember to change the appservice ID, bot profile info, bridge username_template and management_room_text too. - mode: {{ matrix_mautrix_meta_messenger_meta_mode | to_json }} - - # When in Instagram mode, should the bridge connect to WhatsApp servers for encrypted chats? - # In FB/Messenger mode encryption is always enabled, this option only affects Instagram mode. - ig_e2ee: {{ matrix_mautrix_meta_messenger_meta_ig_e2ee | to_json }} - - # Displayname template for FB/IG users. Available variables: + # Displayname template for FB users. Available variables: # .DisplayName - The display name set by the user. # .Username - The username set by the user. # .ID - The internal user ID of the user. - displayname_template: {{ matrix_mautrix_meta_messenger_bridge_displayname_template | to_json }} + displayname_template: {{ matrix_bridge_mautrix_meta_messenger_bridge_displayname_template | to_json }} # Static proxy address (HTTP or SOCKS5) for connecting to Meta. proxy: + # If using a Tor proxy in the field above, you can set this to connect to + # facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion instead of facebook.com. + tor: {{ (matrix_bridge_mautrix_meta_messenger_meta_mode == 'facebook-tor') | to_json }} # HTTP endpoint to request new proxy address from, for dynamically assigned proxies. # The endpoint must return a JSON body with a string field called proxy_url. get_proxy_from: + # Should media be proxied too? + proxy_media: false + # Should E2EE messages be proxied too? + proxy_e2ee: false + # Should Messenger Lite login traffic be proxied? + proxy_messenger_lite: true + # Should other traffic, not configured here, be proxied? + proxy_other: true # Minimum interval between full reconnects in seconds, default is 1 hour min_full_reconnect_interval_seconds: 3600 # Interval to force refresh the connection (full reconnect), default is 20 hours. Set 0 to disable force refreshes. force_refresh_interval_seconds: 72000 - # Disable fetching XMA media (reels, stories, etc) when backfilling. - disable_xma_backfill: true - # Disable fetching XMA media entirely. - disable_xma_always: false + # Should connection state be cached to allow quicker restarts? + cache_connection_state: false + # Should the bridge mark you as online when you send typing + # notifications? Currently, this only has an effect for E2EE chats on + # Facebook/Messenger. Full presence bridging is not supported. + send_presence_on_typing: false + # Should view-once messages be disabled entirely? + disable_view_once: false + # Should FB marketplace chats have a separate space inside the main Facebook space? + marketplace_space: true + # Log raw Bloks payloads even at debug level, with any user identifiers or credentials redacted. + log_redacted_bloks_payloads: false + + # Thread backfill settings for syncing older conversations + thread_backfill: + # Number of batches (pages) to backfill (-1 for unlimited, 0 to disable) + batch_count: -1 + # Delay between fetching each batch of threads (to avoid rate limiting) + batch_delay: 2s # Config options that affect the central bridge module. bridge: # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_mautrix_meta_messenger_bridge_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_mautrix_meta_messenger_bridge_command_prefix | to_json }} # Should the bridge create a space for each login containing the rooms that account is in? - personal_filtering_spaces: {{ matrix_mautrix_meta_messenger_bridge_personal_filtering_spaces | to_json }} + personal_filtering_spaces: {{ matrix_bridge_mautrix_meta_messenger_bridge_personal_filtering_spaces | to_json }} # Whether the bridge should set names and avatars explicitly for DM portals. # This is only necessary when using clients that don't support MSC4171. private_chat_portal_meta: false @@ -97,12 +108,12 @@ bridge: relay: # Whether relay mode should be allowed. If allowed, the set-relay command can be used to turn any # authenticated user into a relaybot for that chat. - enabled: {{ matrix_mautrix_meta_messenger_bridge_relay_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_meta_messenger_bridge_relay_enabled | to_json }} # Should only admins be allowed to set themselves as relay users? # If true, non-admins can only set users listed in default_relays as relays in a room. - admin_only: {{ matrix_mautrix_meta_messenger_bridge_relay_admin_only | to_json }} + admin_only: {{ matrix_bridge_mautrix_meta_messenger_bridge_relay_admin_only | to_json }} # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. - default_relays: {{ matrix_mautrix_meta_messenger_bridge_relay_default_relays | to_json }} + default_relays: {{ matrix_bridge_mautrix_meta_messenger_bridge_relay_default_relays | to_json }} # The formats to use when sending messages via the relaybot. # Available variables: # .Sender.UserID - The Matrix user ID of the sender. @@ -138,18 +149,18 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_meta_messenger_bridge_permissions | to_json }} + permissions: {{ matrix_bridge_mautrix_meta_messenger_bridge_permissions | to_json }} # Config for the bridge's database. database: # The database type. "sqlite3-fk-wal" and "postgres" are supported. - type: {{ matrix_mautrix_meta_messenger_appservice_database_type | to_json }} + type: {{ matrix_bridge_mautrix_meta_messenger_appservice_database_type | to_json }} # The database URI. # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. # https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_mautrix_meta_messenger_appservice_database_uri | to_json }} + uri: {{ matrix_bridge_mautrix_meta_messenger_appservice_database_uri | to_json }} # Maximum number of connections. max_open_conns: 5 max_idle_conns: 1 @@ -163,9 +174,9 @@ homeserver: # The address that this appservice can use to connect to the homeserver. # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, # but https also works if they run on different machines. - address: {{ matrix_mautrix_meta_messenger_homeserver_address | to_json }} + address: {{ matrix_bridge_mautrix_meta_messenger_homeserver_address | to_json }} # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: {{ matrix_mautrix_meta_messenger_homeserver_domain | to_json }} + domain: {{ matrix_bridge_mautrix_meta_messenger_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -181,7 +192,7 @@ homeserver: # The bridge will use the appservice as_token to authorize requests. message_send_checkpoint_endpoint: # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_mautrix_meta_messenger_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_mautrix_meta_messenger_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -194,10 +205,10 @@ homeserver: # Changing these values requires regeneration of the registration (except when noted otherwise) appservice: # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_mautrix_meta_messenger_appservice_address | to_json }} + address: {{ matrix_bridge_mautrix_meta_messenger_appservice_address | to_json }} # A public address that external services can use to reach this appservice. # This value doesn't affect the registration file. - public_address: https://bridge.example.com + public_address: {{ matrix_bridge_mautrix_meta_messenger_bridge_public_address | to_json }} # The hostname and port where this appservice should listen. # For Docker, you generally have to change the hostname to 0.0.0.0. @@ -205,15 +216,15 @@ appservice: port: 29319 # The unique ID of this appservice. - id: {{ matrix_mautrix_meta_messenger_appservice_id | to_json }} + id: {{ matrix_bridge_mautrix_meta_messenger_appservice_id | to_json }} # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_mautrix_meta_messenger_appservice_username | to_json }} + username: {{ matrix_bridge_mautrix_meta_messenger_appservice_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. - displayname: {{ matrix_mautrix_meta_messenger_appservice_displayname | to_json(ensure_ascii=False) }} - avatar: {{ matrix_mautrix_meta_messenger_appservice_avatar | to_json }} + displayname: {{ matrix_bridge_mautrix_meta_messenger_appservice_displayname | to_json(ensure_ascii=False) }} + avatar: {{ matrix_bridge_mautrix_meta_messenger_appservice_avatar | to_json }} # Whether to receive ephemeral events via appservice transactions. ephemeral_events: true @@ -224,12 +235,12 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_mautrix_meta_messenger_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_meta_messenger_homeserver_token | to_json }} + as_token: {{ matrix_bridge_mautrix_meta_messenger_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_meta_messenger_homeserver_token | to_json }} # Localpart template of MXIDs for remote users. # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. - username_template: {{ matrix_mautrix_meta_messenger_bridge_username_template | to_json }} + username_template: {{ matrix_bridge_mautrix_meta_messenger_bridge_username_template | to_json }} # Config options that affect the Matrix connector of the bridge. matrix: @@ -243,7 +254,7 @@ matrix: sync_direct_chat_list: false # Whether created rooms should have federation enabled. If false, created portal rooms # will never be federated. Changing this option requires recreating rooms. - federate_rooms: {{ matrix_mautrix_meta_messenger_bridge_federate_rooms | to_json }} + federate_rooms: {{ matrix_bridge_mautrix_meta_messenger_bridge_federate_rooms | to_json }} # The threshold as bytes after which the bridge should roundtrip uploads via the disk # rather than keeping the whole file in memory. upload_file_threshold: 5242880 @@ -263,7 +274,7 @@ provisioning: prefix: /_matrix/provision # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, # or if set to "disable", the provisioning API will be disabled. - shared_secret: {{ matrix_mautrix_meta_messenger_provisioning_shared_secret | to_json }} + shared_secret: {{ matrix_bridge_mautrix_meta_messenger_provisioning_shared_secret | to_json }} # Whether to allow provisioning API requests to be authed using Matrix access tokens. # This follows the same rules as double puppeting to determine which server to contact to check the token, # which means that by default, it only works for users on the same server as the bridge. @@ -279,7 +290,7 @@ public_media: enabled: false # A key for signing public media URLs. # If set to "generate", a random key will be generated. - signing_key: {{ matrix_mautrix_meta_messenger_public_media_signing_key | to_json }} + signing_key: {{ matrix_bridge_mautrix_meta_messenger_public_media_signing_key | to_json }} # Number of seconds that public media URLs are valid for. # If set to 0, URLs will never expire. expiry: 0 @@ -313,18 +324,18 @@ direct_media: # See https://docs.mau.fi/bridges/general/backfill.html for more details. backfill: # Whether to do backfilling at all. - enabled: {{ matrix_mautrix_meta_messenger_backfill_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_meta_messenger_backfill_enabled | to_json }} # Maximum number of messages to backfill in empty rooms. - max_initial_messages: {{ matrix_mautrix_meta_messenger_backfill_max_initial_messages | to_json}} + max_initial_messages: {{ matrix_bridge_mautrix_meta_messenger_backfill_max_initial_messages | to_json}} # Maximum number of missed messages to backfill after bridge restarts. - max_catchup_messages: {{ matrix_mautrix_meta_messenger_backfill_max_catchup_messages | to_json }} + max_catchup_messages: {{ matrix_bridge_mautrix_meta_messenger_backfill_max_catchup_messages | to_json }} # If a backfilled chat is older than this number of hours, # mark it as read even if it's unread on the remote network. - unread_hours_threshold: {{ matrix_mautrix_meta_messenger_backfill_unread_hours_threshold | to_json }} + unread_hours_threshold: {{ matrix_bridge_mautrix_meta_messenger_backfill_unread_hours_threshold | to_json }} # Settings for backfilling threads within other backfills. threads: # Maximum number of messages to backfill in a new thread. - max_initial_messages: {{ matrix_mautrix_meta_messenger_backfill_threads_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_mautrix_meta_messenger_backfill_threads_max_initial_messages | to_json }} # Settings for the backwards backfill queue. This only applies when connecting to # Beeper as standard Matrix servers don't support inserting messages into history. queue: @@ -352,32 +363,32 @@ double_puppet: allow_discovery: false # Shared secrets for automatic double puppeting. # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. - secrets: {{ matrix_mautrix_meta_messenger_double_puppet_secrets | to_json }} + secrets: {{ matrix_bridge_mautrix_meta_messenger_double_puppet_secrets | to_json }} # End-to-bridge encryption support options. # # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. - allow: {{ matrix_mautrix_meta_messenger_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_mautrix_meta_messenger_bridge_encryption_allow | to_json }} # Whether to force-enable encryption in all bridged rooms. - default: {{ matrix_mautrix_meta_messenger_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_mautrix_meta_messenger_bridge_encryption_default | to_json }} # Whether to require all messages to be encrypted and drop any unencrypted messages. - require: {{ matrix_mautrix_meta_messenger_bridge_encryption_require | to_json }} + require: {{ matrix_bridge_mautrix_meta_messenger_bridge_encryption_require | to_json }} # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. # This option is not yet compatible with standard Matrix servers like Synapse and should not be used. - appservice: {{ matrix_mautrix_meta_messenger_bridge_encryption_appservice | to_json }} + appservice: {{ matrix_bridge_mautrix_meta_messenger_bridge_encryption_appservice | to_json }} # Whether to use MSC4190 instead of appservice login to create the bridge bot device. # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_mautrix_meta_messenger_msc4190_enabled | to_json }} + msc4190: {{ matrix_bridge_mautrix_meta_messenger_msc4190_enabled | to_json }} # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) # Requires msc4190 to replace keys on reset - self_sign: {{ matrix_mautrix_meta_messenger_self_sign_enabled | to_json }} + self_sign: {{ matrix_bridge_mautrix_meta_messenger_self_sign_enabled | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_mautrix_meta_messenger_bridge_encryption_allow_key_sharing | to_json }} + allow_key_sharing: {{ matrix_bridge_mautrix_meta_messenger_bridge_encryption_allow_key_sharing | to_json }} # Pickle key for encrypting encryption keys in the bridge database. # If set to generate, a random key will be generated. pickle_key: mautrix.bridge.e2ee @@ -439,7 +450,7 @@ encryption: # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_mautrix_meta_messenger_logging_min_level | to_json }} + min_level: {{ matrix_bridge_mautrix_meta_messenger_logging_min_level | to_json }} writers: - type: stdout format: pretty diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/labels.j2 index 21946df81..8a61ac236 100644 --- a/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/labels.j2 @@ -4,51 +4,48 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_meta_messenger_container_labels_traefik_enabled and matrix_mautrix_meta_messenger_container_labels_metrics_enabled %} +{% if matrix_bridge_mautrix_meta_messenger_container_labels_traefik_enabled and matrix_bridge_mautrix_meta_messenger_container_labels_exposure_enabled %} traefik.enable=true -{% if matrix_mautrix_meta_messenger_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_meta_messenger_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_meta_messenger_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_meta_messenger_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.{{ matrix_mautrix_meta_messenger_identifier }}-appservice.loadbalancer.server.port=29319 -traefik.http.services.{{ matrix_mautrix_meta_messenger_identifier }}-metrics.loadbalancer.server.port=8000 - +{% if matrix_bridge_mautrix_meta_messenger_container_labels_exposure_enabled %} +traefik.http.services.{{ matrix_bridge_mautrix_meta_messenger_identifier }}-appservice.loadbalancer.server.port=29319 +{% endif %} -{% if matrix_mautrix_meta_messenger_container_labels_metrics_enabled %} +{% if matrix_bridge_mautrix_meta_messenger_container_labels_exposure_enabled %} ############################################################ # # -# Metrics # +# Bridge API exposure # # # ############################################################ -{% if matrix_mautrix_meta_messenger_container_labels_metrics_middleware_basic_auth_enabled %} -traefik.http.middlewares.{{ matrix_mautrix_meta_messenger_identifier }}-metrics-basic-auth.basicauth.users={{ matrix_mautrix_meta_messenger_container_labels_metrics_middleware_basic_auth_users }} -traefik.http.routers.{{ matrix_mautrix_meta_messenger_identifier }}-metrics.middlewares={{ matrix_mautrix_meta_messenger_identifier }}-metrics-basic-auth -{% endif %} +traefik.http.middlewares.{{ matrix_bridge_mautrix_meta_messenger_identifier }}-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_meta_messenger_exposure_path_prefix }} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_messenger_identifier }}-exposure.middlewares={{ matrix_bridge_mautrix_meta_messenger_identifier }}-exposure-strip-prefix -traefik.http.routers.{{ matrix_mautrix_meta_messenger_identifier }}-metrics.rule={{ matrix_mautrix_meta_messenger_container_labels_metrics_traefik_rule }} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_messenger_identifier }}-exposure.rule={{ matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_rule }} -{% if matrix_mautrix_meta_messenger_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.{{ matrix_mautrix_meta_messenger_identifier }}-metrics.priority={{ matrix_mautrix_meta_messenger_container_labels_metrics_traefik_priority }} +{% if matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_messenger_identifier }}-exposure.priority={{ matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_priority }} {% endif %} -traefik.http.routers.{{ matrix_mautrix_meta_messenger_identifier }}-metrics.service={{ matrix_mautrix_meta_messenger_identifier }}-metrics -traefik.http.routers.{{ matrix_mautrix_meta_messenger_identifier }}-metrics.entrypoints={{ matrix_mautrix_meta_messenger_container_labels_metrics_traefik_entrypoints }} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_messenger_identifier }}-exposure.service={{ matrix_bridge_mautrix_meta_messenger_identifier }}-appservice +traefik.http.routers.{{ matrix_bridge_mautrix_meta_messenger_identifier }}-exposure.entrypoints={{ matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_entrypoints }} -traefik.http.routers.{{ matrix_mautrix_meta_messenger_identifier }}-metrics.tls={{ matrix_mautrix_meta_messenger_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_mautrix_meta_messenger_container_labels_metrics_traefik_tls %} -traefik.http.routers.{{ matrix_mautrix_meta_messenger_identifier }}-metrics.tls.certResolver={{ matrix_mautrix_meta_messenger_container_labels_metrics_traefik_tls_certResolver }} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_messenger_identifier }}-exposure.tls={{ matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_tls %} +traefik.http.routers.{{ matrix_bridge_mautrix_meta_messenger_identifier }}-exposure.tls.certResolver={{ matrix_bridge_mautrix_meta_messenger_container_labels_exposure_traefik_tls_certResolver }} {% endif %} ############################################################ # # -# /Metrics # +# /Bridge API exposure # # # ############################################################ {% endif %} - {% endif %} -{{ matrix_mautrix_meta_messenger_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_meta_messenger_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/systemd/matrix-mautrix-meta-messenger.service.j2 b/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/systemd/matrix-mautrix-meta-messenger.service.j2 new file mode 100644 index 000000000..c2f0a5380 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/systemd/matrix-mautrix-meta-messenger.service.j2 @@ -0,0 +1,53 @@ +#jinja2: lstrip_blocks: True +[Unit] +Description=mautrix-meta bridge ({{ matrix_bridge_mautrix_meta_messenger_identifier }}) +{% for service in matrix_bridge_mautrix_meta_messenger_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_bridge_mautrix_meta_messenger_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_bridge_mautrix_meta_messenger_identifier }} 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_bridge_mautrix_meta_messenger_identifier }} 2>/dev/null || true' + +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ + --rm \ + --name={{ matrix_bridge_mautrix_meta_messenger_identifier }} \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --network={{ matrix_bridge_mautrix_meta_messenger_container_network }} \ + {% if matrix_bridge_mautrix_meta_messenger_container_http_host_bind_port %} + -p {{ matrix_bridge_mautrix_meta_messenger_container_http_host_bind_port }}:29319 \ + {% endif %} + --mount type=bind,src={{ matrix_bridge_mautrix_meta_messenger_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_meta_messenger_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_meta_messenger_base_path }}/labels \ + {% for arg in matrix_bridge_mautrix_meta_messenger_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_bridge_mautrix_meta_messenger_container_image }} \ + /usr/bin/mautrix-meta -c /config/config.yaml -r /config/registration.yaml --no-update + +{% if matrix_bridge_mautrix_meta_messenger_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_meta_messenger_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_bridge_mautrix_meta_messenger_identifier }} +{% endfor %} +{% endif %} + +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_bridge_mautrix_meta_messenger_identifier }} + +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_bridge_mautrix_meta_messenger_identifier }} 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_bridge_mautrix_meta_messenger_identifier }} 2>/dev/null || true' +Restart=always +RestartSec=30 +SyslogIdentifier={{ matrix_bridge_mautrix_meta_messenger_identifier }} + +[Install] +WantedBy=multi-user.target diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/systemd/matrix-mautrix-meta.service.j2.license b/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/systemd/matrix-mautrix-meta-messenger.service.j2.license similarity index 100% rename from roles/custom/matrix-bridge-mautrix-meta-messenger/templates/systemd/matrix-mautrix-meta.service.j2.license rename to roles/custom/matrix-bridge-mautrix-meta-messenger/templates/systemd/matrix-mautrix-meta-messenger.service.j2.license diff --git a/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/systemd/matrix-mautrix-meta.service.j2 b/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/systemd/matrix-mautrix-meta.service.j2 deleted file mode 100644 index adf8a9c4e..000000000 --- a/roles/custom/matrix-bridge-mautrix-meta-messenger/templates/systemd/matrix-mautrix-meta.service.j2 +++ /dev/null @@ -1,51 +0,0 @@ -#jinja2: lstrip_blocks: True -[Unit] -Description=mautrix-meta bridge ({{ matrix_mautrix_meta_messenger_identifier }}) -{% for service in matrix_mautrix_meta_messenger_systemd_required_services_list %} -Requires={{ service }} -After={{ service }} -{% endfor %} -{% for service in matrix_mautrix_meta_messenger_systemd_wanted_services_list %} -Wants={{ service }} -{% endfor %} -DefaultDependencies=no - -[Service] -Type=simple -Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_mautrix_meta_messenger_identifier }} 2>/dev/null || true' -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_mautrix_meta_messenger_identifier }} 2>/dev/null || true' - -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ - --rm \ - --name={{ matrix_mautrix_meta_messenger_identifier }} \ - --log-driver=none \ - --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ - --cap-drop=ALL \ - --network={{ matrix_mautrix_meta_messenger_container_network }} \ - {% if matrix_mautrix_meta_messenger_container_http_host_bind_port %} - -p {{ matrix_mautrix_meta_messenger_container_http_host_bind_port }}:29319 \ - {% endif %} - --mount type=bind,src={{ matrix_mautrix_meta_messenger_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_mautrix_meta_messenger_data_path }},dst=/data \ - --label-file={{ matrix_mautrix_meta_messenger_base_path }}/labels \ - {% for arg in matrix_mautrix_meta_messenger_container_extra_arguments %} - {{ arg }} \ - {% endfor %} - {{ matrix_mautrix_meta_messenger_container_image }} \ - /usr/bin/mautrix-meta -c /config/config.yaml -r /config/registration.yaml --no-update - -{% for network in matrix_mautrix_meta_messenger_container_additional_networks %} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_mautrix_meta_messenger_identifier }} -{% endfor %} - -ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_mautrix_meta_messenger_identifier }} - -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_mautrix_meta_messenger_identifier }} 2>/dev/null || true' -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_mautrix_meta_messenger_identifier }} 2>/dev/null || true' -Restart=always -RestartSec=30 -SyslogIdentifier={{ matrix_mautrix_meta_messenger_identifier }} - -[Install] -WantedBy=multi-user.target diff --git a/roles/custom/matrix-bridge-mautrix-signal/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-signal/defaults/main.yml index 1553ea37c..0e2c0a70c 100644 --- a/roles/custom/matrix-bridge-mautrix-signal/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-signal/defaults/main.yml @@ -18,41 +18,47 @@ # mautrix-signal is a Matrix <-> Signal bridge # Project source code URL: https://github.com/mautrix/signal -matrix_mautrix_signal_enabled: true +matrix_bridge_mautrix_signal_enabled: true -matrix_mautrix_signal_container_image_self_build: false -matrix_mautrix_signal_container_image_self_build_repo: "https://mau.dev/mautrix/signal.git" -matrix_mautrix_signal_container_image_self_build_branch: "{{ 'main' if matrix_mautrix_signal_version == 'latest' else matrix_mautrix_signal_version }}" +matrix_bridge_mautrix_signal_container_image_self_build: false +matrix_bridge_mautrix_signal_container_image_self_build_repo: "https://mau.dev/mautrix/signal.git" +matrix_bridge_mautrix_signal_container_image_self_build_branch: "{{ 'main' if matrix_bridge_mautrix_signal_version == 'latest' else matrix_bridge_mautrix_signal_version }}" # renovate: datasource=docker depName=dock.mau.dev/mautrix/signal -matrix_mautrix_signal_version: v26.02.2 +matrix_bridge_mautrix_signal_version: v0.2608.0 # See: https://mau.dev/mautrix/signal/container_registry -matrix_mautrix_signal_container_image: "{{ matrix_mautrix_signal_container_image_registry_prefix }}mautrix/signal:{{ matrix_mautrix_signal_container_image_tag }}" -matrix_mautrix_signal_container_image_tag: "{{ matrix_mautrix_signal_version }}" -matrix_mautrix_signal_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_signal_container_image_self_build else matrix_mautrix_signal_container_image_registry_prefix_upstream }}" -matrix_mautrix_signal_container_image_registry_prefix_upstream: "{{ matrix_mautrix_signal_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_signal_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_signal_container_image_force_pull: "{{ matrix_mautrix_signal_container_image.endswith(':latest') }}" - -matrix_mautrix_signal_base_path: "{{ matrix_base_data_path }}/mautrix-signal" -matrix_mautrix_signal_config_path: "{{ matrix_mautrix_signal_base_path }}/config" -matrix_mautrix_signal_data_path: "{{ matrix_mautrix_signal_base_path }}/data" -matrix_mautrix_signal_container_src_files_path: "{{ matrix_mautrix_signal_base_path }}/docker-src" - -matrix_mautrix_signal_homeserver_address: "" -matrix_mautrix_signal_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_mautrix_signal_container_image: "{{ matrix_bridge_mautrix_signal_container_image_registry_prefix }}mautrix/signal:{{ matrix_bridge_mautrix_signal_container_image_tag }}" +matrix_bridge_mautrix_signal_container_image_tag: "{{ matrix_bridge_mautrix_signal_version }}" +matrix_bridge_mautrix_signal_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_signal_container_image_self_build else matrix_bridge_mautrix_signal_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_signal_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_signal_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_signal_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bridge_mautrix_signal_base_path: "{{ matrix_base_data_path }}/mautrix-signal" +matrix_bridge_mautrix_signal_config_path: "{{ matrix_bridge_mautrix_signal_base_path }}/config" +matrix_bridge_mautrix_signal_data_path: "{{ matrix_bridge_mautrix_signal_base_path }}/data" +matrix_bridge_mautrix_signal_container_src_files_path: "{{ matrix_bridge_mautrix_signal_base_path }}/docker-src" + +matrix_bridge_mautrix_signal_homeserver_address: "" +matrix_bridge_mautrix_signal_homeserver_domain: "{{ matrix_domain }}" # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_mautrix_signal_homeserver_async_media: false -matrix_mautrix_signal_appservice_address: "http://matrix-mautrix-signal:8080" +matrix_bridge_mautrix_signal_homeserver_async_media: false +matrix_bridge_mautrix_signal_appservice_address: "http://matrix-mautrix-signal:8080" -matrix_mautrix_signal_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" -matrix_mautrix_signal_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_signal_bridge_public_address`). +matrix_bridge_mautrix_signal_scheme: https -matrix_mautrix_signal_extev_polls: false +# The public base URL at which this bridge's HTTP API is reachable from outside (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_signal_bridge_public_address: "{{ (matrix_bridge_mautrix_signal_scheme + '://' + matrix_bridge_mautrix_signal_exposure_hostname + matrix_bridge_mautrix_signal_exposure_path_prefix) if matrix_bridge_mautrix_signal_exposure_enabled else '' }}" -matrix_mautrix_signal_command_prefix: "!signal" +matrix_bridge_mautrix_signal_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_signal_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" + +matrix_bridge_mautrix_signal_extev_polls: false + +matrix_bridge_mautrix_signal_command_prefix: "!signal" # Displayname template for Signal users. # {{.ProfileName}} - The Signal profile name set by the user. @@ -61,190 +67,179 @@ matrix_mautrix_signal_command_prefix: "!signal" # {{.PhoneNumber}} - The phone number of the user. # {{.UUID}} - The UUID of the Signal user. # {{.AboutEmoji}} - The emoji set by the user in their profile. -matrix_mautrix_signal_network_displayname_template: '{% raw %}{{or .ProfileName .PhoneNumber "Unknown user"}} (Signal){% endraw %}' +matrix_bridge_mautrix_signal_network_displayname_template: '{% raw %}{{or .ProfileName .PhoneNumber "Unknown user"}} (Signal){% endraw %}' -matrix_mautrix_signal_bridge_permissions: | +matrix_bridge_mautrix_signal_bridge_permissions: | {{ - {'*': 'relay', matrix_mautrix_signal_homeserver_domain: 'user'} + {'*': 'relay', matrix_bridge_mautrix_signal_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} # Enable bridge relay functionality -matrix_mautrix_signal_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" +matrix_bridge_mautrix_signal_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" # Only allow admins on this home server to set themselves as a relay user -matrix_mautrix_signal_bridge_relay_admin_only: true +matrix_bridge_mautrix_signal_bridge_relay_admin_only: true -matrix_mautrix_signal_container_network: "" +matrix_bridge_mautrix_signal_container_network: "" -matrix_mautrix_signal_container_additional_networks: "{{ matrix_mautrix_signal_container_additional_networks_auto + matrix_mautrix_signal_container_additional_networks_custom }}" -matrix_mautrix_signal_container_additional_networks_auto: [] -matrix_mautrix_signal_container_additional_networks_custom: [] +matrix_bridge_mautrix_signal_container_additional_networks: "{{ matrix_bridge_mautrix_signal_container_additional_networks_auto + matrix_bridge_mautrix_signal_container_additional_networks_custom }}" +matrix_bridge_mautrix_signal_container_additional_networks_auto: [] +matrix_bridge_mautrix_signal_container_additional_networks_custom: [] -# matrix_mautrix_signal_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_mautrix_signal_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_signal_container_labels_additional_labels`. -matrix_mautrix_signal_container_labels_traefik_enabled: true -matrix_mautrix_signal_container_labels_traefik_docker_network: "{{ matrix_mautrix_signal_container_network }}" -matrix_mautrix_signal_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_signal_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose mautrix-instagram's metrics -matrix_mautrix_signal_container_labels_metrics_enabled: "{{ matrix_mautrix_signal_metrics_enabled and matrix_mautrix_signal_metrics_proxying_enabled }}" -matrix_mautrix_signal_container_labels_metrics_traefik_rule: "Host(`{{ matrix_mautrix_signal_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_mautrix_signal_metrics_proxying_path_prefix }}`)" -matrix_mautrix_signal_container_labels_metrics_traefik_priority: 0 -matrix_mautrix_signal_container_labels_metrics_traefik_entrypoints: "{{ matrix_mautrix_signal_container_labels_traefik_entrypoints }}" -matrix_mautrix_signal_container_labels_metrics_traefik_tls: "{{ matrix_mautrix_signal_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_mautrix_signal_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_mautrix_signal_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_mautrix_signal_container_labels_metrics_middleware_basic_auth_enabled: false -# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_mautrix_signal_container_labels_metrics_middleware_basic_auth_users: '' - -# matrix_mautrix_signal_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# To inject your own other container labels, see `matrix_bridge_mautrix_signal_container_labels_additional_labels`. +matrix_bridge_mautrix_signal_container_labels_traefik_enabled: true +matrix_bridge_mautrix_signal_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_signal_container_network }}" +matrix_bridge_mautrix_signal_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_signal_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-signal's HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_signal_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_signal_exposure_enabled }}" +matrix_bridge_mautrix_signal_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_signal_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_signal_exposure_path_prefix }}`)" +matrix_bridge_mautrix_signal_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_signal_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_signal_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_signal_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_signal_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_signal_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_signal_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_signal_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_signal_container_labels_additional_labels: | +# matrix_bridge_mautrix_signal_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_signal_container_labels_additional_labels: '' +matrix_bridge_mautrix_signal_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_signal_container_extra_arguments: [] +matrix_bridge_mautrix_signal_container_extra_arguments: [] # List of systemd services that matrix-mautrix-signal.service depends on. -matrix_mautrix_signal_systemd_required_services_list: "{{ matrix_mautrix_signal_systemd_required_services_list_default + matrix_mautrix_signal_systemd_required_services_list_auto + matrix_mautrix_signal_systemd_required_services_list_custom }}" -matrix_mautrix_signal_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_signal_systemd_required_services_list_auto: [] -matrix_mautrix_signal_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_signal_systemd_required_services_list: "{{ matrix_bridge_mautrix_signal_systemd_required_services_list_default + matrix_bridge_mautrix_signal_systemd_required_services_list_auto + matrix_bridge_mautrix_signal_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_signal_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_signal_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_signal_systemd_required_services_list_custom: [] # List of systemd services that matrix-mautrix-signal.service wants -matrix_mautrix_signal_systemd_wanted_services_list: [] +matrix_bridge_mautrix_signal_systemd_wanted_services_list: [] -matrix_mautrix_signal_appservice_token: '' -matrix_mautrix_signal_homeserver_token: '' +matrix_bridge_mautrix_signal_appservice_token: '' +matrix_bridge_mautrix_signal_homeserver_token: '' -matrix_mautrix_signal_appservice_bot_username: signalbot +matrix_bridge_mautrix_signal_appservice_bot_username: signalbot # Minimum severity of journal log messages. # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_signal_logging_level: 'warn' +matrix_bridge_mautrix_signal_logging_level: 'warn' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_mautrix_signal_federate_rooms: true - -matrix_mautrix_signal_backfill_enabled: true -matrix_mautrix_signal_backfill_max_initial_messages: 50 -matrix_mautrix_signal_backfill_max_catchup_messages: 500 -matrix_mautrix_signal_backfill_unread_hours_threshold: 720 -matrix_mautrix_signal_backfill_threads_max_initial_messages: 50 +matrix_bridge_mautrix_signal_federate_rooms: true -# Whether or not metrics endpoint should be enabled. -# Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_mautrix_signal_metrics_proxying_enabled`. -matrix_mautrix_signal_metrics_enabled: false +matrix_bridge_mautrix_signal_backfill_enabled: true +matrix_bridge_mautrix_signal_backfill_max_initial_messages: 50 +matrix_bridge_mautrix_signal_backfill_max_catchup_messages: 500 +matrix_bridge_mautrix_signal_backfill_unread_hours_threshold: 720 +matrix_bridge_mautrix_signal_backfill_threads_max_initial_messages: 50 -# Controls whether metrics should be exposed on a public URL. -matrix_mautrix_signal_metrics_proxying_enabled: false -matrix_mautrix_signal_metrics_proxying_hostname: '' -matrix_mautrix_signal_metrics_proxying_path_prefix: '' +# Controls whether mautrix-signal's HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_signal_exposure_enabled: false +matrix_bridge_mautrix_signal_exposure_hostname: '' +matrix_bridge_mautrix_signal_exposure_path_prefix: '' # Database-related configuration fields. # # To use SQLite, stick to these defaults. # # To use Postgres: -# - change the engine (`matrix_mautrix_signal_database_engine: 'postgres'`) -# - adjust your database credentials via the `matrix_mautrix_signal_database_*` variables -matrix_mautrix_signal_database_engine: 'sqlite' - -matrix_mautrix_signal_sqlite_database_path_local: "{{ matrix_mautrix_signal_data_path }}/mautrix-signal.db" -matrix_mautrix_signal_sqlite_database_path_in_container: "/data/mautrix-signal.db?_txlock=immediate" - -matrix_mautrix_signal_database_username: 'matrix_mautrix_signal' -matrix_mautrix_signal_database_password: 'some-password' -matrix_mautrix_signal_database_hostname: '' -matrix_mautrix_signal_database_port: 5432 -matrix_mautrix_signal_database_name: 'matrix_mautrix_signal' -matrix_mautrix_signal_database_sslmode: disable - -matrix_mautrix_signal_database_connection_string: 'postgresql://{{ matrix_mautrix_signal_database_username }}:{{ matrix_mautrix_signal_database_password }}@{{ matrix_mautrix_signal_database_hostname }}:{{ matrix_mautrix_signal_database_port }}/{{ matrix_mautrix_signal_database_name }}?sslmode={{ matrix_mautrix_signal_database_sslmode }}' - -matrix_mautrix_signal_appservice_database_type: "{{ - { - 'sqlite': 'sqlite3-fk-wal', - 'postgres':'postgres', - }[matrix_mautrix_signal_database_engine] -}}" - -matrix_mautrix_signal_appservice_database_uri: "{{ - { - 'sqlite': matrix_mautrix_signal_sqlite_database_path_in_container, - 'postgres': matrix_mautrix_signal_database_connection_string, - }[matrix_mautrix_signal_database_engine] -}}" - -matrix_mautrix_signal_double_puppet_secrets: "{{ matrix_mautrix_signal_double_puppet_secrets_auto | combine(matrix_mautrix_signal_double_puppet_secrets_custom) }}" -matrix_mautrix_signal_double_puppet_secrets_auto: {} -matrix_mautrix_signal_double_puppet_secrets_custom: {} +# - change the engine (`matrix_bridge_mautrix_signal_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_mautrix_signal_database_*` variables +matrix_bridge_mautrix_signal_database_engine: 'sqlite' + +matrix_bridge_mautrix_signal_sqlite_database_path_local: "{{ matrix_bridge_mautrix_signal_data_path }}/mautrix-signal.db" +matrix_bridge_mautrix_signal_sqlite_database_path_in_container: "/data/mautrix-signal.db?_txlock=immediate" + +matrix_bridge_mautrix_signal_database_username: 'matrix_mautrix_signal' +matrix_bridge_mautrix_signal_database_password: 'some-password' +matrix_bridge_mautrix_signal_database_hostname: '' +matrix_bridge_mautrix_signal_database_port: 5432 +matrix_bridge_mautrix_signal_database_name: 'matrix_mautrix_signal' +matrix_bridge_mautrix_signal_database_sslmode: disable + +matrix_bridge_mautrix_signal_database_connection_string: 'postgresql://{{ matrix_bridge_mautrix_signal_database_username }}:{{ matrix_bridge_mautrix_signal_database_password }}@{{ matrix_bridge_mautrix_signal_database_hostname }}:{{ matrix_bridge_mautrix_signal_database_port }}/{{ matrix_bridge_mautrix_signal_database_name }}?sslmode={{ matrix_bridge_mautrix_signal_database_sslmode }}' + +matrix_bridge_mautrix_signal_appservice_database_type: "{{ { + 'sqlite': 'sqlite3-fk-wal', + 'postgres': 'postgres', +}[matrix_bridge_mautrix_signal_database_engine] }}" + +matrix_bridge_mautrix_signal_appservice_database_uri: "{{ { + 'sqlite': matrix_bridge_mautrix_signal_sqlite_database_path_in_container, + 'postgres': matrix_bridge_mautrix_signal_database_connection_string, +}[matrix_bridge_mautrix_signal_database_engine] }}" + +matrix_bridge_mautrix_signal_double_puppet_secrets: "{{ matrix_bridge_mautrix_signal_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_signal_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_signal_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_signal_double_puppet_secrets_custom: {} # Default mautrix-signal configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_signal_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_signal_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_signal_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_signal_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_signal_configuration_extension_yaml: | +matrix_bridge_mautrix_signal_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_signal_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_signal_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_signal_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_signal_configuration_yaml`. -matrix_mautrix_signal_configuration_extension: "{{ matrix_mautrix_signal_configuration_extension_yaml | from_yaml if matrix_mautrix_signal_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_signal_configuration_extension: "{{ matrix_bridge_mautrix_signal_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_signal_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_signal_configuration_yaml`. -matrix_mautrix_signal_configuration: "{{ matrix_mautrix_signal_configuration_yaml | from_yaml | combine(matrix_mautrix_signal_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_signal_configuration_yaml`. +matrix_bridge_mautrix_signal_configuration: "{{ matrix_bridge_mautrix_signal_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_signal_configuration_extension, recursive=True) }}" -matrix_mautrix_signal_registration_yaml: | +matrix_bridge_mautrix_signal_registration_yaml: | id: signal - url: {{ matrix_mautrix_signal_appservice_address }} - as_token: "{{ matrix_mautrix_signal_appservice_token }}" - hs_token: "{{ matrix_mautrix_signal_homeserver_token }}" + url: {{ matrix_bridge_mautrix_signal_appservice_address }} + as_token: "{{ matrix_bridge_mautrix_signal_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_signal_homeserver_token }}" # See https://github.com/mautrix/signal/issues/43 - sender_localpart: _bot_{{ matrix_mautrix_signal_appservice_bot_username }} + sender_localpart: _bot_{{ matrix_bridge_mautrix_signal_appservice_bot_username }} rate_limited: false namespaces: users: - - regex: '^@signal_[-a-f0-9]+:{{ matrix_mautrix_signal_homeserver_domain | regex_escape }}$' + - regex: '^@signal_[-a-f0-9]+:{{ matrix_bridge_mautrix_signal_homeserver_domain | regex_escape }}$' exclusive: true - exclusive: true - regex: '^@{{ matrix_mautrix_signal_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_signal_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_mautrix_signal_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_signal_homeserver_domain | regex_escape }}$' de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_mautrix_signal_msc4190_enabled | to_json }} + io.element.msc4190: {{ matrix_bridge_mautrix_signal_msc4190_enabled | to_json }} -matrix_mautrix_signal_registration: "{{ matrix_mautrix_signal_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_signal_registration: "{{ matrix_bridge_mautrix_signal_registration_yaml | from_yaml }}" # Enable End-to-bridge encryption -matrix_mautrix_signal_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_signal_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_mautrix_signal_bridge_encryption_key_sharing_allow: "{{ matrix_mautrix_signal_bridge_encryption_allow }}" +matrix_bridge_mautrix_signal_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_signal_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_signal_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_mautrix_signal_bridge_encryption_allow }}" -matrix_mautrix_signal_bridge_personal_filtering_spaces: true +matrix_bridge_mautrix_signal_bridge_personal_filtering_spaces: true -matrix_mautrix_signal_network_note_to_self_avatar: "mxc://maunium.net/REBIVrqjZwmaWpssCZpBlmlL" +matrix_bridge_mautrix_signal_network_note_to_self_avatar: "mxc://maunium.net/REBIVrqjZwmaWpssCZpBlmlL" -matrix_mautrix_signal_provisioning_shared_secret: '' -matrix_mautrix_signal_public_media_signing_key: '' +matrix_bridge_mautrix_signal_provisioning_shared_secret: '' +matrix_bridge_mautrix_signal_public_media_signing_key: '' -# matrix_mautrix_signal_restart_necessary controls whether the service +# matrix_bridge_mautrix_signal_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -252,4 +247,4 @@ matrix_mautrix_signal_public_media_signing_key: '' # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_signal_restart_necessary: false +matrix_bridge_mautrix_signal_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-signal/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-signal/molecule/default/converge.yml new file mode 100644 index 000000000..6bfeb6f9d --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-signal/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-signal Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-signal Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-signal is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-signal systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-signal.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-signal/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-signal/molecule/default/molecule.yml new file mode 100644 index 000000000..f30b10e71 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-signal/molecule/default/molecule.yml @@ -0,0 +1,94 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-signal-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_signal_container_network: mautrix-signal-molecule + + # The stub prepare.yml stands up. It is not a real homeserver and the scenario + # deliberately carries no Signal credentials or linked Signal account. + matrix_bridge_mautrix_signal_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_signal_homeserver_domain: molecule.local + + # Postgres is what group_vars/matrix_servers selects whenever Postgres is enabled, + # which is the default deployment path. The non-default database and user names make + # schema creation evidence that the role composed and supplied this connection string. + matrix_bridge_mautrix_signal_database_engine: postgres + matrix_bridge_mautrix_signal_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_signal_database_name: molecule_signal + matrix_bridge_mautrix_signal_database_username: molecule_signal + matrix_bridge_mautrix_signal_database_password: molecule_pg_password_b723e1 + + # These are only Molecule fixtures which must reach both the configuration and the + # registration. They do not authenticate against a real homeserver. + matrix_bridge_mautrix_signal_appservice_token: molecule_signal_as_token_0c981a + matrix_bridge_mautrix_signal_homeserver_token: molecule_signal_hs_token_45de72 + + # Each differs from the role's default, so structural checks can distinguish the + # role's rendered values from values the bridge would have chosen on its own. + matrix_bridge_mautrix_signal_appservice_bot_username: molecule-signalbot + matrix_bridge_mautrix_signal_command_prefix: "!molecule-signal" + matrix_bridge_mautrix_signal_logging_level: info + matrix_bridge_mautrix_signal_federate_rooms: false + matrix_bridge_mautrix_signal_extev_polls: true + matrix_bridge_mautrix_signal_bridge_relay_enabled: true + matrix_bridge_mautrix_signal_bridge_relay_admin_only: false + matrix_bridge_mautrix_signal_backfill_max_initial_messages: 17 + + # Traefik is not started. These values exercise the role's composition of both the + # public address the bridge reads and the exposure labels Docker consumes. + matrix_bridge_mautrix_signal_exposure_enabled: true + matrix_bridge_mautrix_signal_exposure_hostname: signal-api.molecule.local + matrix_bridge_mautrix_signal_exposure_path_prefix: /bridges/signal-api + matrix_bridge_mautrix_signal_scheme: http + matrix_bridge_mautrix_signal_container_labels_traefik_entrypoints: web + matrix_bridge_mautrix_signal_container_labels_additional_labels: | + molecule.signal.coverage=enabled + + # verify.yml is a separate play, where role defaults are out of scope, so paths it + # reads are pinned here to the values the role derives during converge. + matrix_bridge_mautrix_signal_base_path: /matrix/mautrix-signal + matrix_bridge_mautrix_signal_config_path: /matrix/mautrix-signal/config + matrix_bridge_mautrix_signal_data_path: /matrix/mautrix-signal/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-signal/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-signal/molecule/default/prepare.yml new file mode 100644 index 000000000..914704550 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-signal/molecule/default/prepare.yml @@ -0,0 +1,91 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-signal Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks set owner/group by name, which Ansible resolves through the + # passwd database. matrix-base creates these in a complete playbook run. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role creates this during converge, but both dependencies below must attach to it + # first, so prepare creates it early. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_signal_container_network }}" + register: mautrix_signal_molecule_network + changed_when: mautrix_signal_molecule_network.rc == 0 + failed_when: + - mautrix_signal_molecule_network.rc != 0 + - "'already exists' not in mautrix_signal_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_signal_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_signal_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_signal_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_signal_database_password }}" + + # The bridge calls /whoami while starting and refuses to run if it does not name its bot. + # No Signal login is attempted: an unlinked, idle bridge is the intended test state. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_signal_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_signal_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_signal_appservice_bot_username }}:{{ matrix_bridge_mautrix_signal_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-signal/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-signal/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-signal/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-signal/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-signal/molecule/default/verify.yml new file mode 100644 index 000000000..6bdf1b7cc --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-signal/molecule/default/verify.yml @@ -0,0 +1,271 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the bridge starts without a Signal account, accepts the configuration and +# registration the role rendered, becomes ready against the homeserver stub, migrates its +# Postgres schema, and carries the role's runtime identity and public-exposure wiring. +- name: Verify mautrix-signal + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + # Lazily evaluated after the corresponding slurp. Keeping these as play vars avoids + # repeatedly templating the Go templates embedded in the bridge configuration. + vars: + mautrix_signal_config: "{{ mautrix_signal_config_file.content | b64decode | from_yaml }}" + mautrix_signal_registration: "{{ mautrix_signal_registration_file.content | b64decode | from_yaml }}" + mautrix_signal_labels_rendered: "{{ mautrix_signal_labels.content | b64decode }}" + mautrix_signal_expected_public_address: http://signal-api.molecule.local/bridges/signal-api + gather_facts: false + + tasks: + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_signal_role_defaults + + - name: Wait for the mautrix-signal service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-signal.service + register: mautrix_signal_service + until: mautrix_signal_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes ActiveState alone insufficient for a crash-looping bridge. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_signal_service.status.ActiveState == 'active' + - mautrix_signal_service.status.NRestarts is defined + - mautrix_signal_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-signal.service is + {{ mautrix_signal_service.status.ActiveState | default('unknown') }} + after {{ mautrix_signal_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-mautrix-signal.service is active and has not restarted" + + # /live proves the appservice listener opened; /ready additionally proves startup passed + # the homeserver identity check and database initialization. + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_signal_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-signal:8080/_matrix/mau/live + register: mautrix_signal_live + changed_when: false + until: "'HTTP_STATUS=200' in mautrix_signal_live.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_signal_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-signal:8080/_matrix/mau/ready + register: mautrix_signal_ready + changed_when: false + until: "'HTTP_STATUS=200' in mautrix_signal_ready.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on its appservice port + ansible.builtin.assert: + that: + - "'HTTP_STATUS=200' in mautrix_signal_live.stdout" + - "'HTTP_STATUS=200' in mautrix_signal_ready.stdout" + fail_msg: >- + The appservice health responses were live={{ mautrix_signal_live.stdout | default('none') }} + and ready={{ mautrix_signal_ready.stdout | default('none') }} + success_msg: "The bridge is live and ready on its appservice port" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_signal_config_path }}/config.yaml" + register: mautrix_signal_config_file + + - name: Assert the rendered configuration carries this scenario's values + ansible.builtin.assert: + that: + - mautrix_signal_config.homeserver.address == matrix_bridge_mautrix_signal_homeserver_address + - mautrix_signal_config.homeserver.domain == matrix_bridge_mautrix_signal_homeserver_domain + - mautrix_signal_config.appservice.bot.username == matrix_bridge_mautrix_signal_appservice_bot_username + - mautrix_signal_config.appservice.as_token == matrix_bridge_mautrix_signal_appservice_token + - mautrix_signal_config.appservice.hs_token == matrix_bridge_mautrix_signal_homeserver_token + - mautrix_signal_config.appservice.public_address == mautrix_signal_expected_public_address + - mautrix_signal_config.bridge.command_prefix == matrix_bridge_mautrix_signal_command_prefix + - mautrix_signal_config.bridge.relay.enabled + - not mautrix_signal_config.bridge.relay.admin_only + - not mautrix_signal_config.matrix.federate_rooms + - mautrix_signal_config.network.extev_polls + - mautrix_signal_config.backfill.max_initial_messages == 17 + - mautrix_signal_config.logging.min_level == matrix_bridge_mautrix_signal_logging_level + fail_msg: "The rendered configuration does not carry the scenario's non-default values" + success_msg: "The rendered configuration carries the scenario's non-default values" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - mautrix_signal_config.database.type == matrix_bridge_mautrix_signal_database_engine + - matrix_bridge_mautrix_signal_database_username in mautrix_signal_config.database.uri + - matrix_bridge_mautrix_signal_database_hostname in mautrix_signal_config.database.uri + - matrix_bridge_mautrix_signal_database_name in mautrix_signal_config.database.uri + fail_msg: >- + database.uri is {{ mautrix_signal_config.database.uri | default('unset') }}, which + was not composed from the scenario's connection settings + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_signal_config_path }}/registration.yaml" + register: mautrix_signal_registration_file + + - name: Assert the registration carries the tokens, identity and address + ansible.builtin.assert: + that: + - mautrix_signal_registration.id == 'signal' + - mautrix_signal_registration.as_token == matrix_bridge_mautrix_signal_appservice_token + - mautrix_signal_registration.hs_token == matrix_bridge_mautrix_signal_homeserver_token + - mautrix_signal_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_signal_appservice_bot_username + - mautrix_signal_registration.url == 'http://matrix-mautrix-signal:8080' + fail_msg: "The appservice registration does not carry the expected identity and tokens" + success_msg: "The appservice registration carries the expected identity and tokens" + + - name: Assert the registration namespaces cover the bot and Signal ghosts + ansible.builtin.assert: + that: + - mautrix_signal_ghost_regex | length > 0 + - mautrix_signal_bot_regex | length > 0 + - mautrix_signal_ghost_mxid is match(mautrix_signal_ghost_regex) + - mautrix_signal_wrong_ghost_mxid is not match(mautrix_signal_ghost_regex) + - mautrix_signal_bot_mxid is match(mautrix_signal_bot_regex) + fail_msg: "The registration namespaces do not cover the bot and Signal ghost identities" + success_msg: "The registration namespaces cover the bot and Signal ghost identities" + vars: + mautrix_signal_user_regexes: "{{ mautrix_signal_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_signal_ghost_regex: "{{ mautrix_signal_user_regexes | select('search', 'signal_') | first | default('') }}" + mautrix_signal_bot_regex: "{{ mautrix_signal_user_regexes | reject('search', 'signal_') | first | default('') }}" + mautrix_signal_ghost_mxid: "@signal_01234567-89ab-cdef-0123-456789abcdef:{{ matrix_bridge_mautrix_signal_homeserver_domain }}" + mautrix_signal_wrong_ghost_mxid: "@telegram_01234567-89ab-cdef-0123-456789abcdef:{{ matrix_bridge_mautrix_signal_homeserver_domain }}" + mautrix_signal_bot_mxid: "@{{ matrix_bridge_mautrix_signal_appservice_bot_username }}:{{ matrix_bridge_mautrix_signal_homeserver_domain }}" + + # Tables can only appear after hostname resolution, authentication, and migrations. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_signal_database_username }} + - --dbname={{ matrix_bridge_mautrix_signal_database_name }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: mautrix_signal_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - mautrix_signal_tables.rc == 0 + - "'version' in mautrix_signal_table_names" + - mautrix_signal_table_names | length > 5 + fail_msg: >- + The bridge did not create its schema in {{ matrix_bridge_mautrix_signal_database_name }} + (found {{ mautrix_signal_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + mautrix_signal_table_names: "{{ mautrix_signal_tables.stdout_lines | select | list }}" + + - name: Read the running container's image and user identity + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-signal + - --format + - "{{ '{{' }} .Config.Image {{ '}}' }}|{{ '{{' }} .Config.User {{ '}}' }}" + register: mautrix_signal_container_identity + changed_when: false + + - name: Assert the running container uses the exact pinned image + ansible.builtin.assert: + that: + - mautrix_signal_container_image == 'dock.mau.dev/mautrix/signal:' + mautrix_signal_role_defaults.matrix_bridge_mautrix_signal_version + fail_msg: "The running container does not use the exact image the role pins" + success_msg: "The running container uses the exact image the role pins" + vars: + mautrix_signal_container_image: "{{ mautrix_signal_container_identity.stdout.split('|')[0] }}" + + - name: Assert the running container uses the playbook-supplied identity + ansible.builtin.assert: + that: + - mautrix_signal_container_user == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + fail_msg: "The running container does not use the {{ matrix_user_uid }}:{{ matrix_user_gid }} identity" + success_msg: "The running container uses the playbook-supplied identity" + vars: + mautrix_signal_container_user: "{{ mautrix_signal_container_identity.stdout.split('|')[1] }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_signal_base_path }}/labels" + register: mautrix_signal_labels + + - name: Assert the labels route the public endpoint to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_signal_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_signal_container_network in mautrix_signal_labels_rendered" + - "'traefik.http.services.matrix-mautrix-signal-exposure.loadbalancer.server.port=8080' in mautrix_signal_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-signal-exposure.rule=Host(`signal-api.molecule.local`) && PathPrefix(`/bridges/signal-api`)' in mautrix_signal_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-signal-exposure-strip-prefix.stripprefix.prefixes=/bridges/signal-api' in mautrix_signal_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-signal-exposure.entrypoints=web' in mautrix_signal_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-signal-exposure.tls=false' in mautrix_signal_labels_rendered" + - "'molecule.signal.coverage=enabled' in mautrix_signal_labels_rendered" + fail_msg: "The rendered labels do not carry the scenario's exposure configuration" + success_msg: "The rendered labels carry the scenario's exposure configuration" + + - name: Read the custom label Docker attached to the running container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-signal + - --format + - "{{ '{{' }} index .Config.Labels \"molecule.signal.coverage\" {{ '}}' }}" + register: mautrix_signal_container_label + changed_when: false + + - name: Assert Docker accepted the label file the role rendered + ansible.builtin.assert: + that: + - mautrix_signal_container_label.stdout == 'enabled' + fail_msg: "Docker did not attach the role's custom Molecule label" + success_msg: "Docker accepted the label file the role rendered" diff --git a/roles/custom/matrix-bridge-mautrix-signal/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-signal/tasks/main.yml index 60266ba91..4afcdd07b 100644 --- a/roles/custom/matrix-bridge-mautrix-signal/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-signal/tasks/main.yml @@ -22,15 +22,15 @@ - install-all - install-mautrix-signal block: - - when: matrix_mautrix_signal_enabled | bool + - when: matrix_bridge_mautrix_signal_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_signal_enabled | bool + - when: matrix_bridge_mautrix_signal_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mautrix-signal block: - - when: not matrix_mautrix_signal_enabled | bool + - when: not matrix_bridge_mautrix_signal_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-signal/tasks/remove_legacy.yml b/roles/custom/matrix-bridge-mautrix-signal/tasks/remove_legacy.yml index f566606fc..d4a509221 100644 --- a/roles/custom/matrix-bridge-mautrix-signal/tasks/remove_legacy.yml +++ b/roles/custom/matrix-bridge-mautrix-signal/tasks/remove_legacy.yml @@ -8,9 +8,9 @@ - name: Check existence of matrix-mautrix-signal-daemon service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-signal-daemon.service" - register: matrix_mautrix_signal_daemon_service_stat + register: matrix_bridge_mautrix_signal_daemon_service_stat -- when: matrix_mautrix_signal_daemon_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_signal_daemon_service_stat.stat.exists | bool block: - name: Ensure matrix-mautrix-signal-daemon is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mautrix-signal/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-signal/tasks/setup_install.yml index 7df39e6a1..3d6bbbb30 100644 --- a/roles/custom/matrix-bridge-mautrix-signal/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-signal/tasks/setup_install.yml @@ -13,32 +13,32 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_signal_migration_requires_restart: false + matrix_bridge_mautrix_signal_migration_requires_restart: false -- when: "matrix_mautrix_signal_database_engine == 'postgres'" +- when: "matrix_bridge_mautrix_signal_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mautrix_signal_sqlite_database_path_local }}" - register: matrix_mautrix_signal_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mautrix_signal_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_signal_sqlite_database_path_local_stat_result - - when: "matrix_mautrix_signal_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mautrix_signal_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mautrix_signal_sqlite_database_path_local }}" - dst: "{{ matrix_mautrix_signal_database_connection_string }}" + src: "{{ matrix_bridge_mautrix_signal_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_signal_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mautrix_signal_database_engine' + engine_variable_name: 'matrix_bridge_mautrix_signal_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-mautrix-signal.service'] pgloader_options: ['--with "quote identifiers"'] - ansible.builtin.set_fact: - matrix_mautrix_signal_migration_requires_restart: true + matrix_bridge_mautrix_signal_migration_requires_restart: true - name: Ensure Mautrix signal paths exists ansible.builtin.file: @@ -48,56 +48,62 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_signal_base_path }}", when: true} - - {path: "{{ matrix_mautrix_signal_config_path }}", when: true} - - {path: "{{ matrix_mautrix_signal_data_path }}", when: true} - - {path: "{{ matrix_mautrix_signal_container_src_files_path }}", when: "{{ matrix_mautrix_signal_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_signal_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_signal_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_signal_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_signal_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_signal_container_image_self_build }}"} when: item.when | bool - name: Ensure Mautrix signal image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_signal_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_signal_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_signal_container_image_force_pull }}" - when: not matrix_mautrix_signal_container_image_self_build - register: matrix_mautrix_signal_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_signal_container_image }}" + pull: always + when: not matrix_bridge_mautrix_signal_container_image_self_build + register: matrix_bridge_mautrix_signal_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_signal_container_image_pull_result is not failed + until: matrix_bridge_mautrix_signal_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix signal repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_signal_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_signal_container_image_self_build | bool" - name: Ensure Mautrix signal repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_mautrix_signal_container_image_self_build_repo }}" - dest: "{{ matrix_mautrix_signal_container_src_files_path }}" - version: "{{ matrix_mautrix_signal_container_image_self_build_branch }}" + repo: "{{ matrix_bridge_mautrix_signal_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_mautrix_signal_container_src_files_path }}" + version: "{{ matrix_bridge_mautrix_signal_container_image_self_build_branch }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_signal_git_pull_results - when: "matrix_mautrix_signal_container_image_self_build | bool" + register: matrix_bridge_mautrix_signal_git_pull_results + when: "matrix_bridge_mautrix_signal_container_image_self_build | bool" - name: Ensure Mautrix signal Docker image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_signal_container_image }}" - source: build - force_source: "{{ matrix_mautrix_signal_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_signal_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_signal_container_src_files_path }}" - pull: true - when: "matrix_mautrix_signal_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_signal_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_signal_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_signal_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_signal_container_image_self_build | bool" + register: matrix_bridge_mautrix_signal_container_image_build_result - name: Check if an old database file exists ansible.builtin.stat: - path: "{{ matrix_mautrix_signal_base_path }}/mautrix-signal.db" - register: matrix_mautrix_signal_stat_database + path: "{{ matrix_bridge_mautrix_signal_base_path }}/mautrix-signal.db" + register: matrix_bridge_mautrix_signal_stat_database - name: Check if an old Matrix state file exists ansible.builtin.stat: - path: "{{ matrix_mautrix_signal_base_path }}/mx-state.json" - register: matrix_mautrix_signal_stat_mx_state + path: "{{ matrix_bridge_mautrix_signal_base_path }}/mx-state.json" + register: matrix_bridge_mautrix_signal_stat_mx_state - name: (Data relocation) Ensure matrix-mautrix-signal.service is stopped ansible.builtin.service: @@ -106,55 +112,56 @@ enabled: false daemon_reload: true failed_when: false - when: "matrix_mautrix_signal_stat_database.stat.exists" + when: "matrix_bridge_mautrix_signal_stat_database.stat.exists" - name: (Data relocation) Move mautrix-signal database file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_mautrix_signal_base_path }}/mautrix-signal.db {{ matrix_mautrix_signal_data_path }}/mautrix-signal.db" - creates: "{{ matrix_mautrix_signal_data_path }}/mautrix-signal.db" - removes: "{{ matrix_mautrix_signal_base_path }}/mautrix-signal.db" - when: "matrix_mautrix_signal_stat_database.stat.exists" + cmd: "mv {{ matrix_bridge_mautrix_signal_base_path }}/mautrix-signal.db {{ matrix_bridge_mautrix_signal_data_path }}/mautrix-signal.db" + creates: "{{ matrix_bridge_mautrix_signal_data_path }}/mautrix-signal.db" + removes: "{{ matrix_bridge_mautrix_signal_base_path }}/mautrix-signal.db" + when: "matrix_bridge_mautrix_signal_stat_database.stat.exists" - name: (Data relocation) Move mautrix-signal mx-state file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_mautrix_signal_base_path }}/mx-state.json {{ matrix_mautrix_signal_data_path }}/mx-state.json" - creates: "{{ matrix_mautrix_signal_data_path }}/mx-state.json" - removes: "{{ matrix_mautrix_signal_base_path }}/mx-state.json" - when: "matrix_mautrix_signal_stat_mx_state.stat.exists" + cmd: "mv {{ matrix_bridge_mautrix_signal_base_path }}/mx-state.json {{ matrix_bridge_mautrix_signal_data_path }}/mx-state.json" + creates: "{{ matrix_bridge_mautrix_signal_data_path }}/mx-state.json" + removes: "{{ matrix_bridge_mautrix_signal_base_path }}/mx-state.json" + when: "matrix_bridge_mautrix_signal_stat_mx_state.stat.exists" - name: Ensure mautrix-signal config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_signal_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_signal_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_signal_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_signal_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_signal_config_result + register: matrix_bridge_mautrix_signal_config_result - name: Ensure mautrix-signal registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_signal_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_signal_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_signal_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_signal_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_signal_registration_result + register: matrix_bridge_mautrix_signal_registration_result - name: Ensure mautrix-signal support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_signal_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_signal_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_mautrix_signal_support_files_result + register: matrix_bridge_mautrix_signal_support_files_result - name: Ensure matrix-mautrix-signal container network is created + when: matrix_bridge_mautrix_signal_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_signal_container_network }}" + name: "{{ matrix_bridge_mautrix_signal_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -163,18 +170,19 @@ src: "{{ role_path }}/templates/systemd/matrix-mautrix-signal.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-signal.service" mode: '0644' - register: matrix_mautrix_signal_systemd_service_result + register: matrix_bridge_mautrix_signal_systemd_service_result - name: Determine whether matrix-mautrix-signal needs a restart ansible.builtin.set_fact: - matrix_mautrix_signal_restart_necessary: >- + matrix_bridge_mautrix_signal_restart_necessary: >- {{ - matrix_mautrix_signal_migration_requires_restart | default(false) - or matrix_mautrix_signal_config_result.changed | default(false) - or matrix_mautrix_signal_registration_result.changed | default(false) - or matrix_mautrix_signal_support_files_result.changed | default(false) - or matrix_mautrix_signal_systemd_service_result.changed | default(false) - or matrix_mautrix_signal_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_signal_migration_requires_restart | default(false) + or matrix_bridge_mautrix_signal_config_result.changed | default(false) + or matrix_bridge_mautrix_signal_registration_result.changed | default(false) + or matrix_bridge_mautrix_signal_support_files_result.changed | default(false) + or matrix_bridge_mautrix_signal_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_signal_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_signal_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mautrix-signal.service restarted, if necessary @@ -182,4 +190,4 @@ name: "matrix-mautrix-signal.service" state: restarted daemon_reload: true - when: "matrix_mautrix_signal_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_signal_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-signal/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-signal/tasks/setup_uninstall.yml index 79e3f8249..ef9a1ca15 100644 --- a/roles/custom/matrix-bridge-mautrix-signal/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-signal/tasks/setup_uninstall.yml @@ -11,9 +11,9 @@ - name: Check existence of matrix-mautrix-signal service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-signal.service" - register: matrix_mautrix_signal_service_stat + register: matrix_bridge_mautrix_signal_service_stat -- when: matrix_mautrix_signal_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_signal_service_stat.stat.exists | bool block: - name: Ensure matrix-mautrix-signal is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mautrix-signal/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-signal/tasks/validate_config.yml index 4200d7298..fb199563b 100644 --- a/roles/custom/matrix-bridge-mautrix-signal/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-signal/tasks/validate_config.yml @@ -15,20 +15,33 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_signal_log_level', 'new': 'matrix_mautrix_signal_logging_level'} - - {'old': 'matrix_mautrix_signal_bridge_restricted_rooms', 'new': ''} - - {'old': 'matrix_mautrix_signal_bridge_note_to_self_avatar', 'new': 'matrix_mautrix_signal_network_note_to_self_avatar'} - - {'old': 'matrix_mautrix_signal_login_shared_secret', 'new': ''} - - {'old': 'matrix_mautrix_signal_bridge_login_shared_secret_map', 'new': ''} - - {'old': 'matrix_mautrix_signal_bridge_double_puppet_server_map', 'new': ''} - - {'old': 'matrix_mautrix_signal_docker_image_name_prefix', 'new': 'matrix_mautrix_signal_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_signal_docker_image', 'new': 'matrix_mautrix_signal_container_image'} - - {'old': 'matrix_mautrix_signal_docker_image_force_pull', 'new': 'matrix_mautrix_signal_container_image_force_pull'} - - {'old': 'matrix_mautrix_signal_docker_image_registry_prefix', 'new': 'matrix_mautrix_signal_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_signal_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_signal_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_signal_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_signal_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_signal_docker_image_tag', 'new': 'matrix_mautrix_signal_container_image_tag'} - - {'old': 'matrix_mautrix_signal_docker_src_files_path', 'new': 'matrix_mautrix_signal_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_signal_log_level', 'new': 'matrix_bridge_mautrix_signal_logging_level'} + - {'old': 'matrix_bridge_mautrix_signal_bridge_restricted_rooms', 'new': ''} + - {'old': 'matrix_bridge_mautrix_signal_bridge_note_to_self_avatar', 'new': 'matrix_bridge_mautrix_signal_network_note_to_self_avatar'} + - {'old': 'matrix_bridge_mautrix_signal_login_shared_secret', 'new': ''} + - {'old': 'matrix_bridge_mautrix_signal_bridge_login_shared_secret_map', 'new': ''} + - {'old': 'matrix_bridge_mautrix_signal_bridge_double_puppet_server_map', 'new': ''} + - {'old': 'matrix_bridge_mautrix_signal_docker_image_name_prefix', 'new': 'matrix_bridge_mautrix_signal_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_signal_docker_image', 'new': 'matrix_bridge_mautrix_signal_container_image'} + - {'old': 'matrix_bridge_mautrix_signal_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_signal_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_signal_docker_image_registry_prefix', 'new': 'matrix_bridge_mautrix_signal_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_signal_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mautrix_signal_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mautrix_signal_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mautrix_signal_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mautrix_signal_docker_image_tag', 'new': 'matrix_bridge_mautrix_signal_container_image_tag'} + - {'old': 'matrix_bridge_mautrix_signal_docker_src_files_path', 'new': 'matrix_bridge_mautrix_signal_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_signal_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_mautrix_signal_metrics_enabled', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_metrics_proxying_enabled', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_metrics_proxying_hostname', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_metrics_proxying_path_prefix', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_container_labels_metrics_enabled', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_container_labels_metrics_traefik_rule', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_container_labels_metrics_traefik_priority', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_container_labels_metrics_traefik_entrypoints', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_container_labels_metrics_traefik_tls', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_container_labels_metrics_traefik_tls_certResolver', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (mautrix-signal does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_signal_container_labels_metrics_middleware_basic_auth_users', 'new': ' (mautrix-signal does not support metrics)'} - name: Fail if required mautrix-signal settings not defined ansible.builtin.fail: @@ -36,10 +49,8 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_signal_appservice_token', when: true} - - {'name': 'matrix_mautrix_signal_homeserver_address', when: true} - - {'name': 'matrix_mautrix_signal_homeserver_token', when: true} - - {'name': 'matrix_mautrix_signal_database_hostname', when: "{{ matrix_mautrix_signal_database_engine == 'postgres' }}"} - - {'name': 'matrix_mautrix_signal_container_network', when: true} - - {'name': 'matrix_mautrix_signal_metrics_proxying_hostname', when: "{{ matrix_mautrix_signal_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_signal_metrics_proxying_path_prefix', when: "{{ matrix_mautrix_signal_metrics_proxying_enabled }}"} + - {'name': 'matrix_bridge_mautrix_signal_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_signal_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_signal_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_signal_database_hostname', when: "{{ matrix_bridge_mautrix_signal_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_signal_container_network', when: true} diff --git a/roles/custom/matrix-bridge-mautrix-signal/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-signal/templates/config.yaml.j2 index be9e4bbe1..884a4b111 100644 --- a/roles/custom/matrix-bridge-mautrix-signal/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-signal/templates/config.yaml.j2 @@ -2,7 +2,7 @@ # Network-specific config options network: # Displayname template for Signal users. - displayname_template: {{ matrix_mautrix_signal_network_displayname_template | to_json }} + displayname_template: {{ matrix_bridge_mautrix_signal_network_displayname_template | to_json }} # Should avatars from the user's contact list be used? This is not safe on multi-user instances. use_contact_avatars: false # Should the bridge request the user's contact list from the phone on startup? @@ -14,20 +14,20 @@ network: # Default device name that shows up in the Signal app. device_name: mautrix-signal # Avatar image for the Note to Self room. - note_to_self_avatar: {{ matrix_mautrix_signal_network_note_to_self_avatar | to_json }} + note_to_self_avatar: {{ matrix_bridge_mautrix_signal_network_note_to_self_avatar | to_json }} # Format for generating URLs from location messages for sending to Signal. # Google Maps: 'https://www.google.com/maps/place/%[1]s,%[2]s' # OpenStreetMap: 'https://www.openstreetmap.org/?mlat=%[1]s&mlon=%[2]s' location_format: 'https://www.google.com/maps/place/%[1]s,%[2]s' # Should polls be sent using unstable MSC3381 event types? - extev_polls: {{ matrix_mautrix_signal_extev_polls | to_json }} + extev_polls: {{ matrix_bridge_mautrix_signal_extev_polls | to_json }} # Config options that affect the central bridge module. bridge: # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_mautrix_signal_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_mautrix_signal_command_prefix | to_json }} # Should the bridge create a space for each login containing the rooms that account is in? - personal_filtering_spaces: {{ matrix_mautrix_signal_bridge_personal_filtering_spaces | to_json }} + personal_filtering_spaces: {{ matrix_bridge_mautrix_signal_bridge_personal_filtering_spaces | to_json }} # Whether the bridge should set names and avatars explicitly for DM portals. # This is only necessary when using clients that don't support MSC4171. private_chat_portal_meta: true @@ -70,10 +70,10 @@ bridge: relay: # Whether relay mode should be allowed. If allowed, the set-relay command can be used to turn any # authenticated user into a relaybot for that chat. - enabled: {{ matrix_mautrix_signal_bridge_relay_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_signal_bridge_relay_enabled | to_json }} # Should only admins be allowed to set themselves as relay users? # If true, non-admins can only set users listed in default_relays as relays in a room. - admin_only: {{ matrix_mautrix_signal_bridge_relay_admin_only | to_json }} + admin_only: {{ matrix_bridge_mautrix_signal_bridge_relay_admin_only | to_json }} # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. default_relays: [] # The formats to use when sending messages via the relaybot. @@ -111,18 +111,18 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_signal_bridge_permissions | to_json }} + permissions: {{ matrix_bridge_mautrix_signal_bridge_permissions | to_json }} # Config for the bridge's database. database: # The database type. "sqlite3-fk-wal" and "postgres" are supported. - type: {{ matrix_mautrix_signal_appservice_database_type | to_json }} + type: {{ matrix_bridge_mautrix_signal_appservice_database_type | to_json }} # The database URI. # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. # https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_mautrix_signal_appservice_database_uri | to_json }} + uri: {{ matrix_bridge_mautrix_signal_appservice_database_uri | to_json }} # Maximum number of connections. max_open_conns: 20 max_idle_conns: 2 @@ -136,9 +136,9 @@ homeserver: # The address that this appservice can use to connect to the homeserver. # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, # but https also works if they run on different machines. - address: {{ matrix_mautrix_signal_homeserver_address | to_json }} + address: {{ matrix_bridge_mautrix_signal_homeserver_address | to_json }} # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: {{ matrix_mautrix_signal_homeserver_domain | to_json }} + domain: {{ matrix_bridge_mautrix_signal_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -154,7 +154,7 @@ homeserver: # The bridge will use the appservice as_token to authorize requests. message_send_checkpoint_endpoint: null # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_mautrix_signal_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_mautrix_signal_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -167,11 +167,11 @@ homeserver: # Changing these values requires regeneration of the registration (except when noted otherwise) appservice: # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_mautrix_signal_appservice_address | to_json }} + address: {{ matrix_bridge_mautrix_signal_appservice_address | to_json }} # A public address that external services can use to reach this appservice. # This value doesn't affect the registration file. - public_address: "" + public_address: {{ matrix_bridge_mautrix_signal_bridge_public_address | to_json }} # The hostname and port where this appservice should listen. # For Docker, you generally have to change the hostname to 0.0.0.0. @@ -183,7 +183,7 @@ appservice: # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_mautrix_signal_appservice_bot_username | to_json }} + username: {{ matrix_bridge_mautrix_signal_appservice_bot_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. displayname: signal bridge bot @@ -198,8 +198,8 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_mautrix_signal_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_signal_homeserver_token | to_json }} + as_token: {{ matrix_bridge_mautrix_signal_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_signal_homeserver_token | to_json }} # Localpart template of MXIDs for remote users. # {{ '{{.}}' }} is replaced with the internal ID of the Signal user. @@ -217,7 +217,7 @@ matrix: sync_direct_chat_list: false # Whether created rooms should have federation enabled. If false, created portal rooms # will never be federated. Changing this option requires recreating rooms. - federate_rooms: {{ matrix_mautrix_signal_federate_rooms | to_json }} + federate_rooms: {{ matrix_bridge_mautrix_signal_federate_rooms | to_json }} # Settings for provisioning API provisioning: @@ -225,7 +225,7 @@ provisioning: prefix: /_matrix/provision # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, # or if set to "disable", the provisioning API will be disabled. - shared_secret: {{ matrix_mautrix_signal_provisioning_shared_secret | to_json }} + shared_secret: {{ matrix_bridge_mautrix_signal_provisioning_shared_secret | to_json }} # Whether to allow provisioning API requests to be authed using Matrix access tokens. # This follows the same rules as double puppeting to determine which server to contact to check the token, # which means that by default, it only works for users on the same server as the bridge. @@ -241,7 +241,7 @@ public_media: enabled: false # A key for signing public media URLs. # If set to "generate", a random key will be generated. - signing_key: {{ matrix_mautrix_signal_public_media_signing_key | to_json }} + signing_key: {{ matrix_bridge_mautrix_signal_public_media_signing_key | to_json }} # Number of seconds that public media URLs are valid for. # If set to 0, URLs will never expire. expiry: 0 @@ -275,18 +275,18 @@ direct_media: # See https://docs.mau.fi/bridges/general/backfill.html for more details. backfill: # Whether to do backfilling at all. - enabled: {{ matrix_mautrix_signal_backfill_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_signal_backfill_enabled | to_json }} # Maximum number of messages to backfill in empty rooms. - max_initial_messages: {{ matrix_mautrix_signal_backfill_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_mautrix_signal_backfill_max_initial_messages | to_json }} # Maximum number of missed messages to backfill after bridge restarts. - max_catchup_messages: {{ matrix_mautrix_signal_backfill_max_catchup_messages | to_json }} + max_catchup_messages: {{ matrix_bridge_mautrix_signal_backfill_max_catchup_messages | to_json }} # If a backfilled chat is older than this number of hours, # mark it as read even if it's unread on the remote network. - unread_hours_threshold: {{ matrix_mautrix_signal_backfill_unread_hours_threshold| to_json }} + unread_hours_threshold: {{ matrix_bridge_mautrix_signal_backfill_unread_hours_threshold| to_json }} # Settings for backfilling threads within other backfills. threads: # Maximum number of messages to backfill in a new thread. - max_initial_messages: {{ matrix_mautrix_signal_backfill_threads_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_mautrix_signal_backfill_threads_max_initial_messages | to_json }} # Settings for the backwards backfill queue. This only applies when connecting to # Beeper as standard Matrix servers don't support inserting messages into history. queue: @@ -314,16 +314,16 @@ double_puppet: allow_discovery: false # Shared secrets for automatic double puppeting. # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. - secrets: {{ matrix_mautrix_signal_double_puppet_secrets | to_json }} + secrets: {{ matrix_bridge_mautrix_signal_double_puppet_secrets | to_json }} # End-to-bridge encryption support options. # # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. - allow: {{ matrix_mautrix_signal_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_mautrix_signal_bridge_encryption_allow | to_json }} # Whether to force-enable encryption in all bridged rooms. - default: {{ matrix_mautrix_signal_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_mautrix_signal_bridge_encryption_default | to_json }} # Whether to require all messages to be encrypted and drop any unencrypted messages. require: false # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. @@ -333,13 +333,13 @@ encryption: # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_mautrix_signal_msc4190_enabled | to_json }} + msc4190: {{ matrix_bridge_mautrix_signal_msc4190_enabled | to_json }} # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) # Requires msc4190 to replace keys on reset - self_sign: {{ matrix_mautrix_signal_self_sign_enabled | to_json }} + self_sign: {{ matrix_bridge_mautrix_signal_self_sign_enabled | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_mautrix_signal_bridge_encryption_key_sharing_allow | to_json }} + allow_key_sharing: {{ matrix_bridge_mautrix_signal_bridge_encryption_key_sharing_allow | to_json }} # Pickle key for encrypting encryption keys in the bridge database. # If set to generate, a random key will be generated. pickle_key: mautrix.bridge.e2ee @@ -401,7 +401,7 @@ encryption: # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_mautrix_signal_logging_level | to_json }} + min_level: {{ matrix_bridge_mautrix_signal_logging_level | to_json }} writers: - type: stdout format: pretty-colored diff --git a/roles/custom/matrix-bridge-mautrix-signal/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-signal/templates/labels.j2 index 334ca6fbc..b3d2bc4e8 100644 --- a/roles/custom/matrix-bridge-mautrix-signal/templates/labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-signal/templates/labels.j2 @@ -4,44 +4,42 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_signal_container_labels_traefik_enabled %} +{% if matrix_bridge_mautrix_signal_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_mautrix_signal_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_signal_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_signal_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_signal_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.matrix-mautrix-signal-metrics.loadbalancer.server.port=8000 - -{% if matrix_mautrix_signal_container_labels_metrics_enabled %} +{% if matrix_bridge_mautrix_signal_container_labels_exposure_enabled %} ############################################################ # # -# Metrics # +# Bridge API exposure # # # ############################################################ -{% if matrix_mautrix_signal_container_labels_metrics_middleware_basic_auth_enabled %} -traefik.http.middlewares.matrix-mautrix-signal-metrics-basic-auth.basicauth.users={{ matrix_mautrix_signal_container_labels_metrics_middleware_basic_auth_users }} -traefik.http.routers.matrix-mautrix-signal-metrics.middlewares=matrix-mautrix-signal-metrics-basic-auth -{% endif %} +traefik.http.services.matrix-mautrix-signal-exposure.loadbalancer.server.port=8080 + +traefik.http.middlewares.matrix-mautrix-signal-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_signal_exposure_path_prefix }} +traefik.http.routers.matrix-mautrix-signal-exposure.middlewares=matrix-mautrix-signal-exposure-strip-prefix -traefik.http.routers.matrix-mautrix-signal-metrics.rule={{ matrix_mautrix_signal_container_labels_metrics_traefik_rule }} +traefik.http.routers.matrix-mautrix-signal-exposure.rule={{ matrix_bridge_mautrix_signal_container_labels_exposure_traefik_rule }} -{% if matrix_mautrix_signal_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-signal-metrics.priority={{ matrix_mautrix_signal_container_labels_metrics_traefik_priority }} +{% if matrix_bridge_mautrix_signal_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-signal-exposure.priority={{ matrix_bridge_mautrix_signal_container_labels_exposure_traefik_priority }} {% endif %} -traefik.http.routers.matrix-mautrix-signal-metrics.service=matrix-mautrix-signal-metrics -traefik.http.routers.matrix-mautrix-signal-metrics.entrypoints={{ matrix_mautrix_signal_container_labels_metrics_traefik_entrypoints }} +traefik.http.routers.matrix-mautrix-signal-exposure.service=matrix-mautrix-signal-exposure +traefik.http.routers.matrix-mautrix-signal-exposure.entrypoints={{ matrix_bridge_mautrix_signal_container_labels_exposure_traefik_entrypoints }} -traefik.http.routers.matrix-mautrix-signal-metrics.tls={{ matrix_mautrix_signal_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_mautrix_signal_container_labels_metrics_traefik_tls %} -traefik.http.routers.matrix-mautrix-signal-metrics.tls.certResolver={{ matrix_mautrix_signal_container_labels_metrics_traefik_tls_certResolver }} +traefik.http.routers.matrix-mautrix-signal-exposure.tls={{ matrix_bridge_mautrix_signal_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_signal_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-mautrix-signal-exposure.tls.certResolver={{ matrix_bridge_mautrix_signal_container_labels_exposure_traefik_tls_certResolver }} {% endif %} ############################################################ # # -# /Metrics # +# /Bridge API exposure # # # ############################################################ {% endif %} @@ -49,4 +47,4 @@ traefik.http.routers.matrix-mautrix-signal-metrics.tls.certResolver={{ matrix_ma {% endif %} -{{ matrix_mautrix_signal_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_signal_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-signal/templates/systemd/matrix-mautrix-signal.service.j2 b/roles/custom/matrix-bridge-mautrix-signal/templates/systemd/matrix-mautrix-signal.service.j2 index cb6655bcc..b9ef31f69 100644 --- a/roles/custom/matrix-bridge-mautrix-signal/templates/systemd/matrix-mautrix-signal.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-signal/templates/systemd/matrix-mautrix-signal.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix Signal bridge -{% for service in matrix_mautrix_signal_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_signal_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_signal_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_signal_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,20 +22,22 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_signal_container_network }} \ - --mount type=bind,src={{ matrix_mautrix_signal_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_mautrix_signal_data_path }},dst=/data \ - --label-file={{ matrix_mautrix_signal_base_path }}/labels \ + --network={{ matrix_bridge_mautrix_signal_container_network }} \ + --mount type=bind,src={{ matrix_bridge_mautrix_signal_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_signal_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_signal_base_path }}/labels \ --workdir=/data \ - {% for arg in matrix_mautrix_signal_container_extra_arguments %} + {% for arg in matrix_bridge_mautrix_signal_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_signal_container_image }} \ + {{ matrix_bridge_mautrix_signal_container_image }} \ /usr/bin/mautrix-signal -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_mautrix_signal_container_additional_networks %} +{% if matrix_bridge_mautrix_signal_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_signal_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-signal {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-signal diff --git a/roles/custom/matrix-bridge-mautrix-slack/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-slack/defaults/main.yml index 3fd540853..27f1cc694 100644 --- a/roles/custom/matrix-bridge-mautrix-slack/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-slack/defaults/main.yml @@ -10,35 +10,41 @@ # mautrix-slack is a Matrix <-> Slack bridge # Project source code URL: https://github.com/mautrix/slack -matrix_mautrix_slack_enabled: true +matrix_bridge_mautrix_slack_enabled: true -matrix_mautrix_slack_container_image_self_build: false -matrix_mautrix_slack_container_image_self_build_repo: "https://mau.dev/mautrix/slack.git" -matrix_mautrix_slack_container_image_self_build_branch: "{{ 'main' if matrix_mautrix_slack_version == 'latest' else matrix_mautrix_slack_version }}" +matrix_bridge_mautrix_slack_container_image_self_build: false +matrix_bridge_mautrix_slack_container_image_self_build_repo: "https://mau.dev/mautrix/slack.git" +matrix_bridge_mautrix_slack_container_image_self_build_branch: "{{ 'main' if matrix_bridge_mautrix_slack_version == 'latest' else matrix_bridge_mautrix_slack_version }}" # renovate: datasource=docker depName=dock.mau.dev/mautrix/slack -matrix_mautrix_slack_version: v0.2603.0 +matrix_bridge_mautrix_slack_version: v0.2608.0 # See: https://mau.dev/mautrix/slack/container_registry -matrix_mautrix_slack_container_image: "{{ matrix_mautrix_slack_container_image_registry_prefix }}mautrix/slack:{{ matrix_mautrix_slack_version }}" -matrix_mautrix_slack_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_slack_container_image_self_build else matrix_mautrix_slack_container_image_registry_prefix_upstream }}" -matrix_mautrix_slack_container_image_registry_prefix_upstream: "{{ matrix_mautrix_slack_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_slack_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_slack_container_image_force_pull: "{{ matrix_mautrix_slack_container_image.endswith(':latest') }}" - -matrix_mautrix_slack_base_path: "{{ matrix_base_data_path }}/mautrix-slack" -matrix_mautrix_slack_config_path: "{{ matrix_mautrix_slack_base_path }}/config" -matrix_mautrix_slack_data_path: "{{ matrix_mautrix_slack_base_path }}/data" -matrix_mautrix_slack_container_src_files_path: "{{ matrix_mautrix_slack_base_path }}/docker-src" - -matrix_mautrix_slack_homeserver_address: "" -matrix_mautrix_slack_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_mautrix_slack_container_image: "{{ matrix_bridge_mautrix_slack_container_image_registry_prefix }}mautrix/slack:{{ matrix_bridge_mautrix_slack_version }}" +matrix_bridge_mautrix_slack_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_slack_container_image_self_build else matrix_bridge_mautrix_slack_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_slack_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_slack_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_slack_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bridge_mautrix_slack_base_path: "{{ matrix_base_data_path }}/mautrix-slack" +matrix_bridge_mautrix_slack_config_path: "{{ matrix_bridge_mautrix_slack_base_path }}/config" +matrix_bridge_mautrix_slack_data_path: "{{ matrix_bridge_mautrix_slack_base_path }}/data" +matrix_bridge_mautrix_slack_container_src_files_path: "{{ matrix_bridge_mautrix_slack_base_path }}/docker-src" + +matrix_bridge_mautrix_slack_homeserver_address: "" +matrix_bridge_mautrix_slack_homeserver_domain: "{{ matrix_domain }}" # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_mautrix_slack_homeserver_async_media: false -matrix_mautrix_slack_appservice_address: "http://matrix-mautrix-slack:8080" +matrix_bridge_mautrix_slack_homeserver_async_media: false +matrix_bridge_mautrix_slack_appservice_address: "http://matrix-mautrix-slack:8080" -matrix_mautrix_slack_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" -matrix_mautrix_slack_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_slack_bridge_public_address`). +matrix_bridge_mautrix_slack_scheme: https + +# The public base URL at which this bridge's HTTP API is reachable from outside (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_slack_bridge_public_address: "{{ (matrix_bridge_mautrix_slack_scheme + '://' + matrix_bridge_mautrix_slack_exposure_hostname + matrix_bridge_mautrix_slack_exposure_path_prefix) if matrix_bridge_mautrix_slack_exposure_enabled else '' }}" + +matrix_bridge_mautrix_slack_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_slack_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" # Displayname template for Slack users. Available variables: # .Name - The username of the user @@ -59,151 +65,179 @@ matrix_mautrix_slack_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" # .Profile.Pronouns - The pronouns of the user # .Profile.Email - The email address of the user # .Profile.Phone - The formatted phone number of the user -matrix_mautrix_slack_network_displayname_template: '{% raw %}{{or .Profile.DisplayName .Profile.RealName .Name}}{{if .IsBot}} (bot){{end}}{% endraw %}' +matrix_bridge_mautrix_slack_network_displayname_template: '{% raw %}{{or .Profile.DisplayName .Profile.RealName .Name}}{{if .IsBot}} (bot){{end}}{% endraw %}' -matrix_mautrix_slack_command_prefix: "!slack" +matrix_bridge_mautrix_slack_command_prefix: "!slack" -matrix_mautrix_slack_bridge_permissions: | +matrix_bridge_mautrix_slack_bridge_permissions: | {{ - {'*': 'relay', matrix_mautrix_slack_homeserver_domain: 'user'} + {'*': 'relay', matrix_bridge_mautrix_slack_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} -matrix_mautrix_slack_container_network: "" +matrix_bridge_mautrix_slack_container_network: "" + +matrix_bridge_mautrix_slack_container_additional_networks: "{{ matrix_bridge_mautrix_slack_container_additional_networks_auto + matrix_bridge_mautrix_slack_container_additional_networks_custom }}" +matrix_bridge_mautrix_slack_container_additional_networks_auto: [] +matrix_bridge_mautrix_slack_container_additional_networks_custom: [] -matrix_mautrix_slack_container_additional_networks: "{{ matrix_mautrix_slack_container_additional_networks_auto + matrix_mautrix_slack_container_additional_networks_custom }}" -matrix_mautrix_slack_container_additional_networks_auto: [] -matrix_mautrix_slack_container_additional_networks_custom: [] +# matrix_bridge_mautrix_slack_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# See `../templates/labels.j2` for details. +# +# To inject your own other container labels, see `matrix_bridge_mautrix_slack_container_labels_additional_labels`. +matrix_bridge_mautrix_slack_container_labels_traefik_enabled: true +matrix_bridge_mautrix_slack_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_slack_container_network }}" +matrix_bridge_mautrix_slack_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_slack_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-slack's HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_slack_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_slack_exposure_enabled }}" +matrix_bridge_mautrix_slack_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_slack_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_slack_exposure_path_prefix }}`)" +matrix_bridge_mautrix_slack_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_slack_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_slack_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_slack_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_slack_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_slack_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_slack_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_slack_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# See `../templates/labels.j2` for details. +# +# Example: +# matrix_bridge_mautrix_slack_container_labels_additional_labels: | +# my.label=1 +# another.label="here" +matrix_bridge_mautrix_slack_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_slack_container_extra_arguments: [] +matrix_bridge_mautrix_slack_container_extra_arguments: [] # List of systemd services that matrix-mautrix-slack.service depends on. -matrix_mautrix_slack_systemd_required_services_list: "{{ matrix_mautrix_slack_systemd_required_services_list_default + matrix_mautrix_slack_systemd_required_services_list_auto + matrix_mautrix_slack_systemd_required_services_list_custom }}" -matrix_mautrix_slack_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_slack_systemd_required_services_list_auto: [] -matrix_mautrix_slack_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_slack_systemd_required_services_list: "{{ matrix_bridge_mautrix_slack_systemd_required_services_list_default + matrix_bridge_mautrix_slack_systemd_required_services_list_auto + matrix_bridge_mautrix_slack_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_slack_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_slack_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_slack_systemd_required_services_list_custom: [] # List of systemd services that matrix-mautrix-slack.service wants -matrix_mautrix_slack_systemd_wanted_services_list: [] +matrix_bridge_mautrix_slack_systemd_wanted_services_list: [] -matrix_mautrix_slack_appservice_token: '' -matrix_mautrix_slack_homeserver_token: '' +matrix_bridge_mautrix_slack_appservice_token: '' +matrix_bridge_mautrix_slack_homeserver_token: '' -matrix_mautrix_slack_appservice_bot_username: slackbot +matrix_bridge_mautrix_slack_appservice_bot_username: slackbot -matrix_mautrix_slack_backfill_enabled: true -matrix_mautrix_slack_backfill_max_initial_messages: 50 -matrix_mautrix_slack_backfill_max_catchup_messages: 500 -matrix_mautrix_slack_backfill_unread_hours_threshold: 720 -matrix_mautrix_slack_backfill_threads_max_initial_messages: 50 +matrix_bridge_mautrix_slack_backfill_enabled: true +matrix_bridge_mautrix_slack_backfill_max_initial_messages: 50 +matrix_bridge_mautrix_slack_backfill_max_catchup_messages: 500 +matrix_bridge_mautrix_slack_backfill_unread_hours_threshold: 720 +matrix_bridge_mautrix_slack_backfill_threads_max_initial_messages: 50 # Minimum severity of journal log messages. # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_slack_logging_level: 'warn' +matrix_bridge_mautrix_slack_logging_level: 'warn' # Database-related configuration fields. # # To use SQLite, stick to these defaults. # # To use Postgres: -# - change the engine (`matrix_mautrix_slack_database_engine: 'postgres'`) -# - adjust your database credentials via the `matrix_mautrix_slack_database_*` variables -matrix_mautrix_slack_database_engine: 'sqlite' - -matrix_mautrix_slack_sqlite_database_path_local: "{{ matrix_mautrix_slack_data_path }}/mautrix-slack.db" -matrix_mautrix_slack_sqlite_database_path_in_container: "/data/mautrix-slack.db" - -matrix_mautrix_slack_database_username: 'matrix_mautrix_slack' -matrix_mautrix_slack_database_password: 'some-password' -matrix_mautrix_slack_database_hostname: '' -matrix_mautrix_slack_database_port: 5432 -matrix_mautrix_slack_database_name: 'matrix_mautrix_slack' -matrix_mautrix_slack_database_sslmode: disable - -matrix_mautrix_slack_database_connection_string: 'postgresql://{{ matrix_mautrix_slack_database_username }}:{{ matrix_mautrix_slack_database_password }}@{{ matrix_mautrix_slack_database_hostname }}:{{ matrix_mautrix_slack_database_port }}/{{ matrix_mautrix_slack_database_name }}?sslmode={{ matrix_mautrix_slack_database_sslmode }}' - -matrix_mautrix_slack_appservice_database_type: "{{ - { - 'sqlite': 'sqlite3', - 'postgres':'postgres', - }[matrix_mautrix_slack_database_engine] -}}" - -matrix_mautrix_slack_appservice_database_uri: "{{ - { - 'sqlite': matrix_mautrix_slack_sqlite_database_path_in_container, - 'postgres': matrix_mautrix_slack_database_connection_string, - }[matrix_mautrix_slack_database_engine] -}}" - -matrix_mautrix_slack_double_puppet_secrets: "{{ matrix_mautrix_slack_double_puppet_secrets_auto | combine(matrix_mautrix_slack_double_puppet_secrets_custom) }}" -matrix_mautrix_slack_double_puppet_secrets_auto: {} -matrix_mautrix_slack_double_puppet_secrets_custom: {} +# - change the engine (`matrix_bridge_mautrix_slack_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_mautrix_slack_database_*` variables +matrix_bridge_mautrix_slack_database_engine: 'sqlite' + +matrix_bridge_mautrix_slack_sqlite_database_path_local: "{{ matrix_bridge_mautrix_slack_data_path }}/mautrix-slack.db" +matrix_bridge_mautrix_slack_sqlite_database_path_in_container: "/data/mautrix-slack.db" + +matrix_bridge_mautrix_slack_database_username: 'matrix_mautrix_slack' +matrix_bridge_mautrix_slack_database_password: 'some-password' +matrix_bridge_mautrix_slack_database_hostname: '' +matrix_bridge_mautrix_slack_database_port: 5432 +matrix_bridge_mautrix_slack_database_name: 'matrix_mautrix_slack' +matrix_bridge_mautrix_slack_database_sslmode: disable + +matrix_bridge_mautrix_slack_database_connection_string: 'postgresql://{{ matrix_bridge_mautrix_slack_database_username }}:{{ matrix_bridge_mautrix_slack_database_password }}@{{ matrix_bridge_mautrix_slack_database_hostname }}:{{ matrix_bridge_mautrix_slack_database_port }}/{{ matrix_bridge_mautrix_slack_database_name }}?sslmode={{ matrix_bridge_mautrix_slack_database_sslmode }}' + +matrix_bridge_mautrix_slack_appservice_database_type: "{{ { + 'sqlite': 'sqlite3', + 'postgres': 'postgres', +}[matrix_bridge_mautrix_slack_database_engine] }}" + +matrix_bridge_mautrix_slack_appservice_database_uri: "{{ { + 'sqlite': matrix_bridge_mautrix_slack_sqlite_database_path_in_container, + 'postgres': matrix_bridge_mautrix_slack_database_connection_string, +}[matrix_bridge_mautrix_slack_database_engine] }}" + +matrix_bridge_mautrix_slack_double_puppet_secrets: "{{ matrix_bridge_mautrix_slack_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_slack_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_slack_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_slack_double_puppet_secrets_custom: {} # Default mautrix-slack configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_slack_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_slack_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_slack_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_slack_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_slack_configuration_extension_yaml: | +matrix_bridge_mautrix_slack_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_slack_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_slack_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_slack_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_slack_configuration_yaml`. -matrix_mautrix_slack_configuration_extension: "{{ matrix_mautrix_slack_configuration_extension_yaml | from_yaml if matrix_mautrix_slack_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_slack_configuration_extension: "{{ matrix_bridge_mautrix_slack_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_slack_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_slack_configuration_yaml`. -matrix_mautrix_slack_configuration: "{{ matrix_mautrix_slack_configuration_yaml | from_yaml | combine(matrix_mautrix_slack_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_slack_configuration_yaml`. +matrix_bridge_mautrix_slack_configuration: "{{ matrix_bridge_mautrix_slack_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_slack_configuration_extension, recursive=True) }}" -matrix_mautrix_slack_registration_yaml: | +matrix_bridge_mautrix_slack_registration_yaml: | id: slack - url: {{ matrix_mautrix_slack_appservice_address | to_json }} - as_token: {{ matrix_mautrix_slack_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_slack_homeserver_token | to_json }} + url: {{ matrix_bridge_mautrix_slack_appservice_address | to_json }} + as_token: {{ matrix_bridge_mautrix_slack_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_slack_homeserver_token | to_json }} # See https://github.com/mautrix/signal/issues/43 - sender_localpart: _bot_{{ matrix_mautrix_slack_appservice_bot_username }} + sender_localpart: _bot_{{ matrix_bridge_mautrix_slack_appservice_bot_username }} rate_limited: false namespaces: users: - - regex: '^@slack_[a-z-A-Z0-9\-]+:{{ matrix_mautrix_slack_homeserver_domain | regex_escape }}$' + - regex: '^@slack_[a-z-A-Z0-9\-]+:{{ matrix_bridge_mautrix_slack_homeserver_domain | regex_escape }}$' exclusive: true - exclusive: true - regex: '^@{{ matrix_mautrix_slack_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_slack_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_mautrix_slack_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_slack_homeserver_domain | regex_escape }}$' de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_mautrix_slack_msc4190_enabled | to_json }} + io.element.msc4190: {{ matrix_bridge_mautrix_slack_msc4190_enabled | to_json }} -matrix_mautrix_slack_registration: "{{ matrix_mautrix_slack_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_slack_registration: "{{ matrix_bridge_mautrix_slack_registration_yaml | from_yaml }}" # Enable End-to-bridge encryption -matrix_mautrix_slack_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_slack_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_mautrix_slack_bridge_encryption_key_sharing_allow: "{{ matrix_mautrix_slack_bridge_encryption_allow }}" +matrix_bridge_mautrix_slack_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_slack_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_slack_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_mautrix_slack_bridge_encryption_allow }}" # This pickle key value is backward-compatible with the old bridge. # See: https://github.com/mautrix/slack/releases/tag/v0.1.0 -matrix_mautrix_slack_bridge_encryption_pickle_key: maunium.net/go/mautrix-whatsapp +matrix_bridge_mautrix_slack_bridge_encryption_pickle_key: maunium.net/go/mautrix-whatsapp + +matrix_bridge_mautrix_slack_provisioning_shared_secret: '' +matrix_bridge_mautrix_slack_public_media_signing_key: '' -matrix_mautrix_slack_provisioning_shared_secret: '' -matrix_mautrix_slack_public_media_signing_key: '' +# Controls whether mautrix-slack's HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_slack_exposure_enabled: false +matrix_bridge_mautrix_slack_exposure_hostname: '' +matrix_bridge_mautrix_slack_exposure_path_prefix: '' # Controls whether relay mode is enabled -matrix_mautrix_slack_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" +matrix_bridge_mautrix_slack_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" # Controls whether only admins can set themselves as relay users -matrix_mautrix_slack_bridge_relay_admin_only: true +matrix_bridge_mautrix_slack_bridge_relay_admin_only: true # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room -matrix_mautrix_slack_bridge_relay_default_relays: [] +matrix_bridge_mautrix_slack_bridge_relay_default_relays: [] -# matrix_mautrix_slack_restart_necessary controls whether the service +# matrix_bridge_mautrix_slack_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -211,4 +245,4 @@ matrix_mautrix_slack_bridge_relay_default_relays: [] # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_slack_restart_necessary: false +matrix_bridge_mautrix_slack_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-slack/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-slack/molecule/default/converge.yml new file mode 100644 index 000000000..b4e018630 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-slack/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-slack Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-slack Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-slack is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-slack systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-slack.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-slack/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-slack/molecule/default/molecule.yml new file mode 100644 index 000000000..310a49e34 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-slack/molecule/default/molecule.yml @@ -0,0 +1,103 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-slack-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_slack_container_network: mautrix-slack-molecule + + # The stub prepare.yml starts is not a real homeserver, and the scenario carries + # no Slack token, credentials, or workspace. Logged out is the intended boundary. + matrix_bridge_mautrix_slack_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_slack_homeserver_domain: molecule.local + matrix_bridge_mautrix_slack_homeserver_async_media: true + + # Postgres is the normal deployment path. Non-default database and user names make + # the resulting schema evidence that the role composed and supplied this connection. + matrix_bridge_mautrix_slack_database_engine: postgres + matrix_bridge_mautrix_slack_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_slack_database_name: molecule_slack + matrix_bridge_mautrix_slack_database_username: molecule_slack + matrix_bridge_mautrix_slack_database_password: molecule_pg_password_6e95b1 + + # Test-only fixtures which must reach both config.yaml and registration.yaml. + matrix_bridge_mautrix_slack_appservice_token: molecule_slack_as_token_d1504c + matrix_bridge_mautrix_slack_homeserver_token: molecule_slack_hs_token_b873a0 + + # All differ from role defaults, allowing parsed checks to prove role rendering. + matrix_bridge_mautrix_slack_appservice_bot_username: molecule-slackbot + matrix_bridge_mautrix_slack_network_displayname_template: "{% raw %}{{ .Name }} @ {{ .Team.Domain }} (Molecule){% endraw %}" + matrix_bridge_mautrix_slack_command_prefix: "!molecule-slack" + matrix_bridge_mautrix_slack_bridge_permissions: + "*": commands + molecule.local: admin + matrix_bridge_mautrix_slack_bridge_relay_enabled: true + matrix_bridge_mautrix_slack_bridge_relay_admin_only: false + matrix_bridge_mautrix_slack_bridge_relay_default_relays: + - molecule-workspace/molecule-relay + matrix_bridge_mautrix_slack_backfill_enabled: false + matrix_bridge_mautrix_slack_backfill_max_initial_messages: 19 + matrix_bridge_mautrix_slack_backfill_max_catchup_messages: 31 + matrix_bridge_mautrix_slack_backfill_unread_hours_threshold: 73 + matrix_bridge_mautrix_slack_backfill_threads_max_initial_messages: 11 + matrix_bridge_mautrix_slack_provisioning_shared_secret: molecule_provisioning_secret_204c17 + matrix_bridge_mautrix_slack_public_media_signing_key: molecule_public_media_key_2a593d + matrix_bridge_mautrix_slack_double_puppet_secrets_custom: + molecule.remote: molecule_double_puppet_secret_a7d210 + matrix_bridge_mautrix_slack_logging_level: info + + # Traefik is not started. These values exercise both the public address the bridge + # consumes and the exposure labels Docker consumes. + matrix_bridge_mautrix_slack_exposure_enabled: true + matrix_bridge_mautrix_slack_exposure_hostname: slack-api.molecule.local + matrix_bridge_mautrix_slack_exposure_path_prefix: /bridges/slack-api + matrix_bridge_mautrix_slack_scheme: http + matrix_bridge_mautrix_slack_container_labels_traefik_entrypoints: web + matrix_bridge_mautrix_slack_container_labels_additional_labels: | + molecule.slack.coverage=enabled + + # verify.yml is a separate play, where role defaults are out of scope. + matrix_bridge_mautrix_slack_base_path: /matrix/mautrix-slack + matrix_bridge_mautrix_slack_config_path: /matrix/mautrix-slack/config + matrix_bridge_mautrix_slack_data_path: /matrix/mautrix-slack/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-slack/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-slack/molecule/default/prepare.yml new file mode 100644 index 000000000..c7faedf61 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-slack/molecule/default/prepare.yml @@ -0,0 +1,87 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-slack Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role creates this during converge, but both dependencies attach to it first. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_slack_container_network }}" + register: mautrix_slack_molecule_network + changed_when: mautrix_slack_molecule_network.rc == 0 + failed_when: + - mautrix_slack_molecule_network.rc != 0 + - "'already exists' not in mautrix_slack_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_slack_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_slack_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_slack_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_slack_database_password }}" + + # The logged-out bridge still checks its appservice bot identity during startup. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_slack_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_slack_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_slack_appservice_bot_username }}:{{ matrix_bridge_mautrix_slack_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-slack/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-slack/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-slack/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-slack/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-slack/molecule/default/verify.yml new file mode 100644 index 000000000..2a7cefae4 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-slack/molecule/default/verify.yml @@ -0,0 +1,399 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the logged-out bridge starts, accepts the role-rendered configuration and +# registration, migrates real Postgres, and opens its appservice listener. Slack +# credentials and workspace access are deliberately outside the scenario boundary. +- name: Verify mautrix-slack + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + mautrix_slack_config: "{{ mautrix_slack_config_file.content | b64decode | from_yaml }}" + mautrix_slack_registration: "{{ mautrix_slack_registration_file.content | b64decode | from_yaml }}" + mautrix_slack_labels_rendered: "{{ mautrix_slack_labels_file.content | b64decode }}" + mautrix_slack_expected_public_address: http://slack-api.molecule.local/bridges/slack-api + gather_facts: false + + tasks: + # A Renovate bump changes this source of truth and therefore the image expectation. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_slack_role_defaults + + - name: Wait for the mautrix-slack service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-slack.service + register: mautrix_slack_service + until: mautrix_slack_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes ActiveState insufficient for detecting a crash loop. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_slack_service.status.ActiveState == 'active' + - mautrix_slack_service.status.NRestarts is defined + - mautrix_slack_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-slack.service is + {{ mautrix_slack_service.status.ActiveState | default('unknown') }} after + {{ mautrix_slack_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-mautrix-slack.service is active and has not restarted" + + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_slack_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-slack:8080/_matrix/mau/live + register: mautrix_slack_live + changed_when: false + until: mautrix_slack_live.rc == 0 and mautrix_slack_live.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_slack_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-slack:8080/_matrix/mau/ready + register: mautrix_slack_ready + changed_when: false + until: mautrix_slack_ready.rc == 0 and mautrix_slack_ready.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on the configured appservice port + ansible.builtin.assert: + that: + - mautrix_slack_live.rc == 0 + - mautrix_slack_live.stdout == 'HTTP_STATUS=200' + - mautrix_slack_ready.rc == 0 + - mautrix_slack_ready.stdout == 'HTTP_STATUS=200' + fail_msg: >- + Health probes returned live={{ mautrix_slack_live.stdout | default('none') }} + (rc={{ mautrix_slack_live.rc | default('?') }}) and + ready={{ mautrix_slack_ready.stdout | default('none') }} + (rc={{ mautrix_slack_ready.rc | default('?') }}) + success_msg: "The bridge is live and ready on the configured appservice port" + + # This authenticated endpoint exercises the provisioning middleware and the network + # connector's login-flow API without starting a Slack login or carrying credentials. + - name: Query the authenticated provisioning login flows + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_slack_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --fail-with-body + - --header + - "Authorization: Bearer {{ matrix_bridge_mautrix_slack_provisioning_shared_secret }}" + - "http://matrix-mautrix-slack:8080/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_slack_login_flows + changed_when: false + + - name: Query the provisioning API with an invalid secret + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_slack_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - --header + - "Authorization: Bearer definitely-wrong-molecule-secret" + - "http://matrix-mautrix-slack:8080/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_slack_login_flows_unauthorized + changed_when: false + failed_when: false + + - name: Assert the live provisioning API enforces auth and advertises login flows + ansible.builtin.assert: + that: + - mautrix_slack_login_flows.rc == 0 + - (mautrix_slack_login_flows.stdout | from_json).flows is sequence + - (mautrix_slack_login_flows.stdout | from_json).flows | length > 0 + - mautrix_slack_login_flows_unauthorized.rc == 0 + - mautrix_slack_login_flows_unauthorized.stdout == 'HTTP_STATUS=401' + fail_msg: "The provisioning API did not enforce its secret or return Slack login flows" + success_msg: "The provisioning API enforces its secret and returns Slack login flows" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_slack_config_path }}/config.yaml" + register: mautrix_slack_config_file + + - name: Assert the rendered configuration carries the appservice identity + ansible.builtin.assert: + that: + - mautrix_slack_config.homeserver.address == matrix_bridge_mautrix_slack_homeserver_address + - mautrix_slack_config.homeserver.domain == matrix_bridge_mautrix_slack_homeserver_domain + - mautrix_slack_config.homeserver.async_media + - mautrix_slack_config.appservice.id == 'slack' + - mautrix_slack_config.appservice.address == 'http://matrix-mautrix-slack:8080' + - mautrix_slack_config.appservice.public_address == mautrix_slack_expected_public_address + - mautrix_slack_config.appservice.bot.username == matrix_bridge_mautrix_slack_appservice_bot_username + - mautrix_slack_config.appservice.as_token == matrix_bridge_mautrix_slack_appservice_token + - mautrix_slack_config.appservice.hs_token == matrix_bridge_mautrix_slack_homeserver_token + fail_msg: "The rendered configuration does not carry the scenario's appservice identity" + success_msg: "The rendered configuration carries the scenario's appservice identity" + + - name: Assert the rendered configuration carries non-default Slack behavior + ansible.builtin.assert: + that: + - mautrix_slack_config.network.displayname_template == matrix_bridge_mautrix_slack_network_displayname_template + - mautrix_slack_config.bridge.command_prefix == matrix_bridge_mautrix_slack_command_prefix + - mautrix_slack_config.bridge.permissions['*'] == 'commands' + - mautrix_slack_config.bridge.permissions[matrix_bridge_mautrix_slack_homeserver_domain] == 'admin' + - mautrix_slack_config.bridge.relay.enabled + - not mautrix_slack_config.bridge.relay.admin_only + - mautrix_slack_config.bridge.relay.default_relays == ['molecule-workspace/molecule-relay'] + - mautrix_slack_config.logging.min_level == matrix_bridge_mautrix_slack_logging_level + fail_msg: "The rendered configuration does not carry the scenario's Slack behavior" + success_msg: "The rendered configuration carries the scenario's Slack behavior" + + - name: Assert the rendered configuration carries integration secrets + ansible.builtin.assert: + that: + - mautrix_slack_config.provisioning.shared_secret == matrix_bridge_mautrix_slack_provisioning_shared_secret + - mautrix_slack_config.public_media.signing_key == matrix_bridge_mautrix_slack_public_media_signing_key + - mautrix_slack_config.double_puppet.secrets['molecule.remote'] == 'molecule_double_puppet_secret_a7d210' + fail_msg: "The rendered configuration does not carry the scenario's integration secrets" + success_msg: "The rendered configuration carries the scenario's integration secrets" + + - name: Assert the rendered configuration carries the non-default backfill policy + ansible.builtin.assert: + that: + - not mautrix_slack_config.backfill.enabled + - mautrix_slack_config.backfill.max_initial_messages == 19 + - mautrix_slack_config.backfill.max_catchup_messages == 31 + - mautrix_slack_config.backfill.unread_hours_threshold == 73 + - mautrix_slack_config.backfill.threads.max_initial_messages == 11 + fail_msg: "The rendered configuration does not carry the scenario's backfill policy" + success_msg: "The rendered configuration carries the scenario's backfill policy" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - mautrix_slack_config.database.type == matrix_bridge_mautrix_slack_database_engine + - matrix_bridge_mautrix_slack_database_username in mautrix_slack_config.database.uri + - matrix_bridge_mautrix_slack_database_hostname in mautrix_slack_config.database.uri + - matrix_bridge_mautrix_slack_database_name in mautrix_slack_config.database.uri + fail_msg: >- + database.uri is {{ mautrix_slack_config.database.uri | default('unset') }}, which + was not composed from the scenario's connection settings + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_slack_config_path }}/registration.yaml" + register: mautrix_slack_registration_file + + - name: Assert the registration carries the configured handshake values + ansible.builtin.assert: + that: + - mautrix_slack_registration.id == 'slack' + - mautrix_slack_registration.as_token == matrix_bridge_mautrix_slack_appservice_token + - mautrix_slack_registration.hs_token == matrix_bridge_mautrix_slack_homeserver_token + - mautrix_slack_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_slack_appservice_bot_username + - mautrix_slack_registration.url == 'http://matrix-mautrix-slack:8080' + fail_msg: "The registration does not carry the configured handshake values" + success_msg: "The registration carries the configured handshake values" + + - name: Assert the registration namespaces cover only Slack ghosts and the bridge bot + ansible.builtin.assert: + that: + - mautrix_slack_ghost_regex | length > 0 + - mautrix_slack_bot_regex | length > 0 + - mautrix_slack_ghost_mxid is match(mautrix_slack_ghost_regex) + - mautrix_slack_wrong_ghost_mxid is not match(mautrix_slack_ghost_regex) + - mautrix_slack_bot_mxid is match(mautrix_slack_bot_regex) + fail_msg: "The registration namespaces do not cover only Slack ghosts and the bot" + success_msg: "The registration namespaces cover only Slack ghosts and the bot" + vars: + mautrix_slack_user_regexes: "{{ mautrix_slack_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_slack_ghost_regex: "{{ mautrix_slack_user_regexes | select('search', 'slack_') | first | default('') }}" + mautrix_slack_bot_regex: "{{ mautrix_slack_user_regexes | reject('search', 'slack_') | first | default('') }}" + mautrix_slack_ghost_mxid: "@slack_T12345-U67890:{{ matrix_bridge_mautrix_slack_homeserver_domain }}" + mautrix_slack_wrong_ghost_mxid: "@discord_T12345-U67890:{{ matrix_bridge_mautrix_slack_homeserver_domain }}" + mautrix_slack_bot_mxid: "@{{ matrix_bridge_mautrix_slack_appservice_bot_username }}:{{ matrix_bridge_mautrix_slack_homeserver_domain }}" + + # Tables can appear only after hostname resolution, authentication, and real migrations. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_slack_database_username }} + - --dbname={{ matrix_bridge_mautrix_slack_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: mautrix_slack_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - mautrix_slack_tables.rc == 0 + - "'version' in mautrix_slack_table_names" + - "'portal' in mautrix_slack_table_names" + - "'user_login' in mautrix_slack_table_names" + - "'message' in mautrix_slack_table_names" + - "'slack_version' in mautrix_slack_table_names" + - "'emoji' in mautrix_slack_table_names" + - mautrix_slack_table_names | length > 12 + fail_msg: >- + The bridge did not migrate its schema into {{ matrix_bridge_mautrix_slack_database_name }} + (found {{ mautrix_slack_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + mautrix_slack_table_names: "{{ mautrix_slack_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_slack_base_path }}/labels" + register: mautrix_slack_labels_file + + - name: Assert the labels route the public endpoint to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_slack_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_slack_container_network in mautrix_slack_labels_rendered" + - "'traefik.http.services.matrix-mautrix-slack-exposure.loadbalancer.server.port=8080' in mautrix_slack_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-slack-exposure.rule=Host(`slack-api.molecule.local`) && PathPrefix(`/bridges/slack-api`)' in mautrix_slack_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-slack-exposure-strip-prefix.stripprefix.prefixes=/bridges/slack-api' in mautrix_slack_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-slack-exposure.entrypoints=web' in mautrix_slack_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-slack-exposure.tls=false' in mautrix_slack_labels_rendered" + - "'molecule.slack.coverage=enabled' in mautrix_slack_labels_rendered" + fail_msg: "The rendered labels do not carry the scenario's exposure configuration" + success_msg: "The rendered labels carry the scenario's exposure configuration" + + - name: Inspect the running bridge container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-slack + register: mautrix_slack_container_inspect + changed_when: false + + - name: Parse the running bridge container inspection + ansible.builtin.set_fact: + mautrix_slack_container: "{{ (mautrix_slack_container_inspect.stdout | from_json) | first }}" + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - mautrix_slack_container.Config.Image == mautrix_slack_expected_image + fail_msg: >- + The running container uses {{ mautrix_slack_container.Config.Image }}, expected + {{ mautrix_slack_expected_image }} + success_msg: "The running container uses the exact image pinned by the role" + vars: + mautrix_slack_expected_image: >- + {{ mautrix_slack_role_defaults.matrix_bridge_mautrix_slack_container_image_registry_prefix_upstream_default }}mautrix/slack:{{ mautrix_slack_role_defaults.matrix_bridge_mautrix_slack_version }} + + - name: Assert the running container uses the playbook-supplied runtime + ansible.builtin.assert: + that: + - mautrix_slack_container.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + - mautrix_slack_container.Config.WorkingDir == '/data' + - mautrix_slack_container.Config.Cmd == ['/usr/bin/mautrix-slack', '-c', '/config/config.yaml', '-r', '/config/registration.yaml', '--no-update'] + - mautrix_slack_container.HostConfig.RestartPolicy.Name == 'no' + - mautrix_slack_container.HostConfig.AutoRemove + - mautrix_slack_container.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container does not use the role's exact identity and command" + success_msg: "The running container uses the role's exact identity and command" + + - name: Assert the running container has the intended privilege isolation + ansible.builtin.assert: + that: + - "'ALL' in mautrix_slack_container.HostConfig.CapDrop" + - not mautrix_slack_container.HostConfig.Privileged + fail_msg: "The running container does not have the intended privilege isolation" + success_msg: "The running container drops all capabilities and is unprivileged" + + - name: Assert the running container carries the role's exact bind mounts + ansible.builtin.assert: + that: + - mautrix_slack_config_mount | length > 0 + - mautrix_slack_config_mount.Source == matrix_bridge_mautrix_slack_config_path + - not mautrix_slack_config_mount.RW + - mautrix_slack_data_mount | length > 0 + - mautrix_slack_data_mount.Source == matrix_bridge_mautrix_slack_data_path + - mautrix_slack_data_mount.RW + - mautrix_slack_container.Mounts | length == 2 + fail_msg: "The running container does not carry the role's exact config and data mounts" + success_msg: "The running container carries read-only config and writable data mounts" + vars: + mautrix_slack_config_mount: >- + {{ mautrix_slack_container.Mounts + | selectattr('Destination', 'equalto', '/config') + | first | default({}) }} + mautrix_slack_data_mount: >- + {{ mautrix_slack_container.Mounts + | selectattr('Destination', 'equalto', '/data') + | first | default({}) }} + + - name: Assert the rendered labels are attached to the running container + ansible.builtin.assert: + that: + - mautrix_slack_container.Config.Labels['traefik.enable'] == 'true' + - mautrix_slack_container.Config.Labels['traefik.docker.network'] == matrix_bridge_mautrix_slack_container_network + - mautrix_slack_container.Config.Labels['traefik.http.services.matrix-mautrix-slack-exposure.loadbalancer.server.port'] == '8080' + - mautrix_slack_container.Config.Labels['molecule.slack.coverage'] == 'enabled' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The running container carries the labels the role rendered" + + - name: Assert the running container has the exact network and port exposure + ansible.builtin.assert: + that: + - mautrix_slack_container.HostConfig.NetworkMode == matrix_bridge_mautrix_slack_container_network + - matrix_bridge_mautrix_slack_container_network in mautrix_slack_container.NetworkSettings.Networks + - mautrix_slack_container.NetworkSettings.Networks | length == 1 + - mautrix_slack_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: >- + The container has unexpected networks or host ports: + networks={{ mautrix_slack_container.NetworkSettings.Networks.keys() | list }}, + ports={{ mautrix_slack_container.HostConfig.PortBindings | default({}) }} + success_msg: "The container uses only its dedicated network and publishes no host ports" diff --git a/roles/custom/matrix-bridge-mautrix-slack/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-slack/tasks/main.yml index 9112981f2..e745b9f78 100644 --- a/roles/custom/matrix-bridge-mautrix-slack/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-slack/tasks/main.yml @@ -11,15 +11,15 @@ - install-all - install-mautrix-slack block: - - when: matrix_mautrix_slack_enabled | bool + - when: matrix_bridge_mautrix_slack_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_slack_enabled | bool + - when: matrix_bridge_mautrix_slack_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mautrix-slack block: - - when: not matrix_mautrix_slack_enabled | bool + - when: not matrix_bridge_mautrix_slack_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-slack/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-slack/tasks/setup_install.yml index b7311e16c..0506c7343 100644 --- a/roles/custom/matrix-bridge-mautrix-slack/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-slack/tasks/setup_install.yml @@ -7,32 +7,32 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_slack_migration_requires_restart: false + matrix_bridge_mautrix_slack_migration_requires_restart: false -- when: "matrix_mautrix_slack_database_engine == 'postgres'" +- when: "matrix_bridge_mautrix_slack_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mautrix_slack_sqlite_database_path_local }}" - register: matrix_mautrix_slack_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mautrix_slack_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_slack_sqlite_database_path_local_stat_result - - when: "matrix_mautrix_slack_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mautrix_slack_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mautrix_slack_sqlite_database_path_local }}" - dst: "{{ matrix_mautrix_slack_database_connection_string }}" + src: "{{ matrix_bridge_mautrix_slack_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_slack_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mautrix_slack_database_engine' + engine_variable_name: 'matrix_bridge_mautrix_slack_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-mautrix-slack.service'] pgloader_options: ['--with "quote identifiers"'] - ansible.builtin.set_fact: - matrix_mautrix_slack_migration_requires_restart: true + matrix_bridge_mautrix_slack_migration_requires_restart: true - name: Ensure Mautrix Slack paths exists ansible.builtin.file: @@ -42,69 +42,87 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_slack_base_path }}", when: true} - - {path: "{{ matrix_mautrix_slack_config_path }}", when: true} - - {path: "{{ matrix_mautrix_slack_data_path }}", when: true} - - {path: "{{ matrix_mautrix_slack_container_src_files_path }}", when: "{{ matrix_mautrix_slack_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_slack_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_slack_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_slack_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_slack_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_slack_container_image_self_build }}"} when: item.when | bool - name: Ensure Mautrix Slack image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_slack_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_slack_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_slack_container_image_force_pull }}" - when: not matrix_mautrix_slack_container_image_self_build - register: matrix_mautrix_slack_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_slack_container_image }}" + pull: always + when: not matrix_bridge_mautrix_slack_container_image_self_build + register: matrix_bridge_mautrix_slack_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_slack_container_image_pull_result is not failed + until: matrix_bridge_mautrix_slack_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix slack repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_slack_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_slack_container_image_self_build | bool" - name: Ensure Mautrix slack repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_mautrix_slack_container_image_self_build_repo }}" - dest: "{{ matrix_mautrix_slack_container_src_files_path }}" - version: "{{ matrix_mautrix_slack_container_image_self_build_branch }}" + repo: "{{ matrix_bridge_mautrix_slack_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_mautrix_slack_container_src_files_path }}" + version: "{{ matrix_bridge_mautrix_slack_container_image_self_build_branch }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_slack_git_pull_results - when: "matrix_mautrix_slack_container_image_self_build | bool" + register: matrix_bridge_mautrix_slack_git_pull_results + when: "matrix_bridge_mautrix_slack_container_image_self_build | bool" - name: Ensure Mautrix slack Docker image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_slack_container_image }}" - source: build - force_source: "{{ matrix_mautrix_slack_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_slack_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_slack_container_src_files_path }}" - pull: true - when: "matrix_mautrix_slack_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_slack_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_slack_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_slack_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_slack_container_image_self_build | bool" + register: matrix_bridge_mautrix_slack_container_image_build_result - name: Ensure mautrix-slack config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_slack_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_slack_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_slack_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_slack_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_slack_config_result + register: matrix_bridge_mautrix_slack_config_result - name: Ensure mautrix-slack registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_slack_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_slack_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_slack_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_slack_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_slack_registration_result + register: matrix_bridge_mautrix_slack_registration_result + +- name: Ensure mautrix-slack support files installed + ansible.builtin.template: + src: "{{ role_path }}/templates/{{ item }}.j2" + dest: "{{ matrix_bridge_mautrix_slack_base_path }}/{{ item }}" + mode: '0640' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - labels + register: matrix_bridge_mautrix_slack_support_files_result - name: Ensure matrix-mautrix-slack container network is created + when: matrix_bridge_mautrix_slack_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_slack_container_network }}" + name: "{{ matrix_bridge_mautrix_slack_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -113,17 +131,19 @@ src: "{{ role_path }}/templates/systemd/matrix-mautrix-slack.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-slack.service" mode: '0644' - register: matrix_mautrix_slack_systemd_service_result + register: matrix_bridge_mautrix_slack_systemd_service_result - name: Determine whether matrix-mautrix-slack needs a restart ansible.builtin.set_fact: - matrix_mautrix_slack_restart_necessary: >- + matrix_bridge_mautrix_slack_restart_necessary: >- {{ - matrix_mautrix_slack_migration_requires_restart | default(false) - or matrix_mautrix_slack_config_result.changed | default(false) - or matrix_mautrix_slack_registration_result.changed | default(false) - or matrix_mautrix_slack_systemd_service_result.changed | default(false) - or matrix_mautrix_slack_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_slack_migration_requires_restart | default(false) + or matrix_bridge_mautrix_slack_config_result.changed | default(false) + or matrix_bridge_mautrix_slack_registration_result.changed | default(false) + or matrix_bridge_mautrix_slack_support_files_result.changed | default(false) + or matrix_bridge_mautrix_slack_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_slack_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_slack_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mautrix-slack.service restarted, if necessary @@ -131,4 +151,4 @@ name: "matrix-mautrix-slack.service" state: restarted daemon_reload: true - when: "matrix_mautrix_slack_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_slack_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-slack/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-slack/tasks/setup_uninstall.yml index 7361983d2..5b742c77c 100644 --- a/roles/custom/matrix-bridge-mautrix-slack/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-slack/tasks/setup_uninstall.yml @@ -7,9 +7,9 @@ - name: Check existence of matrix-mautrix-slack service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-slack.service" - register: matrix_mautrix_slack_service_stat + register: matrix_bridge_mautrix_slack_service_stat -- when: matrix_mautrix_slack_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_slack_service_stat.stat.exists | bool block: - name: Ensure matrix-mautrix-slack is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mautrix-slack/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-slack/tasks/validate_config.yml index 7594385d3..1f3f3a6ab 100644 --- a/roles/custom/matrix-bridge-mautrix-slack/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-slack/tasks/validate_config.yml @@ -13,16 +13,17 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_slack_login_shared_secret', 'new': ''} - - {'old': 'matrix_mautrix_slack_bridge_login_shared_secret_map', 'new': ''} - - {'old': 'matrix_mautrix_slack_bridge_double_puppet_server_map', 'new': ''} - - {'old': 'matrix_mautrix_slack_docker_image_name_prefix', 'new': 'matrix_mautrix_slack_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_slack_docker_image', 'new': 'matrix_mautrix_slack_container_image'} - - {'old': 'matrix_mautrix_slack_docker_image_force_pull', 'new': 'matrix_mautrix_slack_container_image_force_pull'} - - {'old': 'matrix_mautrix_slack_docker_image_registry_prefix', 'new': 'matrix_mautrix_slack_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_slack_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_slack_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_slack_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_slack_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_slack_docker_src_files_path', 'new': 'matrix_mautrix_slack_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_slack_login_shared_secret', 'new': ''} + - {'old': 'matrix_bridge_mautrix_slack_bridge_login_shared_secret_map', 'new': ''} + - {'old': 'matrix_bridge_mautrix_slack_bridge_double_puppet_server_map', 'new': ''} + - {'old': 'matrix_bridge_mautrix_slack_docker_image_name_prefix', 'new': 'matrix_bridge_mautrix_slack_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_slack_docker_image', 'new': 'matrix_bridge_mautrix_slack_container_image'} + - {'old': 'matrix_bridge_mautrix_slack_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_slack_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_slack_docker_image_registry_prefix', 'new': 'matrix_bridge_mautrix_slack_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_slack_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mautrix_slack_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mautrix_slack_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mautrix_slack_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mautrix_slack_docker_src_files_path', 'new': 'matrix_bridge_mautrix_slack_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_slack_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required mautrix-slack settings not defined ansible.builtin.fail: @@ -30,8 +31,8 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_slack_appservice_token', when: true} - - {'name': 'matrix_mautrix_slack_homeserver_address', when: true} - - {'name': 'matrix_mautrix_slack_homeserver_token', when: true} - - {'name': 'matrix_mautrix_slack_database_hostname', when: "{{ matrix_mautrix_slack_database_engine == 'postgres' }}"} - - {'name': 'matrix_mautrix_slack_container_network', when: true} + - {'name': 'matrix_bridge_mautrix_slack_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_slack_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_slack_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_slack_database_hostname', when: "{{ matrix_bridge_mautrix_slack_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_slack_container_network', when: true} diff --git a/roles/custom/matrix-bridge-mautrix-slack/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-slack/templates/config.yaml.j2 index f2a2e8782..21766950c 100644 --- a/roles/custom/matrix-bridge-mautrix-slack/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-slack/templates/config.yaml.j2 @@ -20,7 +20,7 @@ network: # .Profile.Pronouns - The pronouns of the user # .Profile.Email - The email address of the user # .Profile.Phone - The formatted phone number of the user - displayname_template: {{ matrix_mautrix_slack_network_displayname_template | to_json }} + displayname_template: {{ matrix_bridge_mautrix_slack_network_displayname_template | to_json }} # Channel name template for Slack channels (all types). Available variables: # .Name - The name of the channel # .Team.Name - The name of the team the channel is in @@ -66,7 +66,7 @@ network: # Config options that affect the central bridge module. bridge: # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_mautrix_slack_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_mautrix_slack_command_prefix | to_json }} # Should the bridge create a space for each login containing the rooms that account is in? personal_filtering_spaces: true # Whether the bridge should set names and avatars explicitly for DM portals. @@ -113,12 +113,12 @@ bridge: relay: # Whether relay mode should be allowed. If allowed, the set-relay command can be used to turn any # authenticated user into a relaybot for that chat. - enabled: {{ matrix_mautrix_slack_bridge_relay_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_slack_bridge_relay_enabled | to_json }} # Should only admins be allowed to set themselves as relay users? # If true, non-admins can only set users listed in default_relays as relays in a room. - admin_only: {{ matrix_mautrix_slack_bridge_relay_admin_only | to_json }} + admin_only: {{ matrix_bridge_mautrix_slack_bridge_relay_admin_only | to_json }} # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. - default_relays: {{ matrix_mautrix_slack_bridge_relay_default_relays | to_json }} + default_relays: {{ matrix_bridge_mautrix_slack_bridge_relay_default_relays | to_json }} # The formats to use when sending messages via the relaybot. # Available variables: # .Sender.UserID - The Matrix user ID of the sender. @@ -154,18 +154,18 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_slack_bridge_permissions | to_json }} + permissions: {{ matrix_bridge_mautrix_slack_bridge_permissions | to_json }} # Config for the bridge's database. database: # The database type. "sqlite3-fk-wal" and "postgres" are supported. - type: {{ matrix_mautrix_slack_appservice_database_type | to_json }} + type: {{ matrix_bridge_mautrix_slack_appservice_database_type | to_json }} # The database URI. # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. # https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_mautrix_slack_appservice_database_uri | to_json }} + uri: {{ matrix_bridge_mautrix_slack_appservice_database_uri | to_json }} # Maximum number of connections. max_open_conns: 5 max_idle_conns: 1 @@ -179,9 +179,9 @@ homeserver: # The address that this appservice can use to connect to the homeserver. # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, # but https also works if they run on different machines. - address: {{ matrix_mautrix_slack_homeserver_address | to_json }} + address: {{ matrix_bridge_mautrix_slack_homeserver_address | to_json }} # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: {{ matrix_mautrix_slack_homeserver_domain | to_json }} + domain: {{ matrix_bridge_mautrix_slack_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -197,7 +197,7 @@ homeserver: # The bridge will use the appservice as_token to authorize requests. message_send_checkpoint_endpoint: # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_mautrix_slack_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_mautrix_slack_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -210,10 +210,10 @@ homeserver: # Changing these values requires regeneration of the registration (except when noted otherwise) appservice: # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_mautrix_slack_appservice_address | to_json }} + address: {{ matrix_bridge_mautrix_slack_appservice_address | to_json }} # A public address that external services can use to reach this appservice. # This value doesn't affect the registration file. - public_address: https://bridge.example.com + public_address: {{ matrix_bridge_mautrix_slack_bridge_public_address | to_json }} # The hostname and port where this appservice should listen. # For Docker, you generally have to change the hostname to 0.0.0.0. @@ -225,7 +225,7 @@ appservice: # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_mautrix_slack_appservice_bot_username | to_json }} + username: {{ matrix_bridge_mautrix_slack_appservice_bot_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. displayname: Slack bridge bot @@ -240,8 +240,8 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_mautrix_slack_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_slack_homeserver_token | to_json }} + as_token: {{ matrix_bridge_mautrix_slack_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_slack_homeserver_token | to_json }} # Localpart template of MXIDs for remote users. # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. @@ -267,7 +267,7 @@ provisioning: prefix: /_matrix/provision # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, # or if set to "disable", the provisioning API will be disabled. - shared_secret: {{ matrix_mautrix_slack_provisioning_shared_secret | to_json }} + shared_secret: {{ matrix_bridge_mautrix_slack_provisioning_shared_secret | to_json }} # Whether to allow provisioning API requests to be authed using Matrix access tokens. # This follows the same rules as double puppeting to determine which server to contact to check the token, # which means that by default, it only works for users on the same server as the bridge. @@ -283,7 +283,7 @@ public_media: enabled: false # A key for signing public media URLs. # If set to "generate", a random key will be generated. - signing_key: {{ matrix_mautrix_slack_public_media_signing_key | to_json }} + signing_key: {{ matrix_bridge_mautrix_slack_public_media_signing_key | to_json }} # Number of seconds that public media URLs are valid for. # If set to 0, URLs will never expire. expiry: 0 @@ -317,18 +317,18 @@ direct_media: # See https://docs.mau.fi/bridges/general/backfill.html for more details. backfill: # Whether to do backfilling at all. - enabled: {{ matrix_mautrix_slack_backfill_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_slack_backfill_enabled | to_json }} # Maximum number of messages to backfill in empty rooms. - max_initial_messages: {{ matrix_mautrix_slack_backfill_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_mautrix_slack_backfill_max_initial_messages | to_json }} # Maximum number of missed messages to backfill after bridge restarts. - max_catchup_messages: {{ matrix_mautrix_slack_backfill_max_catchup_messages | to_json }} + max_catchup_messages: {{ matrix_bridge_mautrix_slack_backfill_max_catchup_messages | to_json }} # If a backfilled chat is older than this number of hours, # mark it as read even if it's unread on the remote network. - unread_hours_threshold: {{ matrix_mautrix_slack_backfill_unread_hours_threshold| to_json }} + unread_hours_threshold: {{ matrix_bridge_mautrix_slack_backfill_unread_hours_threshold| to_json }} # Settings for backfilling threads within other backfills. threads: # Maximum number of messages to backfill in a new thread. - max_initial_messages: {{ matrix_mautrix_slack_backfill_threads_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_mautrix_slack_backfill_threads_max_initial_messages | to_json }} # Settings for the backwards backfill queue. This only applies when connecting to # Beeper as standard Matrix servers don't support inserting messages into history. queue: @@ -356,16 +356,16 @@ double_puppet: allow_discovery: false # Shared secrets for automatic double puppeting. # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. - secrets: {{ matrix_mautrix_slack_double_puppet_secrets | to_json }} + secrets: {{ matrix_bridge_mautrix_slack_double_puppet_secrets | to_json }} # End-to-bridge encryption support options. # # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. - allow: {{ matrix_mautrix_slack_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_mautrix_slack_bridge_encryption_allow | to_json }} # Whether to force-enable encryption in all bridged rooms. - default: {{ matrix_mautrix_slack_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_mautrix_slack_bridge_encryption_default | to_json }} # Whether to require all messages to be encrypted and drop any unencrypted messages. require: false # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. @@ -375,16 +375,16 @@ encryption: # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_mautrix_slack_msc4190_enabled | to_json }} + msc4190: {{ matrix_bridge_mautrix_slack_msc4190_enabled | to_json }} # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) # Requires msc4190 to replace keys on reset - self_sign: {{ matrix_mautrix_slack_self_sign_enabled | to_json }} + self_sign: {{ matrix_bridge_mautrix_slack_self_sign_enabled | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_mautrix_slack_bridge_encryption_key_sharing_allow | to_json }} + allow_key_sharing: {{ matrix_bridge_mautrix_slack_bridge_encryption_key_sharing_allow | to_json }} # Pickle key for encrypting encryption keys in the bridge database. # If set to generate, a random key will be generated. - pickle_key: {{ matrix_mautrix_slack_bridge_encryption_pickle_key | to_json }} + pickle_key: {{ matrix_bridge_mautrix_slack_bridge_encryption_pickle_key | to_json }} # Options for deleting megolm sessions from the bridge. delete_keys: # Beeper-specific: delete outbound sessions when hungryserv confirms @@ -443,7 +443,7 @@ encryption: # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_mautrix_slack_logging_level | to_json }} + min_level: {{ matrix_bridge_mautrix_slack_logging_level | to_json }} writers: - type: stdout format: pretty-colored diff --git a/roles/custom/matrix-bridge-mautrix-slack/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-slack/templates/labels.j2 new file mode 100644 index 000000000..df677d392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-slack/templates/labels.j2 @@ -0,0 +1,50 @@ +{# +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later +#} + +{% if matrix_bridge_mautrix_slack_container_labels_traefik_enabled %} +traefik.enable=true + +{% if matrix_bridge_mautrix_slack_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_slack_container_labels_traefik_docker_network }} +{% endif %} + +{% if matrix_bridge_mautrix_slack_container_labels_exposure_enabled %} +############################################################ +# # +# Bridge API exposure # +# # +############################################################ + +traefik.http.services.matrix-mautrix-slack-exposure.loadbalancer.server.port=8080 + +traefik.http.middlewares.matrix-mautrix-slack-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_slack_exposure_path_prefix }} +traefik.http.routers.matrix-mautrix-slack-exposure.middlewares=matrix-mautrix-slack-exposure-strip-prefix + +traefik.http.routers.matrix-mautrix-slack-exposure.rule={{ matrix_bridge_mautrix_slack_container_labels_exposure_traefik_rule }} + +{% if matrix_bridge_mautrix_slack_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-slack-exposure.priority={{ matrix_bridge_mautrix_slack_container_labels_exposure_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-mautrix-slack-exposure.service=matrix-mautrix-slack-exposure +traefik.http.routers.matrix-mautrix-slack-exposure.entrypoints={{ matrix_bridge_mautrix_slack_container_labels_exposure_traefik_entrypoints }} + +traefik.http.routers.matrix-mautrix-slack-exposure.tls={{ matrix_bridge_mautrix_slack_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_slack_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-mautrix-slack-exposure.tls.certResolver={{ matrix_bridge_mautrix_slack_container_labels_exposure_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Bridge API exposure # +# # +############################################################ +{% endif %} + + +{% endif %} + +{{ matrix_bridge_mautrix_slack_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-slack/templates/systemd/matrix-mautrix-slack.service.j2 b/roles/custom/matrix-bridge-mautrix-slack/templates/systemd/matrix-mautrix-slack.service.j2 index 200adc7f2..d4f8edd96 100644 --- a/roles/custom/matrix-bridge-mautrix-slack/templates/systemd/matrix-mautrix-slack.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-slack/templates/systemd/matrix-mautrix-slack.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix Slack bridge -{% for service in matrix_mautrix_slack_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_slack_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_slack_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_slack_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,19 +22,22 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_slack_container_network }} \ - --mount type=bind,src={{ matrix_mautrix_slack_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_mautrix_slack_data_path }},dst=/data \ + --network={{ matrix_bridge_mautrix_slack_container_network }} \ + --mount type=bind,src={{ matrix_bridge_mautrix_slack_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_slack_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_slack_base_path }}/labels \ --workdir=/data \ - {% for arg in matrix_mautrix_slack_container_extra_arguments %} + {% for arg in matrix_bridge_mautrix_slack_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_slack_container_image }} \ + {{ matrix_bridge_mautrix_slack_container_image }} \ /usr/bin/mautrix-slack -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_mautrix_slack_container_additional_networks %} +{% if matrix_bridge_mautrix_slack_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_slack_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-slack {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-slack diff --git a/roles/custom/matrix-bridge-mautrix-telegram/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-telegram/defaults/main.yml index 007d0a936..a5d5ab5c6 100644 --- a/roles/custom/matrix-bridge-mautrix-telegram/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-telegram/defaults/main.yml @@ -1,5 +1,5 @@ # SPDX-FileCopyrightText: 2019 - 2024 MDAD project contributors -# SPDX-FileCopyrightText: 2019 - 2025 Slavi Pantaleev +# SPDX-FileCopyrightText: 2019 - 2026 Slavi Pantaleev # SPDX-FileCopyrightText: 2020 Johanna Dorothea Reichmann # SPDX-FileCopyrightText: 2020 Marcel Partap # SPDX-FileCopyrightText: 2021 Aaron Raimist @@ -19,247 +19,232 @@ # mautrix-telegram is a Matrix <-> Telegram bridge # Project source code URL: https://github.com/mautrix/telegram -matrix_mautrix_telegram_enabled: true +matrix_bridge_mautrix_telegram_enabled: true -matrix_mautrix_telegram_scheme: https -matrix_mautrix_telegram_hostname: '' -matrix_mautrix_telegram_path_prefix: '' - -matrix_mautrix_telegram_lottieconverter_container_image_self_build: false -matrix_mautrix_telegram_lottieconverter_container_image_self_build_mask_arch: false -matrix_mautrix_telegram_lottieconverter_container_repo: "https://mau.dev/tulir/lottieconverter.git" -matrix_mautrix_telegram_lottieconverter_container_repo_version: "master" -matrix_mautrix_telegram_lottieconverter_container_src_files_path: "{{ matrix_base_data_path }}/lotticonverter/docker-src" -matrix_mautrix_telegram_lottieconverter_container_image: "{{ matrix_mautrix_telegram_lottieconverter_container_image_registry_prefix }}tulir/lottieconverter:alpine-3.16" # needs to be adjusted according to the FROM clause of Dockerfile of mautrix-telegram -matrix_mautrix_telegram_lottieconverter_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_telegram_lottieconverter_container_image_self_build else matrix_mautrix_telegram_lottieconverter_container_image_registry_prefix_upstream }}" -matrix_mautrix_telegram_lottieconverter_container_image_registry_prefix_upstream: "{{ matrix_mautrix_telegram_lottieconverter_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_telegram_lottieconverter_container_image_registry_prefix_upstream_default: "dock.mau.dev/" - -matrix_mautrix_telegram_container_image_self_build: false -matrix_mautrix_telegram_container_repo: "https://mau.dev/mautrix/telegram.git" -matrix_mautrix_telegram_container_repo_version: "{{ 'master' if matrix_mautrix_telegram_version == 'latest' else matrix_mautrix_telegram_version }}" -matrix_mautrix_telegram_container_src_files_path: "{{ matrix_base_data_path }}/mautrix-telegram/docker-src" +matrix_bridge_mautrix_telegram_container_image_self_build: false +matrix_bridge_mautrix_telegram_container_image_self_build_repo: "https://mau.dev/mautrix/telegram.git" +matrix_bridge_mautrix_telegram_container_image_self_build_branch: "{{ 'main' if matrix_bridge_mautrix_telegram_version == 'latest' else matrix_bridge_mautrix_telegram_version }}" # renovate: datasource=docker depName=dock.mau.dev/mautrix/telegram -matrix_mautrix_telegram_version: v0.15.3 -# See: https://mau.dev/mautrix/telegram/container_registry -matrix_mautrix_telegram_container_image: "{{ matrix_mautrix_telegram_container_image_registry_prefix }}mautrix/telegram:{{ matrix_mautrix_telegram_version }}" -matrix_mautrix_telegram_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_telegram_container_image_self_build else matrix_mautrix_telegram_container_image_registry_prefix_upstream }}" -matrix_mautrix_telegram_container_image_registry_prefix_upstream: "{{ matrix_mautrix_telegram_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_telegram_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_telegram_container_image_force_pull: "{{ matrix_mautrix_telegram_container_image.endswith(':latest') }}" - -matrix_mautrix_telegram_base_path: "{{ matrix_base_data_path }}/mautrix-telegram" -matrix_mautrix_telegram_config_path: "{{ matrix_mautrix_telegram_base_path }}/config" -matrix_mautrix_telegram_data_path: "{{ matrix_mautrix_telegram_base_path }}/data" - -matrix_mautrix_telegram_command_prefix: "!tg" +matrix_bridge_mautrix_telegram_version: v0.2608.0 -matrix_mautrix_telegram_bridge_permissions: | - {{ - {'*': 'relaybot', matrix_mautrix_telegram_homeserver_domain: 'full'} - | combine({matrix_admin: 'admin'} if matrix_admin else {}) - }} - -# Get your own API keys at https://my.telegram.org/apps -matrix_mautrix_telegram_api_id: '' -matrix_mautrix_telegram_api_hash: '' -matrix_mautrix_telegram_bot_token: disabled - -# Define the filter-mode -matrix_mautrix_telegram_filter_mode: "blacklist" - -# Whether or not the public-facing endpoints should be enabled (web-based login) -matrix_mautrix_telegram_appservice_public_enabled: true - -# Mautrix telegram public endpoint to log in to telegram -# Use an uuid so it's not easily discoverable. -# Example: /741a0483-ba17-4682-9900-30bd7269f1cc -matrix_mautrix_telegram_public_endpoint: "{{ matrix_mautrix_telegram_path_prefix }}" - -matrix_mautrix_telegram_homeserver_address: "" -matrix_mautrix_telegram_homeserver_domain: '{{ matrix_domain }}' +# See: https://mau.dev/mautrix/telegram/container_registry +matrix_bridge_mautrix_telegram_container_image: "{{ matrix_bridge_mautrix_telegram_container_image_registry_prefix }}mautrix/telegram:{{ matrix_bridge_mautrix_telegram_version }}" +matrix_bridge_mautrix_telegram_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_telegram_container_image_self_build else matrix_bridge_mautrix_telegram_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_telegram_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_telegram_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_telegram_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bridge_mautrix_telegram_base_path: "{{ matrix_base_data_path }}/mautrix-telegram" +matrix_bridge_mautrix_telegram_config_path: "{{ matrix_bridge_mautrix_telegram_base_path }}/config" +matrix_bridge_mautrix_telegram_data_path: "{{ matrix_bridge_mautrix_telegram_base_path }}/data" +matrix_bridge_mautrix_telegram_container_src_files_path: "{{ matrix_bridge_mautrix_telegram_base_path }}/docker-src" + +matrix_bridge_mautrix_telegram_homeserver_address: "" +matrix_bridge_mautrix_telegram_homeserver_domain: '{{ matrix_domain }}' # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_mautrix_telegram_homeserver_async_media: false -matrix_mautrix_telegram_appservice_address: 'http://matrix-mautrix-telegram:8080' -matrix_mautrix_telegram_appservice_public_external: '{{ matrix_mautrix_telegram_scheme }}://{{ matrix_mautrix_telegram_hostname }}{{ matrix_mautrix_telegram_public_endpoint }}' +matrix_bridge_mautrix_telegram_homeserver_async_media: false +matrix_bridge_mautrix_telegram_appservice_address: 'http://matrix-mautrix-telegram:8080' -matrix_mautrix_telegram_appservice_bot_username: telegrambot +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_telegram_bridge_public_address`). +matrix_bridge_mautrix_telegram_scheme: https -matrix_mautrix_telegram_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +# The public base URL at which this bridge's HTTP API is reachable from outside (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_telegram_bridge_public_address: "{{ (matrix_bridge_mautrix_telegram_scheme + '://' + matrix_bridge_mautrix_telegram_exposure_hostname + matrix_bridge_mautrix_telegram_exposure_path_prefix) if matrix_bridge_mautrix_telegram_exposure_enabled else '' }}" -# Specifies the default log level for all bridge loggers. -matrix_mautrix_telegram_logging_level: WARNING +matrix_bridge_mautrix_telegram_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_telegram_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" -# Whether or not created rooms should have federation enabled. -# If false, created portal rooms will never be federated. -matrix_mautrix_telegram_federate_rooms: true +matrix_bridge_mautrix_telegram_command_prefix: "!tg" -# Controls whether the matrix-mautrix-telegram container exposes its HTTP port (tcp/8080 in the container). -# -# Takes an ":" or "" value (e.g. "127.0.0.1:9006"), or empty string to not expose. -matrix_mautrix_telegram_container_http_host_bind_port: '' +# Get your own API keys at https://my.telegram.org/apps +matrix_bridge_mautrix_telegram_api_id: '' +matrix_bridge_mautrix_telegram_api_hash: '' -matrix_mautrix_telegram_container_network: "" +matrix_bridge_mautrix_telegram_container_network: "" -matrix_mautrix_telegram_container_additional_networks: "{{ matrix_mautrix_telegram_container_additional_networks_auto + matrix_mautrix_telegram_container_additional_networks_custom }}" -matrix_mautrix_telegram_container_additional_networks_auto: [] -matrix_mautrix_telegram_container_additional_networks_custom: [] +matrix_bridge_mautrix_telegram_container_additional_networks: "{{ matrix_bridge_mautrix_telegram_container_additional_networks_auto + matrix_bridge_mautrix_telegram_container_additional_networks_custom }}" +matrix_bridge_mautrix_telegram_container_additional_networks_auto: [] +matrix_bridge_mautrix_telegram_container_additional_networks_custom: [] -# matrix_mautrix_telegram_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_mautrix_telegram_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_telegram_container_labels_additional_labels`. -matrix_mautrix_telegram_container_labels_traefik_enabled: true -matrix_mautrix_telegram_container_labels_traefik_docker_network: "{{ matrix_mautrix_telegram_container_network }}" -matrix_mautrix_telegram_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_telegram_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose mautrix-telegram's public endpoint -matrix_mautrix_telegram_container_labels_public_endpoint_enabled: "{{ matrix_mautrix_telegram_appservice_public_enabled }}" -matrix_mautrix_telegram_container_labels_public_endpoint_hostname: "{{ matrix_mautrix_telegram_hostname }}" -matrix_mautrix_telegram_container_labels_public_endpoint_path_prefix: "{{ matrix_mautrix_telegram_path_prefix }}" -matrix_mautrix_telegram_container_labels_public_endpoint_traefik_rule: "Host(`{{ matrix_mautrix_telegram_container_labels_public_endpoint_hostname }}`) && PathPrefix(`{{ matrix_mautrix_telegram_container_labels_public_endpoint_path_prefix }}`)" -matrix_mautrix_telegram_container_labels_public_endpoint_traefik_priority: 0 -matrix_mautrix_telegram_container_labels_public_endpoint_traefik_entrypoints: "{{ matrix_mautrix_telegram_container_labels_traefik_entrypoints }}" -matrix_mautrix_telegram_container_labels_public_endpoint_traefik_tls: "{{ matrix_mautrix_telegram_container_labels_public_endpoint_traefik_entrypoints != 'web' }}" -matrix_mautrix_telegram_container_labels_public_endpoint_traefik_tls_certResolver: "{{ matrix_mautrix_telegram_container_labels_traefik_tls_certResolver }}" # noqa var-naming - -# Controls whether labels will be added that expose mautrix-telegram's metrics -matrix_mautrix_telegram_container_labels_metrics_enabled: "{{ matrix_mautrix_telegram_metrics_enabled and matrix_mautrix_telegram_metrics_proxying_enabled }}" -matrix_mautrix_telegram_container_labels_metrics_traefik_rule: "Host(`{{ matrix_mautrix_telegram_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_mautrix_telegram_metrics_proxying_path_prefix }}`)" -matrix_mautrix_telegram_container_labels_metrics_traefik_priority: 0 -matrix_mautrix_telegram_container_labels_metrics_traefik_entrypoints: "{{ matrix_mautrix_telegram_container_labels_traefik_entrypoints }}" -matrix_mautrix_telegram_container_labels_metrics_traefik_tls: "{{ matrix_mautrix_telegram_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_mautrix_telegram_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_mautrix_telegram_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_mautrix_telegram_container_labels_metrics_middleware_basic_auth_enabled: false -# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_mautrix_telegram_container_labels_metrics_middleware_basic_auth_users: '' - -# matrix_mautrix_telegram_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# To inject your own other container labels, see `matrix_bridge_mautrix_telegram_container_labels_additional_labels`. +matrix_bridge_mautrix_telegram_container_labels_traefik_enabled: true +matrix_bridge_mautrix_telegram_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_telegram_container_network }}" +matrix_bridge_mautrix_telegram_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_telegram_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-telegram's HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_telegram_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_telegram_exposure_enabled }}" +matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_telegram_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_telegram_exposure_path_prefix }}`)" +matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_telegram_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_telegram_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_telegram_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_telegram_container_labels_additional_labels: | +# matrix_bridge_mautrix_telegram_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_telegram_container_labels_additional_labels: '' +matrix_bridge_mautrix_telegram_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_telegram_container_extra_arguments: [] +matrix_bridge_mautrix_telegram_container_extra_arguments: [] # List of systemd services that matrix-mautrix-telegram.service depends on. -matrix_mautrix_telegram_systemd_required_services_list: "{{ matrix_mautrix_telegram_systemd_required_services_list_default + matrix_mautrix_telegram_systemd_required_services_list_auto + matrix_mautrix_telegram_systemd_required_services_list_custom }}" -matrix_mautrix_telegram_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_telegram_systemd_required_services_list_auto: [] -matrix_mautrix_telegram_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_telegram_systemd_required_services_list: "{{ matrix_bridge_mautrix_telegram_systemd_required_services_list_default + matrix_bridge_mautrix_telegram_systemd_required_services_list_auto + matrix_bridge_mautrix_telegram_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_telegram_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_telegram_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_telegram_systemd_required_services_list_custom: [] # List of systemd services that matrix-mautrix-telegram.service wants -matrix_mautrix_telegram_systemd_wanted_services_list: [] +matrix_bridge_mautrix_telegram_systemd_wanted_services_list: [] -matrix_mautrix_telegram_appservice_token: '' -matrix_mautrix_telegram_homeserver_token: '' +matrix_bridge_mautrix_telegram_appservice_token: '' +matrix_bridge_mautrix_telegram_homeserver_token: '' -matrix_mautrix_telegram_provisioning_shared_secret: disable +matrix_bridge_mautrix_telegram_appservice_bot_username: telegrambot -# Whether or not metrics endpoint should be enabled. -# Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_mautrix_telegram_metrics_proxying_enabled`. -matrix_mautrix_telegram_metrics_enabled: false +# Minimum severity of journal log messages. +# Valid values: fatal, error, warn, info, debug, trace +matrix_bridge_mautrix_telegram_logging_level: 'warn' -# Controls whether metrics should be exposed on a public URL. -matrix_mautrix_telegram_metrics_proxying_enabled: false -matrix_mautrix_telegram_metrics_proxying_hostname: '' -matrix_mautrix_telegram_metrics_proxying_path_prefix: '' +# Whether or not created rooms should have federation enabled. +# If false, created portal rooms will never be federated. +matrix_bridge_mautrix_telegram_federate_rooms: true + +# Controls whether mautrix-telegram's HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_telegram_exposure_enabled: false +matrix_bridge_mautrix_telegram_exposure_hostname: '' +matrix_bridge_mautrix_telegram_exposure_path_prefix: '' # Database-related configuration fields. # # To use SQLite, stick to these defaults. # # To use Postgres: -# - change the engine (`matrix_mautrix_telegram_database_engine: 'postgres'`) -# - adjust your database credentials via the `matrix_mautrix_telegram_database_*` variables -matrix_mautrix_telegram_database_engine: 'sqlite' +# - change the engine (`matrix_bridge_mautrix_telegram_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_mautrix_telegram_database_*` variables +matrix_bridge_mautrix_telegram_database_engine: 'sqlite' + +matrix_bridge_mautrix_telegram_sqlite_database_path_local: "{{ matrix_bridge_mautrix_telegram_data_path }}/mautrix-telegram.db" +matrix_bridge_mautrix_telegram_sqlite_database_path_in_container: "/data/mautrix-telegram.db" + +matrix_bridge_mautrix_telegram_database_username: 'matrix_mautrix_telegram' +matrix_bridge_mautrix_telegram_database_password: 'some-password' +matrix_bridge_mautrix_telegram_database_hostname: '' +matrix_bridge_mautrix_telegram_database_port: 5432 +matrix_bridge_mautrix_telegram_database_name: 'matrix_mautrix_telegram' +matrix_bridge_mautrix_telegram_database_sslmode: disable + +matrix_bridge_mautrix_telegram_database_connection_string: 'postgresql://{{ matrix_bridge_mautrix_telegram_database_username }}:{{ matrix_bridge_mautrix_telegram_database_password }}@{{ matrix_bridge_mautrix_telegram_database_hostname }}:{{ matrix_bridge_mautrix_telegram_database_port }}/{{ matrix_bridge_mautrix_telegram_database_name }}?sslmode={{ matrix_bridge_mautrix_telegram_database_sslmode }}' + +matrix_bridge_mautrix_telegram_appservice_database_type: "{{ { + 'sqlite': 'sqlite3-fk-wal', + 'postgres': 'postgres', +}[matrix_bridge_mautrix_telegram_database_engine] }}" + +matrix_bridge_mautrix_telegram_appservice_database_uri: "{{ { + 'sqlite': matrix_bridge_mautrix_telegram_sqlite_database_path_in_container, + 'postgres': matrix_bridge_mautrix_telegram_database_connection_string, +}[matrix_bridge_mautrix_telegram_database_engine] }}" + +matrix_bridge_mautrix_telegram_double_puppet_secrets: "{{ matrix_bridge_mautrix_telegram_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_telegram_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_telegram_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_telegram_double_puppet_secrets_custom: {} + +# Displayname template for Telegram users. +# Available variables: +# {{ .FullName }} - the full name of the Telegram user +# {{ .FirstName }} - the first name of the Telegram user +# {{ .LastName }} - the last name of the Telegram user +# {{ .Username }} - the primary username of the Telegram user, if the user has one +# {{ .UserID }} - the internal user ID of the Telegram user +# {{ .Deleted }} - true if the user has been deleted, false otherwise +matrix_bridge_mautrix_telegram_network_displayname_template: '{% raw %}{{ if .Deleted }}Deleted account {{ .UserID }}{{ else }}{{ .FullName }}{{ end }}{% endraw %}' + +# Enable End-to-bridge encryption +matrix_bridge_mautrix_telegram_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_telegram_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_telegram_bridge_encryption_require: false +matrix_bridge_mautrix_telegram_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_mautrix_telegram_bridge_encryption_allow }}" +# This pickle key value is backward-compatible with the legacy (Python) bridge. +# See: https://mau.dev/mautrix/telegram/-/blob/v0.2604.0/cmd/mautrix-telegram/legacymigrate.go +matrix_bridge_mautrix_telegram_bridge_encryption_pickle_key: mautrix.bridge.e2ee -matrix_mautrix_telegram_sqlite_database_path_local: "{{ matrix_mautrix_telegram_data_path }}/mautrix-telegram.db" -matrix_mautrix_telegram_sqlite_database_path_in_container: "/data/mautrix-telegram.db" +matrix_bridge_mautrix_telegram_bridge_personal_filtering_spaces: true + +matrix_bridge_mautrix_telegram_provisioning_shared_secret: '' +matrix_bridge_mautrix_telegram_public_media_signing_key: '' + +matrix_bridge_mautrix_telegram_bridge_permissions: | + {{ + {'*': 'relay', matrix_bridge_mautrix_telegram_homeserver_domain: 'user'} + | combine({matrix_admin: 'admin'} if matrix_admin else {}) + }} -matrix_mautrix_telegram_database_username: 'matrix_mautrix_telegram' -matrix_mautrix_telegram_database_password: 'some-password' -matrix_mautrix_telegram_database_hostname: '' -matrix_mautrix_telegram_database_port: 5432 -matrix_mautrix_telegram_database_name: 'matrix_mautrix_telegram' +# Enable bridge relay functionality +matrix_bridge_mautrix_telegram_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" -matrix_mautrix_telegram_database_connection_string: 'postgres://{{ matrix_mautrix_telegram_database_username }}:{{ matrix_mautrix_telegram_database_password }}@{{ matrix_mautrix_telegram_database_hostname }}:{{ matrix_mautrix_telegram_database_port }}/{{ matrix_mautrix_telegram_database_name }}' +# Only allow admins on this home server to set themselves as a relay user +matrix_bridge_mautrix_telegram_bridge_relay_admin_only: true -matrix_mautrix_telegram_appservice_database: "{{ - { - 'sqlite': ('sqlite:///' + matrix_mautrix_telegram_sqlite_database_path_in_container), - 'postgres': matrix_mautrix_telegram_database_connection_string, - }[matrix_mautrix_telegram_database_engine] -}}" +# List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. +matrix_bridge_mautrix_telegram_bridge_relay_default_relays: [] -matrix_mautrix_telegram_bridge_login_shared_secret_map: "{{ matrix_mautrix_telegram_bridge_login_shared_secret_map_auto | combine(matrix_mautrix_telegram_bridge_login_shared_secret_map_custom) }}" -matrix_mautrix_telegram_bridge_login_shared_secret_map_auto: {} -matrix_mautrix_telegram_bridge_login_shared_secret_map_custom: {} +# Controls whether to do backfilling at all. +matrix_bridge_mautrix_telegram_backfill_enabled: true -# Default configuration template which covers the generic use case. +# Default mautrix-telegram configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_telegram_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_telegram_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_telegram_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_telegram_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_telegram_configuration_extension_yaml: | +matrix_bridge_mautrix_telegram_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_telegram_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_telegram_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_telegram_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_telegram_configuration_yaml`. -matrix_mautrix_telegram_configuration_extension: "{{ matrix_mautrix_telegram_configuration_extension_yaml | from_yaml if matrix_mautrix_telegram_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_telegram_configuration_extension: "{{ matrix_bridge_mautrix_telegram_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_telegram_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_telegram_configuration_yaml`. -matrix_mautrix_telegram_configuration: "{{ matrix_mautrix_telegram_configuration_yaml | from_yaml | combine(matrix_mautrix_telegram_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_telegram_configuration_yaml`. +matrix_bridge_mautrix_telegram_configuration: "{{ matrix_bridge_mautrix_telegram_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_telegram_configuration_extension, recursive=True) }}" -matrix_mautrix_telegram_registration_yaml: | +matrix_bridge_mautrix_telegram_registration_yaml: | id: telegram - as_token: "{{ matrix_mautrix_telegram_appservice_token }}" - hs_token: "{{ matrix_mautrix_telegram_homeserver_token }}" + url: {{ matrix_bridge_mautrix_telegram_appservice_address }} + as_token: "{{ matrix_bridge_mautrix_telegram_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_telegram_homeserver_token }}" + # See https://github.com/mautrix/signal/issues/43 + sender_localpart: _bot_{{ matrix_bridge_mautrix_telegram_appservice_bot_username }} + rate_limited: false namespaces: users: - exclusive: true - regex: '^@{{ matrix_mautrix_telegram_username_template | replace('{userid}', '.+') }}:{{ matrix_mautrix_telegram_homeserver_domain | regex_escape }}$' + regex: '^@telegram_.+:{{ matrix_bridge_mautrix_telegram_homeserver_domain | regex_escape }}$' - exclusive: true - regex: '^@{{ matrix_mautrix_telegram_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_telegram_homeserver_domain | regex_escape }}$' - aliases: - - exclusive: true - regex: '^#{{ matrix_mautrix_telegram_alias_template | replace('{groupname}', '.+') }}:{{ matrix_mautrix_telegram_homeserver_domain | regex_escape }}$' - # See https://github.com/mautrix/signal/issues/43 - sender_localpart: _bot_{{ matrix_mautrix_telegram_appservice_bot_username }} - url: {{ matrix_mautrix_telegram_appservice_address }} - rate_limited: false + regex: '^@{{ matrix_bridge_mautrix_telegram_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_telegram_homeserver_domain | regex_escape }}$' de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_mautrix_telegram_msc4190_enabled | to_json }} - -matrix_mautrix_telegram_registration: "{{ matrix_mautrix_telegram_registration_yaml | from_yaml }}" + io.element.msc4190: {{ matrix_bridge_mautrix_telegram_msc4190_enabled | to_json }} -# Templates for defining MXID's and displaynames for users and rooms. -matrix_mautrix_telegram_username_template: 'telegram_{userid}' -matrix_mautrix_telegram_alias_template: 'telegram_{groupname}' -matrix_mautrix_telegram_displayname_template: '{displayname} (Telegram)' - -# Enable End-to-bridge encryption -matrix_mautrix_telegram_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_telegram_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_mautrix_telegram_bridge_encryption_key_sharing_allow: "{{ matrix_mautrix_telegram_bridge_encryption_allow }}" +matrix_bridge_mautrix_telegram_registration: "{{ matrix_bridge_mautrix_telegram_registration_yaml | from_yaml }}" -# matrix_mautrix_telegram_restart_necessary controls whether the service +# matrix_bridge_mautrix_telegram_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -267,4 +252,4 @@ matrix_mautrix_telegram_bridge_encryption_key_sharing_allow: "{{ matrix_mautrix_ # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_telegram_restart_necessary: false +matrix_bridge_mautrix_telegram_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/converge.yml new file mode 100644 index 000000000..3d19adfc8 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-telegram Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-telegram Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-telegram is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-telegram systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-telegram.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/molecule.yml new file mode 100644 index 000000000..1b37a380e --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/molecule.yml @@ -0,0 +1,93 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-telegram-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_telegram_container_network: mautrix-telegram-molecule + + # The stub prepare.yml stands up. It is not a real homeserver and the scenario + # does not attempt to bridge a Telegram account. + matrix_bridge_mautrix_telegram_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_telegram_homeserver_domain: molecule.local + + # Postgres is what group_vars/matrix_servers selects in the normal deployment. + # Name and user differ from the role defaults, so a migrated schema proves the + # bridge used the connection string the role composed from these values. + matrix_bridge_mautrix_telegram_database_engine: postgres + matrix_bridge_mautrix_telegram_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_telegram_database_name: molecule_telegram + matrix_bridge_mautrix_telegram_database_username: molecule_telegram + matrix_bridge_mautrix_telegram_database_password: molecule_pg_password_a492c8 + + # Plausibly shaped placeholders only. Starting the bridge does not contact Telegram; + # that happens after a user explicitly starts a login through the provisioning API. + matrix_bridge_mautrix_telegram_api_id: 12345678 + matrix_bridge_mautrix_telegram_api_hash: "0123456789abcdef0123456789abcdef" + + # These only have to reach the rendered configuration and registration. + matrix_bridge_mautrix_telegram_appservice_token: molecule_telegram_as_token_2405cd + matrix_bridge_mautrix_telegram_homeserver_token: molecule_telegram_hs_token_bdf713 + + # Each differs from the role and bridge defaults so parsed-config assertions can + # distinguish the role carrying a value through from an upstream default. + matrix_bridge_mautrix_telegram_appservice_bot_username: molecule-telegrambot + matrix_bridge_mautrix_telegram_command_prefix: "!molecule-tg" + matrix_bridge_mautrix_telegram_network_displayname_template: '{% raw %}{{ .Username }} (Molecule){% endraw %}' + matrix_bridge_mautrix_telegram_federate_rooms: false + matrix_bridge_mautrix_telegram_bridge_personal_filtering_spaces: false + matrix_bridge_mautrix_telegram_backfill_enabled: false + matrix_bridge_mautrix_telegram_logging_level: debug + + # Traefik is not deployed. The scenario checks the public address the bridge reads + # and the labels the role renders from these settings. + matrix_bridge_mautrix_telegram_exposure_enabled: true + matrix_bridge_mautrix_telegram_exposure_hostname: bridges.molecule.local + matrix_bridge_mautrix_telegram_exposure_path_prefix: /bridges/telegram + matrix_bridge_mautrix_telegram_scheme: https + + # verify.yml is a separate play, so pin the paths that it must read there. + matrix_bridge_mautrix_telegram_base_path: /matrix/mautrix-telegram + matrix_bridge_mautrix_telegram_config_path: /matrix/mautrix-telegram/config + matrix_bridge_mautrix_telegram_data_path: /matrix/mautrix-telegram/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/prepare.yml new file mode 100644 index 000000000..03881e357 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/prepare.yml @@ -0,0 +1,90 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-telegram Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks resolve the owner/group by name. matrix-base creates them + # in a full playbook run, so the scenario supplies that small piece of context. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The dependencies must attach before converge asks the role to create the same network. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_telegram_container_network }}" + register: mautrix_telegram_molecule_network + changed_when: mautrix_telegram_molecule_network.rc == 0 + failed_when: + - mautrix_telegram_molecule_network.rc != 0 + - "'already exists' not in mautrix_telegram_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_telegram_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_telegram_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_telegram_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_telegram_database_password }}" + + # The bridge calls /whoami before opening its appservice listener. This proves the + # Matrix-side startup only; no Telegram login or real external credential is involved. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_telegram_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_telegram_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_telegram_appservice_bot_username }}:{{ matrix_bridge_mautrix_telegram_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/verify.yml new file mode 100644 index 000000000..cf4848952 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-telegram/molecule/default/verify.yml @@ -0,0 +1,257 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the bridge starts, reads the role-rendered configuration and registration, migrates +# its Postgres schema, and opens its appservice listener. No Telegram login is attempted. +- name: Verify mautrix-telegram + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + # These are deliberately lazy rather than set_fact. The bridge configuration contains Go + # templates; storing the parsed document as a fact would make Ansible template them again. + vars: + mautrix_telegram_config: "{{ mautrix_telegram_config_file.content | b64decode | from_yaml }}" + mautrix_telegram_registration: "{{ mautrix_telegram_registration_file.content | b64decode | from_yaml }}" + mautrix_telegram_labels_rendered: "{{ mautrix_telegram_labels.content | b64decode }}" + gather_facts: false + tasks: + # Load the shipped version instead of pinning it in the scenario, so Renovate bumps are + # checked against the new image automatically. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_telegram_role_defaults + + - name: Wait for the mautrix-telegram service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-telegram.service + register: mautrix_telegram_service + until: mautrix_telegram_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always leaves a crash-looping service active, so both properties matter. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_telegram_service.status.ActiveState == 'active' + - mautrix_telegram_service.status.NRestarts is defined + - mautrix_telegram_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-telegram.service is + {{ mautrix_telegram_service.status.ActiveState | default('unknown') }} + after {{ mautrix_telegram_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-mautrix-telegram.service is active and has not restarted" + + # /live proves the listener opened; /ready additionally proves startup passed the + # homeserver identity check and database initialization. + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_telegram_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-telegram:8080/_matrix/mau/live + register: mautrix_telegram_live + changed_when: false + until: "'HTTP_STATUS=200' in mautrix_telegram_live.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_telegram_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-telegram:8080/_matrix/mau/ready + register: mautrix_telegram_ready + changed_when: false + until: "'HTTP_STATUS=200' in mautrix_telegram_ready.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on its appservice port + ansible.builtin.assert: + that: + - "'HTTP_STATUS=200' in mautrix_telegram_live.stdout" + - "'HTTP_STATUS=200' in mautrix_telegram_ready.stdout" + fail_msg: >- + The appservice health responses were live={{ mautrix_telegram_live.stdout | default('none') }} + and ready={{ mautrix_telegram_ready.stdout | default('none') }} + success_msg: "The bridge is live and ready on its appservice port" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_telegram_config_path }}/config.yaml" + register: mautrix_telegram_config_file + + # All scenario-provided values below differ from the role or component defaults. + - name: Assert the parsed configuration carries the scenario's values + ansible.builtin.assert: + that: + - mautrix_telegram_config.homeserver.address == matrix_bridge_mautrix_telegram_homeserver_address + - mautrix_telegram_config.homeserver.domain == matrix_bridge_mautrix_telegram_homeserver_domain + - mautrix_telegram_config.network.api_id | int == matrix_bridge_mautrix_telegram_api_id | int + - mautrix_telegram_config.network.api_hash == matrix_bridge_mautrix_telegram_api_hash + - mautrix_telegram_config.appservice.bot.username == matrix_bridge_mautrix_telegram_appservice_bot_username + - mautrix_telegram_config.appservice.as_token == matrix_bridge_mautrix_telegram_appservice_token + - mautrix_telegram_config.appservice.hs_token == matrix_bridge_mautrix_telegram_homeserver_token + - mautrix_telegram_config.bridge.command_prefix == matrix_bridge_mautrix_telegram_command_prefix + - not mautrix_telegram_config.bridge.personal_filtering_spaces + - not mautrix_telegram_config.matrix.federate_rooms + - not mautrix_telegram_config.backfill.enabled + - mautrix_telegram_config.logging.min_level == matrix_bridge_mautrix_telegram_logging_level + - "'(Molecule)' in mautrix_telegram_config.network.displayname_template" + - mautrix_telegram_config.bridge.permissions[matrix_bridge_mautrix_telegram_homeserver_domain] == 'user' + fail_msg: "The parsed configuration does not carry the scenario's values" + success_msg: "The parsed configuration carries the scenario's values" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - mautrix_telegram_config.database.type == matrix_bridge_mautrix_telegram_database_engine + - matrix_bridge_mautrix_telegram_database_username in mautrix_telegram_config.database.uri + - matrix_bridge_mautrix_telegram_database_name in mautrix_telegram_config.database.uri + - matrix_bridge_mautrix_telegram_database_hostname in mautrix_telegram_config.database.uri + fail_msg: >- + database.uri is {{ mautrix_telegram_config.database.uri | default('unset') }}, + which was not built from the scenario's connection settings + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Assert the exposure settings produce the bridge's public address + ansible.builtin.assert: + that: + - mautrix_telegram_config.appservice.public_address == 'https://bridges.molecule.local/bridges/telegram' + fail_msg: >- + appservice.public_address is + {{ mautrix_telegram_config.appservice.public_address | default('unset') }} + success_msg: "The exposure settings produce the bridge's public address" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_telegram_config_path }}/registration.yaml" + register: mautrix_telegram_registration_file + + - name: Assert the parsed registration carries the scenario's identity and tokens + ansible.builtin.assert: + that: + - mautrix_telegram_registration.id == 'telegram' + - mautrix_telegram_registration.as_token == matrix_bridge_mautrix_telegram_appservice_token + - mautrix_telegram_registration.hs_token == matrix_bridge_mautrix_telegram_homeserver_token + - mautrix_telegram_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_telegram_appservice_bot_username + - mautrix_telegram_registration.url == 'http://matrix-mautrix-telegram:8080' + fail_msg: "The appservice registration does not carry the scenario's identity and tokens" + success_msg: "The appservice registration carries the scenario's identity and tokens" + + # Check the namespace regexes by matching examples rather than reimplementing their escaping. + - name: Assert the registration namespaces cover the bot and Telegram ghost users + ansible.builtin.assert: + that: + - mautrix_telegram_ghost_regex | length > 0 + - mautrix_telegram_bot_regex | length > 0 + - mautrix_telegram_ghost_mxid is match(mautrix_telegram_ghost_regex) + - mautrix_telegram_non_ghost_mxid is not match(mautrix_telegram_ghost_regex) + - mautrix_telegram_bot_mxid is match(mautrix_telegram_bot_regex) + fail_msg: "The registration namespaces do not cover the bot and Telegram ghost users" + success_msg: "The registration namespaces cover the bot and Telegram ghost users" + vars: + mautrix_telegram_user_regexes: "{{ mautrix_telegram_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_telegram_ghost_regex: "{{ mautrix_telegram_user_regexes | select('search', 'telegram_') | first | default('') }}" + mautrix_telegram_bot_regex: "{{ mautrix_telegram_user_regexes | reject('search', 'telegram_') | first | default('') }}" + mautrix_telegram_ghost_mxid: "@telegram_12345678:{{ matrix_bridge_mautrix_telegram_homeserver_domain }}" + mautrix_telegram_non_ghost_mxid: "@signal_12345678:{{ matrix_bridge_mautrix_telegram_homeserver_domain }}" + mautrix_telegram_bot_mxid: "@{{ matrix_bridge_mautrix_telegram_appservice_bot_username }}:{{ matrix_bridge_mautrix_telegram_homeserver_domain }}" + + # Tables can appear only after hostname resolution, authentication and migrations succeed. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_telegram_database_username }} + - --dbname={{ matrix_bridge_mautrix_telegram_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: mautrix_telegram_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - mautrix_telegram_tables.rc == 0 + - "'version' in mautrix_telegram_table_names" + - mautrix_telegram_table_names | length > 5 + fail_msg: >- + The bridge did not migrate its schema into + {{ matrix_bridge_mautrix_telegram_database_name }} + (found {{ mautrix_telegram_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + mautrix_telegram_table_names: "{{ mautrix_telegram_tables.stdout_lines | select | list }}" + + - name: Read the running container's image and user + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-telegram + - --format + - "{{ '{{' }} .Config.Image {{ '}}' }} {{ '{{' }} .Config.User {{ '}}' }}" + register: mautrix_telegram_container + changed_when: false + + - name: Assert the running container uses the exact pinned image + ansible.builtin.assert: + that: + - mautrix_telegram_container.stdout.split()[0] == 'dock.mau.dev/mautrix/telegram:' + mautrix_telegram_role_defaults.matrix_bridge_mautrix_telegram_version + fail_msg: "The running container does not use the exact image the role pins" + success_msg: "The running container uses the exact image the role pins" + + - name: Assert the running container uses the playbook-supplied identity + ansible.builtin.assert: + that: + - mautrix_telegram_container.stdout.split()[1] == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + fail_msg: "The running container does not use the {{ matrix_user_uid }}:{{ matrix_user_gid }} identity" + success_msg: "The running container uses the playbook-supplied identity" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_telegram_base_path }}/labels" + register: mautrix_telegram_labels + + - name: Assert the labels route the exposure hostname and prefix to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_telegram_labels_rendered" + - "'traefik.http.services.matrix-mautrix-telegram-exposure.loadbalancer.server.port=8080' in mautrix_telegram_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-telegram-exposure.rule=Host(`bridges.molecule.local`) && PathPrefix(`/bridges/telegram`)' in mautrix_telegram_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-telegram-exposure-strip-prefix.stripprefix.prefixes=/bridges/telegram' in mautrix_telegram_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_telegram_container_network in mautrix_telegram_labels_rendered" + fail_msg: "The labels do not route the exposure hostname and prefix to port 8080" + success_msg: "The labels route the exposure hostname and prefix to port 8080" diff --git a/roles/custom/matrix-bridge-mautrix-telegram/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-telegram/tasks/main.yml index fab0c1657..47df69131 100644 --- a/roles/custom/matrix-bridge-mautrix-telegram/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-telegram/tasks/main.yml @@ -12,15 +12,15 @@ - install-all - install-mautrix-telegram block: - - when: matrix_mautrix_telegram_enabled | bool + - when: matrix_bridge_mautrix_telegram_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_telegram_enabled | bool + - when: matrix_bridge_mautrix_telegram_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mautrix-telegram block: - - when: not matrix_mautrix_telegram_enabled | bool + - when: not matrix_bridge_mautrix_telegram_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-telegram/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-telegram/tasks/setup_install.yml index 2b6ac9a4a..c6de5c077 100644 --- a/roles/custom/matrix-bridge-mautrix-telegram/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-telegram/tasks/setup_install.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2018 - 2025 Slavi Pantaleev +# SPDX-FileCopyrightText: 2018 - 2026 Slavi Pantaleev # SPDX-FileCopyrightText: 2018 Hugues Morisset # SPDX-FileCopyrightText: 2019 Aaron Raimist # SPDX-FileCopyrightText: 2019 Dan Arnfield @@ -18,31 +18,66 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_telegram_migration_requires_restart: false + matrix_bridge_mautrix_telegram_migration_requires_restart: false + +# The legacy Python bridge stored its SQLite DB at `{base_path}/mautrix-telegram.db` (the role's +# root). Later, we started relocating it to `{base_path}/data/mautrix-telegram.db`. The sqlite→ +# postgres migration below only knows about the new path, so if the DB is still at the legacy +# location, move it to the new location first — otherwise users who follow the changelog and +# switch to Postgres wouldn't actually get their data imported before the service starts. +- name: Check if a legacy-location SQLite database exists + ansible.builtin.stat: + path: "{{ matrix_bridge_mautrix_telegram_base_path }}/mautrix-telegram.db" + register: matrix_bridge_mautrix_telegram_stat_database_legacy_location -- when: "matrix_mautrix_telegram_database_engine == 'postgres'" +- when: matrix_bridge_mautrix_telegram_stat_database_legacy_location.stat.exists | bool + block: + - name: Ensure matrix-mautrix-telegram.service is stopped before relocating legacy SQLite DB + ansible.builtin.service: + name: matrix-mautrix-telegram + state: stopped + enabled: false + daemon_reload: true + failed_when: false + + - name: Ensure data directory exists for legacy SQLite DB relocation + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_telegram_data_path }}" + state: directory + mode: '0750' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + + - name: (Data relocation) Move mautrix-telegram SQLite DB from legacy location to data directory + ansible.builtin.command: + cmd: "mv {{ matrix_bridge_mautrix_telegram_base_path }}/mautrix-telegram.db {{ matrix_bridge_mautrix_telegram_data_path }}/mautrix-telegram.db" + creates: "{{ matrix_bridge_mautrix_telegram_data_path }}/mautrix-telegram.db" + removes: "{{ matrix_bridge_mautrix_telegram_base_path }}/mautrix-telegram.db" + +- when: "matrix_bridge_mautrix_telegram_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mautrix_telegram_sqlite_database_path_local }}" - register: matrix_mautrix_telegram_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mautrix_telegram_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_telegram_sqlite_database_path_local_stat_result - - when: "matrix_mautrix_telegram_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mautrix_telegram_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mautrix_telegram_sqlite_database_path_local }}" - dst: "{{ matrix_mautrix_telegram_database_connection_string }}" + src: "{{ matrix_bridge_mautrix_telegram_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_telegram_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mautrix_telegram_database_engine' + engine_variable_name: 'matrix_bridge_mautrix_telegram_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-mautrix-telegram.service'] + pgloader_options: ['--with "quote identifiers"'] - ansible.builtin.set_fact: - matrix_mautrix_telegram_migration_requires_restart: true + matrix_bridge_mautrix_telegram_migration_requires_restart: true - name: Ensure Mautrix Telegram paths exist ansible.builtin.file: @@ -52,126 +87,87 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_telegram_base_path }}", when: true} - - {path: "{{ matrix_mautrix_telegram_config_path }}", when: true} - - {path: "{{ matrix_mautrix_telegram_data_path }}", when: true} - - {path: "{{ matrix_mautrix_telegram_container_src_files_path }}", when: "{{ matrix_mautrix_telegram_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_telegram_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_telegram_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_telegram_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_telegram_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_telegram_container_image_self_build }}"} when: item.when | bool - name: Ensure Mautrix Telegram image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_telegram_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_telegram_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_telegram_container_image_force_pull }}" - when: "not matrix_mautrix_telegram_container_image_self_build | bool" - register: matrix_mautrix_telegram_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_telegram_container_image }}" + pull: always + when: "not matrix_bridge_mautrix_telegram_container_image_self_build | bool" + register: matrix_bridge_mautrix_telegram_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_telegram_container_image_pull_result is not failed + until: matrix_bridge_mautrix_telegram_container_image_pull_result is not failed -- name: Ensure lottieconverter is present when self-building - ansible.builtin.git: - repo: "{{ matrix_mautrix_telegram_lottieconverter_container_repo }}" - version: "{{ matrix_mautrix_telegram_lottieconverter_container_repo_version }}" - dest: "{{ matrix_mautrix_telegram_lottieconverter_container_src_files_path }}" - force: "yes" - become: true - become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_telegram_lottieconverter_git_pull_results - when: "matrix_mautrix_telegram_lottieconverter_container_image_self_build | bool and matrix_mautrix_telegram_container_image_self_build | bool" - -- name: Ensure lottieconverter Docker image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_telegram_lottieconverter_container_image }}" - source: build - force_source: "{{ matrix_mautrix_telegram_lottieconverter_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_telegram_lottieconverter_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_telegram_lottieconverter_container_src_files_path }}" - pull: true - when: "matrix_mautrix_telegram_lottieconverter_container_image_self_build | bool and matrix_mautrix_telegram_lottieconverter_git_pull_results.changed and matrix_mautrix_telegram_container_image_self_build | bool" - -- name: Ensure matrix-mautrix-telegram repository is present when self-building +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix Telegram repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_telegram_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_telegram_container_image_self_build | bool" + +- name: Ensure Mautrix Telegram repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_mautrix_telegram_container_repo }}" - version: "{{ matrix_mautrix_telegram_container_repo_version }}" - dest: "{{ matrix_mautrix_telegram_container_src_files_path }}" + repo: "{{ matrix_bridge_mautrix_telegram_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_mautrix_telegram_container_src_files_path }}" + version: "{{ matrix_bridge_mautrix_telegram_container_image_self_build_branch }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_telegram_git_pull_results - when: "matrix_mautrix_telegram_container_image_self_build | bool" - -- name: Ensure matrix-mautrix-telegram Docker image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_telegram_container_image }}" - source: build - force_source: "{{ matrix_mautrix_telegram_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_telegram_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_telegram_container_src_files_path }}" - pull: "{{ not matrix_mautrix_telegram_lottieconverter_container_image_self_build_mask_arch | bool }}" - args: - TARGETARCH: "" - when: "matrix_mautrix_telegram_container_image_self_build | bool and matrix_mautrix_telegram_git_pull_results.changed" - -- name: Check if an old database file already exists - ansible.builtin.stat: - path: "{{ matrix_mautrix_telegram_base_path }}/mautrix-telegram.db" - register: matrix_mautrix_telegram_stat_database - -- name: (Data relocation) Ensure matrix-mautrix-telegram.service is stopped - ansible.builtin.service: - name: matrix-mautrix-telegram - state: stopped - enabled: false - daemon_reload: true - failed_when: false - when: "matrix_mautrix_telegram_stat_database.stat.exists" - -- name: (Data relocation) Move mautrix-telegram database file to ./data directory - ansible.builtin.command: - cmd: "mv {{ matrix_mautrix_telegram_base_path }}/mautrix-telegram.db {{ matrix_mautrix_telegram_data_path }}/mautrix-telegram.db" - creates: "{{ matrix_mautrix_telegram_data_path }}/mautrix-telegram.db" - removes: "{{ matrix_mautrix_telegram_base_path }}/mautrix-telegram.db" - when: "matrix_mautrix_telegram_stat_database.stat.exists" + register: matrix_bridge_mautrix_telegram_git_pull_results + when: "matrix_bridge_mautrix_telegram_container_image_self_build | bool" + +- name: Ensure Mautrix Telegram Docker image is built + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_telegram_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_telegram_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_telegram_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_telegram_container_image_self_build | bool" + register: matrix_bridge_mautrix_telegram_container_image_build_result - name: Ensure mautrix-telegram config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_telegram_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_telegram_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_telegram_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_telegram_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_telegram_config_result + register: matrix_bridge_mautrix_telegram_config_result - name: Ensure mautrix-telegram registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_telegram_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_telegram_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_telegram_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_telegram_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_telegram_registration_result + register: matrix_bridge_mautrix_telegram_registration_result - name: Ensure mautrix-telegram support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_telegram_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_telegram_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_mautrix_telegram_support_files_result + register: matrix_bridge_mautrix_telegram_support_files_result - name: Ensure matrix-mautrix-telegram container network is created + when: matrix_bridge_mautrix_telegram_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_telegram_container_network }}" + name: "{{ matrix_bridge_mautrix_telegram_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -180,18 +176,19 @@ src: "{{ role_path }}/templates/systemd/matrix-mautrix-telegram.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-telegram.service" mode: '0644' - register: matrix_mautrix_telegram_systemd_service_result + register: matrix_bridge_mautrix_telegram_systemd_service_result - name: Determine whether matrix-mautrix-telegram needs a restart ansible.builtin.set_fact: - matrix_mautrix_telegram_restart_necessary: >- + matrix_bridge_mautrix_telegram_restart_necessary: >- {{ - matrix_mautrix_telegram_migration_requires_restart | default(false) - or matrix_mautrix_telegram_config_result.changed | default(false) - or matrix_mautrix_telegram_registration_result.changed | default(false) - or matrix_mautrix_telegram_support_files_result.changed | default(false) - or matrix_mautrix_telegram_systemd_service_result.changed | default(false) - or matrix_mautrix_telegram_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_telegram_migration_requires_restart | default(false) + or matrix_bridge_mautrix_telegram_config_result.changed | default(false) + or matrix_bridge_mautrix_telegram_registration_result.changed | default(false) + or matrix_bridge_mautrix_telegram_support_files_result.changed | default(false) + or matrix_bridge_mautrix_telegram_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_telegram_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_telegram_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mautrix-telegram.service restarted, if necessary @@ -199,4 +196,4 @@ name: "matrix-mautrix-telegram.service" state: restarted daemon_reload: true - when: "matrix_mautrix_telegram_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_telegram_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-telegram/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-telegram/tasks/setup_uninstall.yml index cbde3ff57..b7528283d 100644 --- a/roles/custom/matrix-bridge-mautrix-telegram/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-telegram/tasks/setup_uninstall.yml @@ -9,9 +9,9 @@ - name: Check existence of matrix-mautrix-telegram service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-telegram.service" - register: matrix_mautrix_telegram_service_stat + register: matrix_bridge_mautrix_telegram_service_stat -- when: matrix_mautrix_telegram_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_telegram_service_stat.stat.exists | bool block: - name: Ensure matrix-mautrix-telegram is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mautrix-telegram/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-telegram/tasks/validate_config.yml index fbad995fd..ca305368b 100644 --- a/roles/custom/matrix-bridge-mautrix-telegram/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-telegram/tasks/validate_config.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2019 - 2024 Slavi Pantaleev +# SPDX-FileCopyrightText: 2019 - 2026 Slavi Pantaleev # SPDX-FileCopyrightText: 2022 MDAD project contributors # SPDX-FileCopyrightText: 2025 Suguru Hirahara # @@ -13,34 +13,85 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_telegram_container_exposed_port_number', 'new': ''} - - {'old': 'matrix_mautrix_telegram_container_self_build', 'new': 'matrix_mautrix_telegram_container_image_self_build'} - - {'old': 'matrix_mautrix_telegram_lottieconverter_container_self_build', 'new': 'matrix_mautrix_telegram_container_image_self_build'} - - {'old': 'matrix_mautrix_telegram_lottieconverter_container_self_build_mask_arch', 'new': 'matrix_mautrix_telegram_lottieconverter_container_image_self_build_mask_arch'} - - {'old': 'matrix_mautrix_telegram_login_shared_secret', 'new': ''} - - {'old': 'matrix_mautrix_telegram_lottieconverter_docker_image_name_prefix', 'new': 'matrix_mautrix_telegram_lottieconverter_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_telegram_docker_image_name_prefix', 'new': 'matrix_mautrix_telegram_container_image_registry_prefix'} - - {'old': 'matrix_telegram_lottieconverter_container_image_self_build', 'new': 'matrix_mautrix_telegram_lottieconverter_container_image_self_build'} - - {'old': 'matrix_telegram_lottieconverter_container_image_self_build_mask_arch', 'new': 'matrix_mautrix_telegram_lottieconverter_container_image_self_build_mask_arch'} - - {'old': 'matrix_telegram_lottieconverter_docker_repo', 'new': 'matrix_mautrix_telegram_lottieconverter_container_repo'} - - {'old': 'matrix_telegram_lottieconverter_docker_repo_version', 'new': 'matrix_mautrix_telegram_lottieconverter_container_repo_version'} - - {'old': 'matrix_telegram_lottieconverter_docker_src_files_path', 'new': 'matrix_mautrix_telegram_lottieconverter_container_src_files_path'} - - {'old': 'matrix_telegram_lottieconverter_docker_image', 'new': 'matrix_mautrix_telegram_lottieconverter_container_image'} - - {'old': 'matrix_mautrix_telegram_docker_repo', 'new': 'matrix_mautrix_telegram_container_repo'} - - {'old': 'matrix_mautrix_telegram_docker_repo_version', 'new': 'matrix_mautrix_telegram_container_repo_version'} - - {'old': 'matrix_mautrix_telegram_docker_src_files_path', 'new': 'matrix_mautrix_telegram_container_src_files_path'} - - {'old': 'matrix_mautrix_telegram_docker_image', 'new': 'matrix_mautrix_telegram_container_image'} - - {'old': 'matrix_mautrix_telegram_docker_image_force_pull', 'new': 'matrix_mautrix_telegram_container_image_force_pull'} - - {'old': 'matrix_mautrix_telegram_docker_image_registry_prefix', 'new': 'matrix_mautrix_telegram_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_telegram_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_telegram_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_telegram_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_telegram_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_telegram_lottieconverter_docker_image', 'new': 'matrix_mautrix_telegram_lottieconverter_container_image'} - - {'old': 'matrix_mautrix_telegram_lottieconverter_docker_image_registry_prefix', 'new': 'matrix_mautrix_telegram_lottieconverter_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_telegram_lottieconverter_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_telegram_lottieconverter_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_telegram_lottieconverter_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_telegram_lottieconverter_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_telegram_lottieconverter_docker_repo', 'new': 'matrix_mautrix_telegram_lottieconverter_container_repo'} - - {'old': 'matrix_mautrix_telegram_lottieconverter_docker_repo_version', 'new': 'matrix_mautrix_telegram_lottieconverter_container_repo_version'} - - {'old': 'matrix_mautrix_telegram_lottieconverter_docker_src_files_path', 'new': 'matrix_mautrix_telegram_lottieconverter_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_telegram_container_exposed_port_number', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_container_self_build', 'new': 'matrix_bridge_mautrix_telegram_container_image_self_build'} + - {'old': 'matrix_bridge_mautrix_telegram_login_shared_secret', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_docker_image_name_prefix', 'new': 'matrix_bridge_mautrix_telegram_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_telegram_docker_repo', 'new': 'matrix_bridge_mautrix_telegram_container_image_self_build_repo'} + - {'old': 'matrix_bridge_mautrix_telegram_docker_repo_version', 'new': 'matrix_bridge_mautrix_telegram_container_image_self_build_branch'} + - {'old': 'matrix_bridge_mautrix_telegram_docker_src_files_path', 'new': 'matrix_bridge_mautrix_telegram_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_telegram_docker_image', 'new': 'matrix_bridge_mautrix_telegram_container_image'} + - {'old': 'matrix_bridge_mautrix_telegram_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_telegram_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_telegram_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_mautrix_telegram_docker_image_registry_prefix', 'new': 'matrix_bridge_mautrix_telegram_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_telegram_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mautrix_telegram_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mautrix_telegram_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mautrix_telegram_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mautrix_telegram_container_repo', 'new': 'matrix_bridge_mautrix_telegram_container_image_self_build_repo'} + - {'old': 'matrix_bridge_mautrix_telegram_container_repo_version', 'new': 'matrix_bridge_mautrix_telegram_container_image_self_build_branch'} + # Variables removed in the bridgev2 (Go) rewrite — mautrix-telegram no longer has a Python runtime, + # a separate lottieconverter container or a web-based login endpoint. + # (matrix_bridge_mautrix_telegram_scheme was part of this group too, but has since been reintroduced to configure the bridge's HTTP API exposure address, so it's intentionally not listed here.) + - {'old': 'matrix_bridge_mautrix_telegram_hostname', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_path_prefix', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_public_endpoint', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_appservice_public_enabled', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_appservice_public_external', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_public_endpoint_enabled', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_public_endpoint_hostname', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_public_endpoint_path_prefix', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_public_endpoint_traefik_rule', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_public_endpoint_traefik_priority', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_public_endpoint_traefik_entrypoints', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_public_endpoint_traefik_tls', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_public_endpoint_traefik_tls_certResolver', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_container_http_host_bind_port', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_filter_mode', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_bot_token', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_bridge_login_shared_secret_map', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_bridge_login_shared_secret_map_auto', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_bridge_login_shared_secret_map_custom', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_username_template', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_alias_template', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_displayname_template', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_appservice_database', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_container_image_self_build', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_container_image_self_build_mask_arch', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_container_repo', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_container_repo_version', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_container_src_files_path', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_container_image', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_container_image_registry_prefix', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_container_image_registry_prefix_upstream', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_container_image_registry_prefix_upstream_default', 'new': ''} + # Historical lottieconverter aliases from before the _docker_ → _container_ rename: + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_container_self_build', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_docker_image_name_prefix', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_docker_image', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_docker_image_registry_prefix', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_docker_image_registry_prefix_upstream', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_docker_image_registry_prefix_upstream_default', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_docker_repo', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_docker_repo_version', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_lottieconverter_docker_src_files_path', 'new': ''} + # Even older aliases (no `_mautrix` infix): + - {'old': 'matrix_telegram_lottieconverter_container_image_self_build', 'new': ''} + - {'old': 'matrix_telegram_lottieconverter_container_image_self_build_mask_arch', 'new': ''} + - {'old': 'matrix_telegram_lottieconverter_docker_repo', 'new': ''} + - {'old': 'matrix_telegram_lottieconverter_docker_repo_version', 'new': ''} + - {'old': 'matrix_telegram_lottieconverter_docker_src_files_path', 'new': ''} + - {'old': 'matrix_telegram_lottieconverter_docker_image', 'new': ''} + - {'old': 'matrix_bridge_mautrix_telegram_metrics_enabled', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_metrics_proxying_enabled', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_metrics_proxying_hostname', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_metrics_proxying_path_prefix', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_metrics_enabled', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_metrics_traefik_rule', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_metrics_traefik_priority', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_metrics_traefik_entrypoints', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_metrics_traefik_tls', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_metrics_traefik_tls_certResolver', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (mautrix-telegram does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_telegram_container_labels_metrics_middleware_basic_auth_users', 'new': ' (mautrix-telegram does not support metrics)'} - name: Fail if required mautrix-telegram settings not defined ansible.builtin.fail: @@ -48,15 +99,54 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_telegram_hostname', when: true} - - {'name': 'matrix_mautrix_telegram_path_prefix', when: true} - - {'name': 'matrix_mautrix_telegram_api_id', when: true} - - {'name': 'matrix_mautrix_telegram_api_hash', when: true} - - {'name': 'matrix_mautrix_telegram_public_endpoint', when: true} - - {'name': 'matrix_mautrix_telegram_appservice_token', when: true} - - {'name': 'matrix_mautrix_telegram_homeserver_address', when: true} - - {'name': 'matrix_mautrix_telegram_homeserver_token', when: true} - - {'name': 'matrix_mautrix_telegram_container_network', when: true} - - {'name': 'matrix_mautrix_telegram_database_hostname', when: "{{ matrix_mautrix_telegram_database_engine == 'postgres' }}"} - - {'name': 'matrix_mautrix_telegram_metrics_proxying_hostname', when: "{{ matrix_mautrix_telegram_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_telegram_metrics_proxying_path_prefix', when: "{{ matrix_mautrix_telegram_metrics_proxying_enabled }}"} + - {'name': 'matrix_bridge_mautrix_telegram_api_id', when: true} + - {'name': 'matrix_bridge_mautrix_telegram_api_hash', when: true} + - {'name': 'matrix_bridge_mautrix_telegram_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_telegram_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_telegram_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_telegram_container_network', when: true} + - {'name': 'matrix_bridge_mautrix_telegram_database_hostname', when: "{{ matrix_bridge_mautrix_telegram_database_engine == 'postgres' }}"} + +# Temporary workaround for an upstream SQLite legacy-migration bug in mautrix-telegram v0.2604.0. +# See the separate task file for details; the whole file (and this include) can be deleted once +# upstream ships a release that fixes the bug. +- name: Guard against the upstream mautrix-telegram v0.2604.0 SQLite legacy-migration bug + ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config_sqlite_legacy_migration_bug.yml" + when: + - "matrix_bridge_mautrix_telegram_database_engine == 'sqlite'" + - "not (matrix_bridge_mautrix_telegram_bridgev2_sqlite_upgrade_confirmed | default(false) | bool)" + +# Bridgev2 permission values are: block, relay, commands, user, admin. +# The old Python bridge had different levels (relaybot, user, puppeting, full, admin). +# `user` and `admin` still exist in both but with different semantics (the new `user` is +# equivalent to the old `full`/`puppeting`). `relaybot`, `puppeting` and `full` don't exist +# in bridgev2 and will cause the bridge to reject its config at startup. +# +# We check the fully-merged configuration (not just `matrix_bridge_mautrix_telegram_bridge_permissions`) +# because users commonly override permissions via `matrix_bridge_mautrix_telegram_configuration_extension_yaml`, +# and those overrides would otherwise slip through validation. +- name: Fail if bridge permissions still reference legacy Python-bridge permission levels + ansible.builtin.fail: + msg: |- + Your final mautrix-telegram configuration contains a `bridge.permissions` entry with + value `{{ item.value }}` (for `{{ item.key }}`). This was a permission level in the legacy + (Python) mautrix-telegram bridge but is not valid in the bridgev2 rewrite shipped in v0.2604.0 + — the bridge would reject this at startup. + + Valid values are: `relay`, `commands`, `user`, `admin` (plus `block`). + + Rough mapping from the old levels: + + relaybot -> relay + user -> user (semantics changed: this now grants full puppeting, like the old `full`) + puppeting -> user + full -> user + admin -> admin + + See https://docs.mau.fi/bridges/general/permissions.html and the bridge's example config + for details. Update either `matrix_bridge_mautrix_telegram_bridge_permissions` or the `bridge.permissions` + section inside `matrix_bridge_mautrix_telegram_configuration_extension_yaml` — whichever you use. + when: "item.value in ['relaybot', 'puppeting', 'full']" + loop: "{{ (matrix_bridge_mautrix_telegram_configuration.bridge.permissions | default({})) | dict2items }}" + loop_control: + label: "{{ item.key }}" diff --git a/roles/custom/matrix-bridge-mautrix-telegram/tasks/validate_config_sqlite_legacy_migration_bug.yml b/roles/custom/matrix-bridge-mautrix-telegram/tasks/validate_config_sqlite_legacy_migration_bug.yml new file mode 100644 index 000000000..408cdcf68 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-telegram/tasks/validate_config_sqlite_legacy_migration_bug.yml @@ -0,0 +1,99 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# ########################################################################### +# TEMPORARY — delete this file (and its include in `validate_config.yml`) +# once upstream mautrix-telegram ships a release that fixes the SQLite +# legacy-migration bug introduced in v0.2604.0. +# +# Upstream warning: +# "Migration of SQLite databases has a known bug. If you're upgrading a +# legacy bridge that uses SQLite, use the main branch or wait for the +# next release" +# — https://github.com/mautrix/telegram/releases/tag/v0.2604.0 +# +# We specifically want to block upgrades of the *legacy* Python-bridge +# SQLite databases; fresh bridgev2 SQLite databases (or already-migrated +# ones) must still be allowed. +# +# The cheapest reliable signature of a legacy Python-bridge DB is the +# presence of the `telethon_sessions` table (the Python bridge's +# Telethon-session store, which upstream's legacymigrate.sql renames to +# `telethon_sessions_old` as part of the bridgev2 migration). +# +# Users can bypass this via `matrix_bridge_mautrix_telegram_bridgev2_sqlite_upgrade_confirmed: true`. +# ########################################################################### + +- name: Check for an existing mautrix-telegram SQLite database (legacy location) + ansible.builtin.stat: + path: "{{ matrix_bridge_mautrix_telegram_base_path }}/mautrix-telegram.db" + register: matrix_bridge_mautrix_telegram_sqlite_legacy_path_stat + +- name: Check for an existing mautrix-telegram SQLite database (data path) + ansible.builtin.stat: + path: "{{ matrix_bridge_mautrix_telegram_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_telegram_sqlite_data_path_stat + +- name: Inspect SQLite database for the legacy Python-bridge schema signature + ansible.builtin.command: + argv: + - python3 + - -c + - | + import sqlite3, sys + try: + conn = sqlite3.connect("file:" + sys.argv[1] + "?mode=ro", uri=True) + cur = conn.execute( + "SELECT name FROM sqlite_master " + "WHERE type='table' AND name='telethon_sessions'" + ) + sys.exit(1 if cur.fetchone() else 0) + except Exception: + sys.exit(0) + - "{{ matrix_bridge_mautrix_telegram_sqlite_legacy_path_stat.stat.path if matrix_bridge_mautrix_telegram_sqlite_legacy_path_stat.stat.exists else matrix_bridge_mautrix_telegram_sqlite_data_path_stat.stat.path }}" + register: matrix_bridge_mautrix_telegram_sqlite_legacy_check + changed_when: false + failed_when: false + when: >- + matrix_bridge_mautrix_telegram_sqlite_legacy_path_stat.stat.exists + or matrix_bridge_mautrix_telegram_sqlite_data_path_stat.stat.exists + +- name: Fail if upgrading a legacy SQLite install (upstream has a known migration bug) + ansible.builtin.fail: + msg: |- + A legacy Python mautrix-telegram SQLite database was detected at + `{{ matrix_bridge_mautrix_telegram_sqlite_legacy_path_stat.stat.path if matrix_bridge_mautrix_telegram_sqlite_legacy_path_stat.stat.exists else matrix_bridge_mautrix_telegram_sqlite_data_path_stat.stat.path }}` + (it contains the `telethon_sessions` table from the Python bridge). + + Upstream mautrix-telegram v0.2604.0 has a **known bug** in the legacy SQLite + database migration (see the warning on the release page: + https://github.com/mautrix/telegram/releases/tag/v0.2604.0). + Running this upgrade against a legacy SQLite database is very likely to corrupt your data. + + Recommended options: + + 1. Switch to Postgres before upgrading. If you're using the playbook-managed Postgres + service (`postgres_enabled: true`), just set: + + matrix_bridge_mautrix_telegram_database_engine: postgres + + and re-run the playbook. The playbook will migrate your SQLite data into Postgres + first (via pgloader), and upstream's bridgev2 migration path is known to work on + Postgres. + + 2. Wait for the next upstream mautrix-telegram release, which is expected to fix the + SQLite migration bug. + + If you're sure you want to proceed anyway (for example because you have a separate + backup), you can bypass this check by setting: + + matrix_bridge_mautrix_telegram_bridgev2_sqlite_upgrade_confirmed: true + + in your vars.yml. Only use the override if you know what you're doing. + when: >- + (matrix_bridge_mautrix_telegram_sqlite_legacy_path_stat.stat.exists + or matrix_bridge_mautrix_telegram_sqlite_data_path_stat.stat.exists) + and (matrix_bridge_mautrix_telegram_sqlite_legacy_check.rc | default(0)) == 1 diff --git a/roles/custom/matrix-bridge-mautrix-telegram/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-telegram/templates/config.yaml.j2 index f0b52729d..fc2aba7e9 100644 --- a/roles/custom/matrix-bridge-mautrix-telegram/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-telegram/templates/config.yaml.j2 @@ -1,246 +1,29 @@ #jinja2: lstrip_blocks: True -# Homeserver details -homeserver: - # The address that this appservice can use to connect to the homeserver. - address: {{ matrix_mautrix_telegram_homeserver_address }} - # The domain of the homeserver (for MXIDs, etc). - domain: {{ matrix_mautrix_telegram_homeserver_domain }} - # Whether or not to verify the SSL certificate of the homeserver. - # Only applies if address starts with https:// - verify_ssl: true - # What software is the homeserver running? - # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. - software: standard - # Number of retries for all HTTP requests if the homeserver isn't reachable. - http_retry_count: 4 - # The URL to push real-time bridge status to. - # If set, the bridge will make POST requests to this URL whenever a user's Telegram connection state changes. - # The bridge will use the appservice as_token to authorize requests. - status_endpoint: null - # Endpoint for reporting per-message status. - message_send_checkpoint_endpoint: null - # Whether asynchronous uploads via MSC2246 should be enabled for media. - # Requires a media repo that supports MSC2246. - async_media: {{ matrix_mautrix_telegram_homeserver_async_media | to_json }} - -# Application service host/registration related details -# Changing these values requires regeneration of the registration. -appservice: - # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_mautrix_telegram_appservice_address|to_json }} - - # The hostname and port where this appservice should listen. - hostname: 0.0.0.0 - port: 8080 - # The maximum body size of appservice API requests (from the homeserver) in mebibytes - # Usually 1 is enough, but on high-traffic bridges you might need to increase this to avoid 413s - max_body_size: 1 - - # The full URI to the database. SQLite and Postgres are supported. - # Format examples: - # SQLite: sqlite:filename.db - # Postgres: postgres://username:password@hostname/dbname - database: {{ matrix_mautrix_telegram_appservice_database|to_json }} - # Additional arguments for asyncpg.create_pool() or sqlite3.connect() - # https://magicstack.github.io/asyncpg/current/api/index.html#asyncpg.pool.create_pool - # https://docs.python.org/3/library/sqlite3.html#sqlite3.connect - # For sqlite, min_size is used as the connection thread pool size and max_size is ignored. - # Additionally, SQLite supports init_commands as an array of SQL queries to run on connect (e.g. to set PRAGMAs). - database_opts: - min_size: 1 - max_size: 10 - - # Public part of web server for out-of-Matrix interaction with the bridge. - # Used for things like login if the user wants to make sure the 2FA password isn't stored in - # the HS database. - public: - # Whether or not the public-facing endpoints should be enabled. - enabled: {{ matrix_mautrix_telegram_appservice_public_enabled|to_json }} - # The prefix to use in the public-facing endpoints. - prefix: {{ matrix_mautrix_telegram_public_endpoint|to_json }} - # The base URL where the public-facing endpoints are available. The prefix is not added - # implicitly. - external: {{ matrix_mautrix_telegram_appservice_public_external|to_json }} - - # Provisioning API part of the web server for automated portal creation and fetching information. - # Used by things like Dimension (https://dimension.t2bot.io/). - provisioning: - # Whether or not the provisioning API should be enabled. - enabled: false - # The prefix to use in the provisioning API endpoints. - prefix: /_matrix/provision/v1 - # The shared secret to authorize users of the API. - # Set to "generate" to generate and save a new token. - shared_secret: {{ matrix_mautrix_telegram_provisioning_shared_secret | to_json }} - - # The unique ID of this appservice. - id: telegram - # Username of the appservice bot. - bot_username: {{ matrix_mautrix_telegram_appservice_bot_username|to_json }} - # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty - # to leave display name/avatar as-is. - bot_displayname: Telegram bridge bot - bot_avatar: mxc://maunium.net/tJCRmUyJDsgRNgqhOgoiHWbX - - # Whether or not to receive ephemeral events via appservice transactions. - # Requires MSC2409 support (i.e. Synapse 1.22+). - # You should disable bridge -> sync_with_custom_puppets when this is enabled. - ephemeral_events: true - - # Authentication tokens for AS <-> HS communication. - as_token: {{ matrix_mautrix_telegram_appservice_token|to_json }} - hs_token: {{ matrix_mautrix_telegram_homeserver_token|to_json }} - -# Prometheus telemetry config. Requires prometheus-client to be installed. -metrics: - enabled: {{ matrix_mautrix_telegram_metrics_enabled | to_json }} - listen_port: 8000 +# Network-specific config options +network: + # Get your own API keys at https://my.telegram.org/apps + api_id: {{ matrix_bridge_mautrix_telegram_api_id | int | to_json }} + api_hash: {{ matrix_bridge_mautrix_telegram_api_hash | to_json }} -# Manhole config. -manhole: - # Whether or not opening the manhole is allowed. - enabled: false - # The path for the unix socket. - path: /var/tmp/mautrix-telegram.manhole - # The list of UIDs who can be added to the whitelist. - # If empty, any UIDs can be specified in the open-manhole command. - whitelist: - - 0 - -# Bridge config -bridge: - # Localpart template of MXIDs for Telegram users. - # {userid} is replaced with the user ID of the Telegram user. - # Default: telegram_{userid} - username_template: {{ matrix_mautrix_telegram_username_template|to_json }} - # Localpart template of room aliases for Telegram portal rooms. - # {groupname} is replaced with the name part of the public channel/group invite link ( https://t.me/{} ) - # Default: telegram_{groupname} - alias_template: {{ matrix_mautrix_telegram_alias_template|to_json }} - # Displayname template for Telegram users. - # {displayname} is replaced with the display name of the Telegram user. - # Default: {displayname} (Telegram) - displayname_template: {{ matrix_mautrix_telegram_displayname_template|to_json }} + # Device info shown in the Telegram device list. + device_info: + device_model: mautrix-telegram + system_version: + app_version: auto + lang_code: en + system_lang_code: en - # Set the preferred order of user IDs which to use in the Matrix puppet display name. - # In the (hopefully unlikely) scenario that none of the given keys are found, the numeric user - # ID is used. - # - # If the bridge is working properly, a phone number or an username should always be known, but - # the other one can very well be empty. - # - # Valid keys: - # "full name" (First and/or last name) - # "full name reversed" (Last and/or first name) - # "first name" - # "last name" - # "username" - # "phone number" - displayname_preference: - - full name - - username - - phone number - # Maximum length of displayname - displayname_max_length: 100 - # Remove avatars from Telegram ghost users when removed on Telegram. This is disabled by default - # as there's no way to determine whether an avatar is removed or just hidden from some users. If - # you're on a single-user instance, this should be safe to enable. - allow_avatar_remove: false - # Should contact names and profile pictures be allowed? - # This is only safe to enable on single-user instances. - allow_contact_info: false - - # Maximum number of members to sync per portal when starting up. Other members will be - # synced when they send messages. The maximum is 10000, after which the Telegram server - # will not send any more members. - # -1 means no limit (which means it's limited to 10000 by the server) - max_initial_member_sync: 100 - # Maximum number of participants in chats to bridge. Only applies when the portal is being created. - # If there are more members when trying to create a room, the room creation will be cancelled. - # -1 means no limit (which means all chats can be bridged) - max_member_count: -1 - # Whether or not to sync the member list in channels. - # If no channel admins have logged into the bridge, the bridge won't be able to sync the member - # list regardless of this setting. - sync_channel_members: false - # Whether or not to skip deleted members when syncing members. - skip_deleted_members: true - # Whether or not to automatically synchronize contacts and chats of Matrix users logged into - # their Telegram account at startup. - startup_sync: false - # Number of most recently active dialogs to check when syncing chats. - # Set to 0 to remove limit. - sync_update_limit: 0 - # Number of most recently active dialogs to create portals for when syncing chats. - # Set to 0 to remove limit. - sync_create_limit: 15 - # Should all chats be scheduled to be created later? - # This is best used in combination with MSC2716 infinite backfill. - sync_deferred_create_all: false - # Whether or not to sync and create portals for direct chats at startup. - sync_direct_chats: false - # The maximum number of simultaneous Telegram deletions to handle. - # A large number of simultaneous redactions could put strain on your homeserver. - max_telegram_delete: 10 - # Whether or not to automatically sync the Matrix room state (mostly unpuppeted displaynames) - # at startup and when creating a bridge. - sync_matrix_state: true - # Allow logging in within Matrix. If false, users can only log in using login-qr or the - # out-of-Matrix login website (see appservice.public config section) - allow_matrix_login: true - # Whether or not to make portals of publicly joinable channels/supergroups publicly joinable on Matrix. - public_portals: false - # Whether or not to use /sync to get presence, read receipts and typing notifications - # when double puppeting is enabled - sync_with_custom_puppets: false - # Whether or not to update the m.direct account data event when double puppeting is enabled. - # Note that updating the m.direct event is not atomic (except with mautrix-asmux) - # and is therefore prone to race conditions. - sync_direct_chat_list: false - # Servers to always allow double puppeting from - double_puppet_server_map: - "{{ matrix_mautrix_telegram_homeserver_domain }}": {{ matrix_mautrix_telegram_homeserver_address }} - # Allow using double puppeting from any server with a valid client .well-known file. - double_puppet_allow_discovery: false - # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth - # - # If set, custom puppets will be enabled automatically for local users - # instead of users having to find an access token and run `login-matrix` - # manually. - # If using this for other servers than the bridge's server, - # you must also set the URL in the double_puppet_server_map. - login_shared_secret_map: {{ matrix_mautrix_telegram_bridge_login_shared_secret_map|to_json }} - # Set to false to disable link previews in messages sent to Telegram. - telegram_link_preview: true - # Whether or not the !tg join command should do a HTTP request - # to resolve redirects in invite links. - invite_link_resolve: false - # Send captions in the same message as images. This will send data compatible with both MSC2530 and MSC3552. - # This is currently not supported in most clients. - caption_in_message: false - # Maximum size of image in megabytes before sending to Telegram as a document. - image_as_file_size: 10 - # Maximum number of pixels in an image before sending to Telegram as a document. Defaults to 4096x4096 = 16777216. - image_as_file_pixels: 16777216 - # Enable experimental parallel file transfer, which makes uploads/downloads much faster by - # streaming from/to Matrix and using many connections for Telegram. - # Note that generating HQ thumbnails for videos is not possible with streamed transfers. - # This option uses internal Telethon implementation details and may break with minor updates. - parallel_file_transfer: false - # Whether or not created rooms should have federation enabled. - # If false, created portal rooms will never be federated. - federate_rooms: {{ matrix_mautrix_telegram_federate_rooms|to_json }} - # Should the bridge send all unicode reactions as custom emoji reactions to Telegram? - # By default, the bridge only uses custom emojis for unicode emojis that aren't allowed in reactions. - always_custom_emoji_reaction: false # Settings for converting animated stickers. animated_sticker: # Format to which animated stickers should be converted. - # disable - No conversion, send as-is (gzipped lottie) - # png - converts to non-animated png (fastest), - # gif - converts to animated gif - # webm - converts to webm video, requires ffmpeg executable with vp9 codec and webm container support - # webp - converts to animated webp, requires ffmpeg executable with webp codec/container support + # + # disable - no conversion, send as-is (gzipped lottie) + # png - converts to non-animated png (fastest), + # gif - converts to animated gif + # webm - converts to webm video, requires ffmpeg executable with vp9 codec + # and webm container support + # webp - converts to animated webp, requires ffmpeg executable with webp + # codec/container support target: gif # Should video stickers be converted to the specified format as well? convert_from_webm: false @@ -249,414 +32,498 @@ bridge: width: 256 height: 256 fps: 25 # only for webm, webp and gif (2, 5, 10, 20 or 25 recommended) - # Settings for converting animated emoji. - # Same as animated_sticker, but webm is not supported as the target - # (because inline images can only contain images, not videos). - animated_emoji: - target: webp - args: - width: 64 - height: 64 - fps: 25 - # End-to-bridge encryption support options. - # - # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. - encryption: - # Allow encryption, work in group chat rooms with e2ee enabled - allow: {{ matrix_mautrix_telegram_bridge_encryption_allow|to_json }} - # Default to encryption, force-enable encryption in all portals the bridge creates - # This will cause the bridge bot to be in private chats for the encryption to work properly. - default: {{ matrix_mautrix_telegram_bridge_encryption_default|to_json }} - # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. - appservice: false - # Whether to use MSC4190 instead of appservice login to create the bridge bot device. - # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. - # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). - # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_mautrix_telegram_msc4190_enabled | to_json }} - # Require encryption, drop any unencrypted messages. - require: false - # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. - # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_mautrix_telegram_bridge_encryption_key_sharing_allow|to_json }} - # Options for deleting megolm sessions from the bridge. - delete_keys: - # Beeper-specific: delete outbound sessions when hungryserv confirms - # that the user has uploaded the key to key backup. - delete_outbound_on_ack: false - # Don't store outbound sessions in the inbound table. - dont_store_outbound: false - # Ratchet megolm sessions forward after decrypting messages. - ratchet_on_decrypt: false - # Delete fully used keys (index >= max_messages) after decrypting messages. - delete_fully_used_on_decrypt: false - # Delete previous megolm sessions from same device when receiving a new one. - delete_prev_on_new_session: false - # Delete megolm sessions received from a device when the device is deleted. - delete_on_device_delete: false - # Periodically delete megolm sessions when 2x max_age has passed since receiving the session. - periodically_delete_expired: false - # Delete inbound megolm sessions that don't have the received_at field used for - # automatic ratcheting and expired session deletion. This is meant as a migration - # to delete old keys prior to the bridge update. - delete_outdated_inbound: false - # What level of device verification should be required from users? + + # Settings for syncing the member list for portals. + member_list: + # Maximum number of members to sync per portal when starting up. Other + # members will be synced when they send messages. The maximum is 10000, + # after which the Telegram server will not send any more members. # - # Valid levels: - # unverified - Send keys to all device in the room. - # cross-signed-untrusted - Require valid cross-signing, but trust all cross-signing keys. - # cross-signed-tofu - Require valid cross-signing, trust cross-signing keys on first use (and reject changes). - # cross-signed-verified - Require valid cross-signing, plus a valid user signature from the bridge bot. - # Note that creating user signatures from the bridge bot is not currently possible. - # verified - Require manual per-device verification - # (currently only possible by modifying the `trust` column in the `crypto_device` database table). - verification_levels: - # Minimum level for which the bridge should send keys to when bridging messages from Telegram to Matrix. - receive: unverified - # Minimum level that the bridge should accept for incoming Matrix messages. - send: unverified - # Minimum level that the bridge should require for accepting key requests. - share: cross-signed-tofu - # Options for Megolm room key rotation. These options allow you to - # configure the m.room.encryption event content. See: - # https://spec.matrix.org/v1.3/client-server-api/#mroomencryption for - # more information about that event. - rotation: - # Enable custom Megolm room key rotation settings. Note that these - # settings will only apply to rooms created after this option is - # set. - enable_custom: false - # The maximum number of milliseconds a session should be used - # before changing it. The Matrix spec recommends 604800000 (a week) - # as the default. - milliseconds: 604800000 - # The maximum number of messages that should be sent with a given a - # session before changing it. The Matrix spec recommends 100 as the - # default. - messages: 100 - - # Disable rotating keys when a user's devices change? - # You should not enable this option unless you understand all the implications. - disable_device_change_key_rotation: false - - # Whether to explicitly set the avatar and room name for private chat portal rooms. - # If set to `default`, this will be enabled in encrypted rooms and disabled in unencrypted rooms. - # If set to `always`, all DM rooms will have explicit names and avatars set. - # If set to `never`, DM rooms will never have names and avatars set. - private_chat_portal_meta: default - # Disable generating reply fallbacks? Some extremely bad clients still rely on them, - # but they're being phased out and will be completely removed in the future. - disable_reply_fallbacks: false - # Should cross-chat replies from Telegram be bridged? Most servers and clients don't support this. - cross_room_replies: false - # Whether or not the bridge should send a read receipt from the bridge bot when a message has - # been sent to Telegram. - delivery_receipts: false - # Whether or not delivery errors should be reported as messages in the Matrix room. - delivery_error_reports: false - # Should errors in incoming message handling send a message to the Matrix room? - incoming_bridge_error_reports: false - # Whether the bridge should send the message status as a custom com.beeper.message_send_status event. - message_status_events: false - # Set this to true to tell the bridge to re-send m.bridge events to all rooms on the next run. - # This field will automatically be changed back to false after it, - # except if the config file is not writable. - resend_bridge_info: false - # When using double puppeting, should muted chats be muted in Matrix? - mute_bridging: false - # When using double puppeting, should pinned chats be moved to a specific tag in Matrix? - # The favorites tag is `m.favourite`. - pinned_tag: null - # Same as above for archived chats, the low priority tag is `m.lowpriority`. - archive_tag: null - # Whether or not mute status and tags should only be bridged when the portal room is created. - tag_only_on_create: true - # Should leaving the room on Matrix make the user leave on Telegram? - bridge_matrix_leave: true - # Should the user be kicked out of all portals when logging out of the bridge? - kick_on_logout: true - # Should the "* user joined Telegram" notice always be marked as read automatically? - always_read_joined_telegram_notice: true - # Should the bridge auto-create a group chat on Telegram when a ghost is invited to a room? - # Requires the user to have sufficient power level and double puppeting enabled. - create_group_on_invite: true - # Settings for backfilling messages from Telegram. - backfill: - # Allow backfilling at all? - enable: true - # Whether or not to enable backfilling in normal groups. - # Normal groups have numerous technical problems in Telegram, and backfilling normal groups - # will likely cause problems if there are multiple Matrix users in the group. - normal_groups: false - - # If a backfilled chat is older than this number of hours, mark it as read even if it's unread on Telegram. - # Set to -1 to let any chat be unread. - unread_hours_threshold: 720 - - # Forward backfilling limits. + # -1 means no limit (which means it's limited to 10000 by the server) + max_initial_sync: 100 + # Whether or not to sync the member list in broadcast channels. If + # disabled, members will still be synced when they send messages. # - # Using a negative initial limit is not recommended, as it would try to backfill everything in a single batch. - forward_limits: - # Number of messages to backfill immediately after creating a portal. - initial: - user: 50 - normal_group: 100 - supergroup: 10 - channel: 10 - # Number of messages to backfill when syncing chats. - sync: - user: 100 - normal_group: 100 - supergroup: 100 - channel: 100 - # Timeout for forward backfills in seconds. If you have a high limit, you'll have to increase this too. - forward_timeout: 900 - - # Settings for incremental backfill of history. These only apply to Beeper, as upstream abandoned MSC2716. - incremental: - # Maximum number of messages to backfill per batch. - messages_per_batch: 100 - # The number of seconds to wait after backfilling the batch of messages. - post_batch_delay: 20 - # The maximum number of batches to backfill per portal, split by the chat type. - # If set to -1, all messages in the chat will eventually be backfilled. - max_batches: - # Direct chats - user: -1 - # Normal groups. Note that the normal_groups option above must be enabled - # for these to be backfilled. - normal_group: -1 - # Supergroups - supergroup: 10 - # Broadcast channels - channel: -1 - - # Overrides for base power levels. - initial_power_level_overrides: - user: {} - group: {} - - # Whether to bridge Telegram bot messages as m.notices or m.texts. - bot_messages_as_notices: true - bridge_notices: - # Whether or not Matrix bot messages (type m.notice) should be bridged. - default: false - # List of user IDs for whom the previous flag is flipped. - # e.g. if bridge_notices.default is false, notices from other users will not be bridged, but - # notices from users listed here will be bridged. - exceptions: [] - - # An array of possible values for the $distinguisher variable in message formats. - # Each user gets one of the values here, based on a hash of their user ID. - # If the array is empty, the $distinguisher variable will also be empty. - relay_user_distinguishers: ["🟦", "🟣", "🟩", "⭕️", "🔶", "⬛️", "🔵", "🟢"] - # The formats to use when sending messages to Telegram via the relay bot. - # Text msgtypes (m.text, m.notice and m.emote) support HTML, media msgtypes don't. - # - # Available variables: - # $sender_displayname - The display name of the sender (e.g. Example User) - # $sender_username - The username (Matrix ID localpart) of the sender (e.g. alice) - # $sender_mxid - The Matrix ID of the sender (e.g. @alice:example.com) - # $distinguisher - A random string from the options in the relay_user_distinguishers array. - # $message - The message content - message_formats: - m.text: "$distinguisher $sender_displayname: $message" - m.notice: "$distinguisher $sender_displayname: $message" - m.emote: "* $distinguisher $sender_displayname $message" - m.file: "$distinguisher $sender_displayname sent a file: $message" - m.image: "$distinguisher $sender_displayname sent an image: $message" - m.audio: "$distinguisher $sender_displayname sent an audio file: $message" - m.video: "$distinguisher $sender_displayname sent a video: $message" - m.location: "$distinguisher $sender_displayname sent a location: $message" - # Telegram doesn't have built-in emotes, this field specifies how m.emote's from authenticated - # users are sent to telegram. All fields in message_formats are supported. Additionally, the - # Telegram user info is available in the following variables: - # $displayname - Telegram displayname - # $username - Telegram username (may not exist) - # $mention - Telegram @username or displayname mention (depending on which exists) - emote_format: "* $mention $formatted_body" - - # The formats to use when sending state events to Telegram via the relay bot. - # - # Variables from `message_formats` that have the `sender_` prefix are available without the prefix. - # In name_change events, `$prev_displayname` is the previous displayname. - # - # Set format to an empty string to disable the messages for that event. - state_event_formats: - join: "$distinguisher $displayname joined the room." - leave: "$distinguisher $displayname left the room." - name_change: "$distinguisher $prev_displayname changed their name to $distinguisher $displayname" - - # Filter rooms that can/can't be bridged. Can also be managed using the `filter` and - # `filter-mode` management commands. + # If no channel admins have logged into the bridge, the bridge won't be + # able to sync the member list regardless of this setting. + sync_broadcast_channels: false + # Whether or not to skip deleted members when syncing members. + skip_deleted: true + + # Settings for pings to the Telegram server. + ping: + # The interval (in seconds) between pings. + interval_seconds: 30 + # The timeout (in seconds) for a single ping. + timeout_seconds: 10 + + # Proxy settings + proxy: + # Allowed types: disabled, socks5, mtproxy + type: disabled + # Proxy IP address/domain name and port. + address: "127.0.0.1:1080" + # Proxy authentication (optional). Put MTProxy secret in password field. + username: + password: + + sync: + # Number of most recently active dialogs to check when syncing chats. + # Set to -1 to remove limit. + update_limit: 100 + # Number of most recently active dialogs to create portals for when syncing chats. + # Set to -1 to remove limit. + create_limit: 15 + # Number of chats to sync immediately on login before the data export is accepted. + # The create_limit above still applies. This is ignored if takeout.dialog_sync is false. + login_sync_limit: 15 + # Whether or not to sync and create portals for direct chats at startup. + direct_chats: true + + takeout: + # Should the bridge use the data export mode for syncing the full chat list? + # If true, login_sync_limit of chats is synced immediately on login, + # then the rest are synced after the takeout is accepted. + dialog_sync: false + # Should the bridge use the data export mode for forward backfilling messages? + # This should be set to true if the forward backfill limits are set to high values, + # but is probably not necessary otherwise. + forward_backfill: false + # Should the bridge use the data export mode for backward backfilling messages? + # This only affects the backfill queue, which is only available on Beeper. + backward_backfill: false + + # Maximum number of participants in chats to bridge. Only applies when the + # portal is being created. If there are more members when trying to create a + # room, the room creation will be cancelled. # - # An empty blacklist will essentially disable the filter. - filter: - # Filter mode to use. Either "blacklist" or "whitelist". - # If the mode is "blacklist", the listed chats will never be bridged. - # If the mode is "whitelist", only the listed chats can be bridged. - mode: {{ matrix_mautrix_telegram_filter_mode | to_json }} - # The list of group/channel IDs to filter. - list: [] - # How to handle direct chats: - # If users is "null", direct chats will follow the previous settings. - # If users is "true", direct chats will always be bridged. - # If users is "false", direct chats will never be bridged. - users: true + # -1 means no limit (which means all chats can be bridged) + max_member_count: -1 + # Should personal avatars (that are only visible to specific users) be allowed? + contact_avatars: false + # Should contact names be updated from any source even if a name is already set? + # Note that contact names will still be used if there's no other name available. + contact_names: false + # Should the bridge send all unicode reactions as custom emoji reactions to + # Telegram? By default, the bridge only uses custom emojis for unicode emojis + # that aren't allowed in reactions. + always_custom_emoji_reaction: false + # The avatar to use for the Telegram Saved Messages chat + saved_message_avatar: mxc://maunium.net/XhhfHoPejeneOngMyBbtyWDk + # Create a new room and tombstone the old one when upgrading rooms + always_tombstone_on_supergroup_migration: false + # Maximum number of pixels in an image before sending to Telegram as a + # document. Defaults to 4096x4096 = 16777216. + image_as_file_pixels: 16777216 + # Should view-once messages be disabled entirely? + disable_view_once: false + # Displayname template for Telegram users. + displayname_template: {{ matrix_bridge_mautrix_telegram_network_displayname_template | to_json }} +# Config options that affect the central bridge module. +bridge: # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_mautrix_telegram_command_prefix | to_json }} - - # Messages sent upon joining a management room. - # Markdown is supported. The defaults are listed below. - management_room_text: - # Sent when joining a room. - welcome: "Hello, I'm a Telegram bridge bot." - # Sent when joining a management room and the user is already logged in. - welcome_connected: "Use `help` for help." - # Sent when joining a management room and the user is not logged in. - welcome_unconnected: "Use `help` for help or `login` to log in." - # Optional extra text sent when joining a management room. - additional_help: "" - - # Send each message separately (for readability in some clients) - management_room_multiple_messages: false + command_prefix: {{ matrix_bridge_mautrix_telegram_command_prefix | to_json }} + # Should the bridge create a space for each login containing the rooms that account is in? + personal_filtering_spaces: {{ matrix_bridge_mautrix_telegram_bridge_personal_filtering_spaces | to_json }} + # Whether the bridge should set names and avatars explicitly for DM portals. + # This is only necessary when using clients that don't support MSC4171. + private_chat_portal_meta: true + # Should events be handled asynchronously within portal rooms? + # If true, events may end up being out of order, but slow events won't block other ones. + # This is not yet safe to use. + async_events: false + # Should every user have their own portals rather than sharing them? + # By default, users who are in the same group on the remote network will be + # in the same Matrix room bridged to that group. If this is set to true, + # every user will get their own Matrix room instead. + split_portals: false + # Should the bridge resend `m.bridge` events to all portals on startup? + resend_bridge_info: false + + # Should leaving Matrix rooms be bridged as leaving groups on the remote network? + bridge_matrix_leave: false + # Should room tags only be synced when creating the portal? Tags mean things like favorite/pin and archive/low priority. + # Tags currently can't be synced back to the remote network, so a continuous sync means tagging from Matrix will be undone. + tag_only_on_create: true + # Should room mute status only be synced when creating the portal? + # Like tags, mutes can't currently be synced back to the remote network. + mute_only_on_create: true + + # What should be done to portal rooms when a user logs out or is logged out? + # Permitted values: + # nothing - Do nothing, let the user stay in the portals + # kick - Remove the user from the portal rooms, but don't delete them + # unbridge - Remove all ghosts in the room and disassociate it from the remote chat + # delete - Remove all ghosts and users from the room (i.e. delete it) + cleanup_on_logout: + # Should cleanup on logout be enabled at all? + enabled: false + # Settings for manual logouts (explicitly initiated by the Matrix user) + manual: + # Action for private portals which will never be shared with other Matrix users. + private: nothing + # Action for portals with a relay user configured. + relayed: nothing + # Action for portals which may be shared, but don't currently have any other Matrix users. + shared_no_users: nothing + # Action for portals which have other logged-in Matrix users. + shared_has_users: nothing + # Settings for credentials being invalidated (initiated by the remote network, possibly through user action). + # Keys have the same meanings as in the manual section. + bad_credentials: + private: nothing + relayed: nothing + shared_no_users: nothing + shared_has_users: nothing + + # Settings for relay mode + relay: + # Whether relay mode should be allowed. If allowed, the set-relay command can be used to turn any + # authenticated user into a relaybot for that chat. + enabled: {{ matrix_bridge_mautrix_telegram_bridge_relay_enabled | to_json }} + # Should only admins be allowed to set themselves as relay users? + # If true, non-admins can only set users listed in default_relays as relays in a room. + admin_only: {{ matrix_bridge_mautrix_telegram_bridge_relay_admin_only | to_json }} + # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. + default_relays: {{ matrix_bridge_mautrix_telegram_bridge_relay_default_relays | to_json }} + # The formats to use when sending messages via the relaybot. + # Available variables: + # .Sender.UserID - The Matrix user ID of the sender. + # .Sender.Displayname - The display name of the sender (if set). + # .Sender.RequiresDisambiguation - Whether the sender's name may be confused with the name of another user in the room. + # .Sender.DisambiguatedName - The disambiguated name of the sender. This will be the displayname if set, + # plus the user ID in parentheses if the displayname is not unique. + # If the displayname is not set, this is just the user ID. + # .Message - The `formatted_body` field of the message. + # .Caption - The `formatted_body` field of the message, if it's a caption. Otherwise an empty string. + # .FileName - The name of the file being sent. + message_formats: + m.text: "{% raw %}{{ .Sender.DisambiguatedName }}: {{ .Message }}{% endraw %}" + m.notice: "{% raw %}{{ .Sender.DisambiguatedName }}: {{ .Message }}{% endraw %}" + m.emote: "{% raw %}* {{ .Sender.DisambiguatedName }} {{ .Message }}{% endraw %}" + m.file: "{% raw %}{{ .Sender.DisambiguatedName }} sent a file{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.image: "{% raw %}{{ .Sender.DisambiguatedName }} sent an image{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.audio: "{% raw %}{{ .Sender.DisambiguatedName }} sent an audio file{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.video: "{% raw %}{{ .Sender.DisambiguatedName }} sent a video{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.location: "{% raw %}{{ .Sender.DisambiguatedName }} sent a location{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" # Permissions for using the bridge. # Permitted values: - # relaybot - Only use the bridge via the relaybot, no access to commands. - # user - Relaybot level + access to commands to create bridges. - # puppeting - User level + logging in with a Telegram account. - # full - Full access to use the bridge, i.e. previous levels + Matrix login. - # admin - Full access to use the bridge and some extra administration commands. + # relay - Talk through the relaybot (if enabled), no access otherwise + # commands - Access to use commands in the bridge, but not login. + # user - Access to use the bridge with puppeting. + # admin - Full access, user level with some additional administration tools. # Permitted keys: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_telegram_bridge_permissions | to_json }} - - # Options related to the message relay Telegram bot. - relaybot: - private_chat: - # List of users to invite to the portal when someone starts a private chat with the bot. - # If empty, private chats with the bot won't create a portal. - invite: [] - # Whether or not to bridge state change messages in relaybot private chats. - state_changes: true - # When private_chat_invite is empty, this message is sent to users /starting the - # relaybot. Telegram's "markdown" is supported. - message: This is a Matrix bridge relaybot and does not support direct chats - # List of users to invite to all group chat portals created by the bridge. - group_chat_invite: [] - # Whether or not the relaybot should not bridge events in unbridged group chats. - # If false, portals will be created when the relaybot receives messages, just like normal - # users. This behavior is usually not desirable, as it interferes with manually bridging - # the chat to another room. - ignore_unbridged_group_chat: true - # Whether or not to allow creating portals from Telegram. - authless_portals: true - # Whether or not to allow Telegram group admins to use the bot commands. - whitelist_group_admins: true - # Whether or not to ignore incoming events sent by the relay bot. - ignore_own_incoming_events: true - # List of usernames/user IDs who are also allowed to use the bot commands. - whitelist: [] - -# Telegram config -telegram: - # Get your own API keys at https://my.telegram.org/apps - api_id: {{ matrix_mautrix_telegram_api_id|to_json }} - api_hash: {{ matrix_mautrix_telegram_api_hash|to_json }} - # (Optional) Create your own bot at https://t.me/BotFather - bot_token: {{ matrix_mautrix_telegram_bot_token|to_json }} - - # Should the bridge request missed updates from Telegram when restarting? - catch_up: true - # Should incoming updates be handled sequentially to make sure order is preserved on Matrix? - sequential_updates: true - exit_on_update_error: false - - # Telethon connection options. - connection: - # The timeout in seconds to be used when connecting. - timeout: 120 - # How many times the reconnection should retry, either on the initial connection or when - # Telegram disconnects us. May be set to a negative or null value for infinite retries, but - # this is not recommended, since the program can get stuck in an infinite loop. - retries: 5 - # The delay in seconds to sleep between automatic reconnections. - retry_delay: 1 - # The threshold below which the library should automatically sleep on flood wait errors - # (inclusive). For instance, if a FloodWaitError for 17s occurs and flood_sleep_threshold - # is 20s, the library will sleep automatically. If the error was for 21s, it would raise - # the error instead. Values larger than a day (86400) will be changed to a day. - flood_sleep_threshold: 60 - # How many times a request should be retried. Request are retried when Telegram is having - # internal issues, when there is a FloodWaitError less than flood_sleep_threshold, or when - # there's a migrate error. May take a negative or null value for infinite retries, but this - # is not recommended, since some requests can always trigger a call fail (such as searching - # for messages). - request_retries: 5 - # Use IPv6 for Telethon connection - use_ipv6: false - - # Device info sent to Telegram. - device_info: - # "auto" = OS name+version. - device_model: auto - # "auto" = Telethon version. - system_version: auto - # "auto" = mautrix-telegram version. - app_version: auto - lang_code: en - system_lang_code: en + permissions: {{ matrix_bridge_mautrix_telegram_bridge_permissions|to_json }} + +# Config for the bridge's database. +database: + # The database type. "sqlite3-fk-wal" and "postgres" are supported. + type: {{ matrix_bridge_mautrix_telegram_appservice_database_type | to_json }} + # The database URI. + # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. + # https://github.com/mattn/go-sqlite3#connection-string + # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable + # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql + uri: {{ matrix_bridge_mautrix_telegram_appservice_database_uri | to_json }} + # Maximum number of connections. + max_open_conns: 20 + max_idle_conns: 2 + # Maximum connection idle time and lifetime before they're closed. Disabled if null. + # Parsed with https://pkg.go.dev/time#ParseDuration + max_conn_idle_time: null + max_conn_lifetime: null + +# Homeserver details. +homeserver: + # The address that this appservice can use to connect to the homeserver. + # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, + # but https also works if they run on different machines. + address: {{ matrix_bridge_mautrix_telegram_homeserver_address | to_json }} + # The domain of the homeserver (also known as server_name, used for MXIDs, etc). + domain: {{ matrix_bridge_mautrix_telegram_homeserver_domain | to_json }} - # Custom server to connect to. - server: - # Set to true to use these server settings. If false, will automatically - # use production server assigned by Telegram. Set to false in production. + # What software is the homeserver running? + # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. + software: standard + # The URL to push real-time bridge status to. + # If set, the bridge will make POST requests to this URL whenever a user's remote network connection state changes. + # The bridge will use the appservice as_token to authorize requests. + status_endpoint: + # Endpoint for reporting per-message status. + # If set, the bridge will make POST requests to this URL when processing a message from Matrix. + # It will make one request when receiving the message (step BRIDGE), one after decrypting if applicable + # (step DECRYPTED) and one after sending to the remote network (step REMOTE). Errors will also be reported. + # The bridge will use the appservice as_token to authorize requests. + message_send_checkpoint_endpoint: + # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? + async_media: {{ matrix_bridge_mautrix_telegram_homeserver_async_media | to_json }} + + # Should the bridge use a websocket for connecting to the homeserver? + # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, + # mautrix-asmux (deprecated), and hungryserv (proprietary). + websocket: false + # How often should the websocket be pinged? Pinging will be disabled if this is zero. + ping_interval_seconds: 0 + +# Application service host/registration related details. +# Changing these values requires regeneration of the registration (except when noted otherwise) +appservice: + # The address that the homeserver can use to connect to this appservice. + # Like the homeserver address, a local non-https address is recommended when the bridge is on the same machine. + # If the bridge is elsewhere, you must secure the connection yourself (e.g. with https or wireguard) + # If you want to use https, you need to use a reverse proxy. The bridge does not have TLS support built in. + address: {{ matrix_bridge_mautrix_telegram_appservice_address | to_json }} + # A public address that external services can use to reach this appservice. + # This is only needed for things like public media. A reverse proxy is generally necessary when using this field. + # This value doesn't affect the registration file. + public_address: {{ matrix_bridge_mautrix_telegram_bridge_public_address | to_json }} + + # The hostname and port where this appservice should listen. + # For Docker, you generally have to change the hostname to 0.0.0.0. + hostname: 0.0.0.0 + port: 8080 + + # The unique ID of this appservice. + id: telegram + # Appservice bot details. + bot: + # Username of the appservice bot. + username: {{ matrix_bridge_mautrix_telegram_appservice_bot_username | to_json }} + # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty + # to leave display name/avatar as-is. + displayname: Telegram bridge bot + avatar: mxc://maunium.net/tJCRmUyJDsgRNgqhOgoiHWbX + + # Whether to receive ephemeral events via appservice transactions. + ephemeral_events: true + # Should incoming events be handled asynchronously? + # This may be necessary for large public instances with lots of messages going through. + # However, messages will not be guaranteed to be bridged in the same order they were sent in. + # This value doesn't affect the registration file. + async_transactions: false + + # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. + as_token: {{ matrix_bridge_mautrix_telegram_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_telegram_homeserver_token | to_json }} + + # Localpart template of MXIDs for remote users. + # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. + username_template: "{% raw %}telegram_{{.}}{% endraw %}" + +# Config options that affect the Matrix connector of the bridge. +matrix: + # Whether the bridge should send the message status as a custom com.beeper.message_send_status event. + message_status_events: false + # Whether the bridge should send a read receipt after successfully bridging a message. + delivery_receipts: false + # Whether the bridge should send error notices via m.notice events when a message fails to bridge. + message_error_notices: true + # Whether the bridge should update the m.direct account data event when double puppeting is enabled. + sync_direct_chat_list: true + # Whether created rooms should have federation enabled. If false, created portal rooms + # will never be federated. Changing this option requires recreating rooms. + federate_rooms: {{ matrix_bridge_mautrix_telegram_federate_rooms|to_json }} + # The threshold as bytes after which the bridge should roundtrip uploads via the disk + # rather than keeping the whole file in memory. + upload_file_threshold: 5242880 + +# Segment-compatible analytics endpoint for tracking some events, like provisioning API login and encryption errors. +analytics: + # API key to send with tracking requests. Tracking is disabled if this is null. + token: null + # Address to send tracking requests to. + url: https://api.segment.io/v1/track + # Optional user ID for tracking events. If null, defaults to using Matrix user ID. + user_id: null + +# Settings for provisioning API +provisioning: + # Prefix for the provisioning API paths. + prefix: /_matrix/provision + # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, + # or if set to "disable", the provisioning API will be disabled. + shared_secret: {{ matrix_bridge_mautrix_telegram_provisioning_shared_secret | to_json }} + # Whether to allow provisioning API requests to be authed using Matrix access tokens. + # This follows the same rules as double puppeting to determine which server to contact to check the token, + # which means that by default, it only works for users on the same server as the bridge. + allow_matrix_auth: true + # Enable debug API at /debug with provisioning authentication. + debug_endpoints: false + +# Some networks require publicly accessible media download links (e.g. for user avatars when using Discord webhooks). +# These settings control whether the bridge will provide such public media access. +public_media: + # Should public media be enabled at all? + # The public_address field under the appservice section MUST be set when enabling public media. + enabled: false + # A key for signing public media URLs. + # If set to "generate", a random key will be generated. + signing_key: {{ matrix_bridge_mautrix_telegram_public_media_signing_key | to_json }} + # Number of seconds that public media URLs are valid for. + # If set to 0, URLs will never expire. + expiry: 0 + # Length of hash to use for public media URLs. Must be between 0 and 32. + hash_length: 32 + +# Settings for converting remote media to custom mxc:// URIs instead of reuploading. +# More details can be found at https://docs.mau.fi/bridges/go/discord/direct-media.html +direct_media: + # Should custom mxc:// URIs be used instead of reuploading media? + enabled: false + # The server name to use for the custom mxc:// URIs. + # This server name will effectively be a real Matrix server, it just won't implement anything other than media. + # You must either set up .well-known delegation from this domain to the bridge, or proxy the domain directly to the bridge. + server_name: telegram-media.example.com + # Optionally a custom .well-known response. This defaults to `server_name:443` + well_known_response: + # Optionally specify a custom prefix for the media ID part of the MXC URI. + media_id_prefix: + # If the remote network supports media downloads over HTTP, then the bridge will use MSC3860/MSC3916 + # media download redirects if the requester supports it. Optionally, you can force redirects + # and not allow proxying at all by setting this to false. + # This option does nothing if the remote network does not support media downloads over HTTP. + allow_proxy: true + # Matrix server signing key to make the federation tester pass, same format as synapse's .signing.key file. + # This key is also used to sign the mxc:// URIs to ensure only the bridge can generate them. + server_key: "" + +# Settings for backfilling messages. +# Note that the exact way settings are applied depends on the network connector. +# See https://docs.mau.fi/bridges/general/backfill.html for more details. +backfill: + # Whether to do backfilling at all. + enabled: {{ matrix_bridge_mautrix_telegram_backfill_enabled | to_json }} + # Maximum number of messages to backfill in empty rooms. + max_initial_messages: 50 + # Maximum number of missed messages to backfill after bridge restarts. + max_catchup_messages: 500 + # If a backfilled chat is older than this number of hours, + # mark it as read even if it's unread on the remote network. + unread_hours_threshold: 720 + # Settings for backfilling threads within other backfills. + threads: + # Maximum number of messages to backfill in a new thread. + max_initial_messages: 50 + # Settings for the backwards backfill queue. This only applies when connecting to + # Beeper as standard Matrix servers don't support inserting messages into history. + queue: + # Should the backfill queue be enabled? enabled: false - # The DC ID to connect to. - dc: 2 - # The IP to connect to. - ip: 149.154.167.40 - # The port to connect to. 443 may not work, 80 is better and both are equally secure. - port: 80 - - # Telethon proxy configuration. - # You must install PySocks from pip for proxies to work. - proxy: - # Allowed types: disabled, socks4, socks5, http - type: disabled - # Proxy IP address and port. - address: 127.0.0.1 - port: 1080 - # Whether or not to perform DNS resolving remotely. - rdns: true - # Proxy authentication (optional). - username: "" - password: "" - -# Python logging configuration. + # Number of messages to backfill in one batch. + batch_size: 100 + # Delay between batches in seconds. + batch_delay: 20 + # Maximum number of batches to backfill per portal. + # If set to -1, all available messages will be backfilled. + max_batches: -1 + # Optional network-specific overrides for max batches. + # Interpretation of this field depends on the network connector. + max_batches_override: {} + +# Settings for enabling double puppeting +double_puppet: + # Servers to always allow double puppeting from. + # This is only for other servers and should NOT contain the server the bridge is on. + servers: {} + # Whether to allow client API URL discovery for other servers. When using this option, + # users on other servers can use double puppeting even if their server URLs aren't + # explicitly added to the servers map above. + allow_discovery: false + # Shared secrets for automatic double puppeting. + # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. + secrets: {{ matrix_bridge_mautrix_telegram_double_puppet_secrets | to_json }} + +# End-to-bridge encryption support options. # -# See section 16.7.2 of the Python documentation for more info: -# https://docs.python.org/3.6/library/logging.config.html#configuration-dictionary-schema +# See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. +encryption: + # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. + allow: {{ matrix_bridge_mautrix_telegram_bridge_encryption_allow | to_json }} + # Whether to force-enable encryption in all bridged rooms. + default: {{ matrix_bridge_mautrix_telegram_bridge_encryption_default | to_json }} + # Whether to require all messages to be encrypted and drop any unencrypted messages. + require: {{ matrix_bridge_mautrix_telegram_bridge_encryption_require | to_json }} + # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. + # This option is not yet compatible with standard Matrix servers like Synapse and should not be used. + appservice: false + # Whether to use MSC4190 instead of appservice login to create the bridge bot device. + # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. + # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). + # Changing this option requires updating the appservice registration file. + msc4190: {{ matrix_bridge_mautrix_telegram_msc4190_enabled | to_json }} + # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) + # Requires msc4190 to replace keys on reset + self_sign: {{ matrix_bridge_mautrix_telegram_self_sign_enabled | to_json }} + # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. + # You must use a client that supports requesting keys from other users to use this feature. + allow_key_sharing: {{ matrix_bridge_mautrix_telegram_bridge_encryption_key_sharing_allow | to_json }} + # Pickle key for encrypting encryption keys in the bridge database. + # If set to generate, a random key will be generated. + pickle_key: {{ matrix_bridge_mautrix_telegram_bridge_encryption_pickle_key | to_json }} + # Options for deleting megolm sessions from the bridge. + delete_keys: + # Beeper-specific: delete outbound sessions when hungryserv confirms + # that the user has uploaded the key to key backup. + delete_outbound_on_ack: false + # Don't store outbound sessions in the inbound table. + dont_store_outbound: false + # Ratchet megolm sessions forward after decrypting messages. + ratchet_on_decrypt: false + # Delete fully used keys (index >= max_messages) after decrypting messages. + delete_fully_used_on_decrypt: false + # Delete previous megolm sessions from same device when receiving a new one. + delete_prev_on_new_session: false + # Delete megolm sessions received from a device when the device is deleted. + delete_on_device_delete: false + # Periodically delete megolm sessions when 2x max_age has passed since receiving the session. + periodically_delete_expired: false + # Delete inbound megolm sessions that don't have the received_at field used for + # automatic ratcheting and expired session deletion. This is meant as a migration + # to delete old keys prior to the bridge update. + delete_outdated_inbound: false + # What level of device verification should be required from users? + # + # Valid levels: + # unverified - Send keys to all device in the room. + # cross-signed-untrusted - Require valid cross-signing, but trust all cross-signing keys. + # cross-signed-tofu - Require valid cross-signing, trust cross-signing keys on first use (and reject changes). + # cross-signed-verified - Require valid cross-signing, plus a valid user signature from the bridge bot. + # Note that creating user signatures from the bridge bot is not currently possible. + # verified - Require manual per-device verification + # (currently only possible by modifying the `trust` column in the `crypto_device` database table). + verification_levels: + # Minimum level for which the bridge should send keys to when bridging messages from the remote network to Matrix. + receive: unverified + # Minimum level that the bridge should accept for incoming Matrix messages. + send: unverified + # Minimum level that the bridge should require for accepting key requests. + share: cross-signed-tofu + # Options for Megolm room key rotation. These options allow you to configure the m.room.encryption event content. + # See https://spec.matrix.org/v1.10/client-server-api/#mroomencryption for more information about that event. + rotation: + # Enable custom Megolm room key rotation settings. Note that these + # settings will only apply to rooms created after this option is set. + enable_custom: false + # The maximum number of milliseconds a session should be used + # before changing it. The Matrix spec recommends 604800000 (a week) + # as the default. + milliseconds: 604800000 + # The maximum number of messages that should be sent with a given a + # session before changing it. The Matrix spec recommends 100 as the + # default. + messages: 100 + # Disable rotating keys when a user's devices change? + # You should not enable this option unless you understand all the implications. + disable_device_change_key_rotation: false + +# Logging config. See https://github.com/tulir/zeroconfig for details. logging: - version: 1 - formatters: - precise: - format: "[%(asctime)s] [%(levelname)s@%(name)s] %(message)s" - handlers: - console: - class: logging.StreamHandler - formatter: precise - loggers: - mau: - level: {{ matrix_mautrix_telegram_logging_level|to_json }} - telethon: - level: {{ matrix_mautrix_telegram_logging_level|to_json }} - aiohttp: - level: {{ matrix_mautrix_telegram_logging_level|to_json }} - root: - level: {{ matrix_mautrix_telegram_logging_level|to_json }} - handlers: [console] + min_level: {{ matrix_bridge_mautrix_telegram_logging_level | to_json }} + writers: + - type: stdout + format: pretty-colored diff --git a/roles/custom/matrix-bridge-mautrix-telegram/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-telegram/templates/labels.j2 index 04021d807..2c26ecd11 100644 --- a/roles/custom/matrix-bridge-mautrix-telegram/templates/labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-telegram/templates/labels.j2 @@ -1,78 +1,45 @@ {# -SPDX-FileCopyrightText: 2024 Slavi Pantaleev +SPDX-FileCopyrightText: 2024 - 2026 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_telegram_container_labels_traefik_enabled %} +{% if matrix_bridge_mautrix_telegram_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_mautrix_telegram_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_telegram_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_telegram_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_telegram_container_labels_traefik_docker_network }} {% endif %} -{% if matrix_mautrix_telegram_container_labels_public_endpoint_enabled %} +{% if matrix_bridge_mautrix_telegram_container_labels_exposure_enabled %} ############################################################ # # -# Public # +# Bridge API exposure # # # ############################################################ -traefik.http.services.matrix-mautrix-telegram-appservice.loadbalancer.server.port=8080 +traefik.http.services.matrix-mautrix-telegram-exposure.loadbalancer.server.port=8080 -traefik.http.routers.matrix-mautrix-telegram-public.rule={{ matrix_mautrix_telegram_container_labels_public_endpoint_traefik_rule }} +traefik.http.middlewares.matrix-mautrix-telegram-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_telegram_exposure_path_prefix }} +traefik.http.routers.matrix-mautrix-telegram-exposure.middlewares=matrix-mautrix-telegram-exposure-strip-prefix -{% if matrix_mautrix_telegram_container_labels_public_endpoint_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-telegram-public.priority={{ matrix_mautrix_telegram_container_labels_public_endpoint_traefik_priority }} -{% endif %} - -traefik.http.routers.matrix-mautrix-telegram-public.service=matrix-mautrix-telegram-appservice -traefik.http.routers.matrix-mautrix-telegram-public.entrypoints={{ matrix_mautrix_telegram_container_labels_public_endpoint_traefik_entrypoints }} - -traefik.http.routers.matrix-mautrix-telegram-public.tls={{ matrix_mautrix_telegram_container_labels_public_endpoint_traefik_tls | to_json }} -{% if matrix_mautrix_telegram_container_labels_public_endpoint_traefik_tls %} -traefik.http.routers.matrix-mautrix-telegram-public.tls.certResolver={{ matrix_mautrix_telegram_container_labels_public_endpoint_traefik_tls_certResolver }} -{% endif %} - -############################################################ -# # -# /Public # -# # -############################################################ -{% endif %} - - -{% if matrix_mautrix_telegram_container_labels_metrics_enabled %} -############################################################ -# # -# Metrics # -# # -############################################################ - -traefik.http.services.matrix-mautrix-telegram-metrics.loadbalancer.server.port=8000 - -{% if matrix_mautrix_telegram_container_labels_metrics_middleware_basic_auth_enabled %} -traefik.http.middlewares.matrix-mautrix-telegram-metrics-basic-auth.basicauth.users={{ matrix_mautrix_telegram_container_labels_metrics_middleware_basic_auth_users }} -traefik.http.routers.matrix-mautrix-telegram-metrics.middlewares=matrix-mautrix-telegram-metrics-basic-auth -{% endif %} - -traefik.http.routers.matrix-mautrix-telegram-metrics.rule={{ matrix_mautrix_telegram_container_labels_metrics_traefik_rule }} +traefik.http.routers.matrix-mautrix-telegram-exposure.rule={{ matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_rule }} -{% if matrix_mautrix_telegram_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-telegram-metrics.priority={{ matrix_mautrix_telegram_container_labels_metrics_traefik_priority }} +{% if matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-telegram-exposure.priority={{ matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_priority }} {% endif %} -traefik.http.routers.matrix-mautrix-telegram-metrics.service=matrix-mautrix-telegram-metrics -traefik.http.routers.matrix-mautrix-telegram-metrics.entrypoints={{ matrix_mautrix_telegram_container_labels_metrics_traefik_entrypoints }} +traefik.http.routers.matrix-mautrix-telegram-exposure.service=matrix-mautrix-telegram-exposure +traefik.http.routers.matrix-mautrix-telegram-exposure.entrypoints={{ matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_entrypoints }} -traefik.http.routers.matrix-mautrix-telegram-metrics.tls={{ matrix_mautrix_telegram_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_mautrix_telegram_container_labels_metrics_traefik_tls %} -traefik.http.routers.matrix-mautrix-telegram-metrics.tls.certResolver={{ matrix_mautrix_telegram_container_labels_metrics_traefik_tls_certResolver }} +traefik.http.routers.matrix-mautrix-telegram-exposure.tls={{ matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-mautrix-telegram-exposure.tls.certResolver={{ matrix_bridge_mautrix_telegram_container_labels_exposure_traefik_tls_certResolver }} {% endif %} ############################################################ # # -# /Metrics # +# /Bridge API exposure # # # ############################################################ {% endif %} @@ -80,4 +47,4 @@ traefik.http.routers.matrix-mautrix-telegram-metrics.tls.certResolver={{ matrix_ {% endif %} -{{ matrix_mautrix_telegram_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_telegram_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-telegram/templates/systemd/matrix-mautrix-telegram.service.j2 b/roles/custom/matrix-bridge-mautrix-telegram/templates/systemd/matrix-mautrix-telegram.service.j2 index e8382c20c..177500a0a 100644 --- a/roles/custom/matrix-bridge-mautrix-telegram/templates/systemd/matrix-mautrix-telegram.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-telegram/templates/systemd/matrix-mautrix-telegram.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix Telegram bridge -{% for service in matrix_mautrix_telegram_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_telegram_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_telegram_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_telegram_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,22 +22,22 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_telegram_container_network }} \ - {% if matrix_mautrix_telegram_appservice_public_enabled and matrix_mautrix_telegram_container_http_host_bind_port %} - -p {{ matrix_mautrix_telegram_container_http_host_bind_port }}:8080 \ - {% endif %} - --mount type=bind,src={{ matrix_mautrix_telegram_config_path }},dst=/config \ - --mount type=bind,src={{ matrix_mautrix_telegram_data_path }},dst=/data \ - --label-file={{ matrix_mautrix_telegram_base_path }}/labels \ - {% for arg in matrix_mautrix_telegram_container_extra_arguments %} + --network={{ matrix_bridge_mautrix_telegram_container_network }} \ + --mount type=bind,src={{ matrix_bridge_mautrix_telegram_config_path }},dst=/config \ + --mount type=bind,src={{ matrix_bridge_mautrix_telegram_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_telegram_base_path }}/labels \ + --workdir=/data \ + {% for arg in matrix_bridge_mautrix_telegram_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_telegram_container_image }} \ - python3 -m mautrix_telegram -c /config/config.yaml --no-update + {{ matrix_bridge_mautrix_telegram_container_image }} \ + /usr/bin/mautrix-telegram -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_mautrix_telegram_container_additional_networks %} +{% if matrix_bridge_mautrix_telegram_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_telegram_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-telegram {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-telegram diff --git a/roles/custom/matrix-bridge-mautrix-twitter/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-twitter/defaults/main.yml index 82bb796cf..9687362c2 100644 --- a/roles/custom/matrix-bridge-mautrix-twitter/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-twitter/defaults/main.yml @@ -15,212 +15,206 @@ # mautrix-twitter is a Matrix <-> Twitter bridge # Project source code URL: https://github.com/mautrix/twitter -matrix_mautrix_twitter_enabled: true +matrix_bridge_mautrix_twitter_enabled: true -matrix_mautrix_twitter_container_image_self_build: false -matrix_mautrix_twitter_container_image_self_build_repo: "https://github.com/mautrix/twitter.git" -matrix_mautrix_twitter_container_image_self_build_repo_version: "{{ 'master' if matrix_mautrix_twitter_version == 'latest' else matrix_mautrix_twitter_version }}" +matrix_bridge_mautrix_twitter_container_image_self_build: false +matrix_bridge_mautrix_twitter_container_image_self_build_repo: "https://github.com/mautrix/twitter.git" +matrix_bridge_mautrix_twitter_container_image_self_build_repo_version: "{{ 'master' if matrix_bridge_mautrix_twitter_version == 'latest' else matrix_bridge_mautrix_twitter_version }}" # renovate: datasource=docker depName=dock.mau.dev/mautrix/twitter -matrix_mautrix_twitter_version: v0.2603.0 +matrix_bridge_mautrix_twitter_version: v0.2608.0 # See: https://mau.dev/tulir/mautrix-twitter/container_registry -matrix_mautrix_twitter_container_image: "{{ matrix_mautrix_twitter_container_image_registry_prefix }}mautrix/twitter:{{ matrix_mautrix_twitter_version }}" -matrix_mautrix_twitter_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_twitter_container_image_self_build else matrix_mautrix_twitter_container_image_registry_prefix_upstream }}" -matrix_mautrix_twitter_container_image_registry_prefix_upstream: "{{ matrix_mautrix_twitter_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_twitter_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_twitter_container_image_force_pull: "{{ matrix_mautrix_twitter_container_image.endswith(':latest') }}" - -matrix_mautrix_twitter_base_path: "{{ matrix_base_data_path }}/mautrix-twitter" -matrix_mautrix_twitter_config_path: "{{ matrix_mautrix_twitter_base_path }}/config" -matrix_mautrix_twitter_data_path: "{{ matrix_mautrix_twitter_base_path }}/data" -matrix_mautrix_twitter_container_src_files_path: "{{ matrix_mautrix_twitter_base_path }}/docker-src" - -matrix_mautrix_twitter_homeserver_address: "" +matrix_bridge_mautrix_twitter_container_image: "{{ matrix_bridge_mautrix_twitter_container_image_registry_prefix }}mautrix/twitter:{{ matrix_bridge_mautrix_twitter_version }}" +matrix_bridge_mautrix_twitter_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_twitter_container_image_self_build else matrix_bridge_mautrix_twitter_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_twitter_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_twitter_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_twitter_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bridge_mautrix_twitter_base_path: "{{ matrix_base_data_path }}/mautrix-twitter" +matrix_bridge_mautrix_twitter_config_path: "{{ matrix_bridge_mautrix_twitter_base_path }}/config" +matrix_bridge_mautrix_twitter_data_path: "{{ matrix_bridge_mautrix_twitter_base_path }}/data" +matrix_bridge_mautrix_twitter_container_src_files_path: "{{ matrix_bridge_mautrix_twitter_base_path }}/docker-src" + +matrix_bridge_mautrix_twitter_homeserver_address: "" # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_mautrix_twitter_homeserver_async_media: false -matrix_mautrix_twitter_homeserver_domain: '{{ matrix_domain }}' -matrix_mautrix_twitter_appservice_address: 'http://matrix-mautrix-twitter:29327' +matrix_bridge_mautrix_twitter_homeserver_async_media: false +matrix_bridge_mautrix_twitter_homeserver_domain: '{{ matrix_domain }}' +matrix_bridge_mautrix_twitter_appservice_address: 'http://matrix-mautrix-twitter:29327' -matrix_mautrix_twitter_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" -matrix_mautrix_twitter_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" +matrix_bridge_mautrix_twitter_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_twitter_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" -# A public address that external services can use to reach this appservice. -matrix_mautrix_twitter_appservice_public_address: '' +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_twitter_appservice_public_address`). +matrix_bridge_mautrix_twitter_scheme: https + +# A public address that external services can use to reach this appservice (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_twitter_appservice_public_address: "{{ (matrix_bridge_mautrix_twitter_scheme + '://' + matrix_bridge_mautrix_twitter_exposure_hostname + matrix_bridge_mautrix_twitter_exposure_path_prefix) if matrix_bridge_mautrix_twitter_exposure_enabled else '' }}" # Displayname template for Twitter users. # {{ .DisplayName }} is replaced with the display name of the Twitter user. # {{ .Username }} is replaced with the username of the Twitter user. -matrix_mautrix_twitter_network_displayname_template: "{% raw %}{{ .DisplayName }} (Twitter){% endraw %}" +matrix_bridge_mautrix_twitter_network_displayname_template: "{% raw %}{{ .DisplayName }} (Twitter){% endraw %}" -matrix_mautrix_twitter_bridge_command_prefix: "!tw" +matrix_bridge_mautrix_twitter_bridge_command_prefix: "!tw" -matrix_mautrix_twitter_bridge_permissions: | +matrix_bridge_mautrix_twitter_bridge_permissions: | {{ - {matrix_mautrix_twitter_homeserver_domain: 'user'} + {matrix_bridge_mautrix_twitter_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} -matrix_mautrix_twitter_container_network: "" +matrix_bridge_mautrix_twitter_container_network: "" -matrix_mautrix_twitter_container_additional_networks: "{{ matrix_mautrix_twitter_container_additional_networks_auto + matrix_mautrix_twitter_container_additional_networks_custom }}" -matrix_mautrix_twitter_container_additional_networks_auto: [] -matrix_mautrix_twitter_container_additional_networks_custom: [] +matrix_bridge_mautrix_twitter_container_additional_networks: "{{ matrix_bridge_mautrix_twitter_container_additional_networks_auto + matrix_bridge_mautrix_twitter_container_additional_networks_custom }}" +matrix_bridge_mautrix_twitter_container_additional_networks_auto: [] +matrix_bridge_mautrix_twitter_container_additional_networks_custom: [] -# matrix_mautrix_twitter_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_mautrix_twitter_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_twitter_container_labels_additional_labels`. -matrix_mautrix_twitter_container_labels_traefik_enabled: true -matrix_mautrix_twitter_container_labels_traefik_docker_network: "{{ matrix_mautrix_twitter_container_network }}" -matrix_mautrix_twitter_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_twitter_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose mautrix-instagram's metrics -matrix_mautrix_twitter_container_labels_metrics_enabled: "{{ matrix_mautrix_twitter_metrics_enabled and matrix_mautrix_twitter_metrics_proxying_enabled }}" -matrix_mautrix_twitter_container_labels_metrics_traefik_rule: "Host(`{{ matrix_mautrix_twitter_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_mautrix_twitter_metrics_proxying_path_prefix }}`)" -matrix_mautrix_twitter_container_labels_metrics_traefik_priority: 0 -matrix_mautrix_twitter_container_labels_metrics_traefik_entrypoints: "{{ matrix_mautrix_twitter_container_labels_traefik_entrypoints }}" -matrix_mautrix_twitter_container_labels_metrics_traefik_tls: "{{ matrix_mautrix_twitter_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_mautrix_twitter_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_mautrix_twitter_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_mautrix_twitter_container_labels_metrics_middleware_basic_auth_enabled: false -# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_mautrix_twitter_container_labels_metrics_middleware_basic_auth_users: '' - -# matrix_mautrix_twitter_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# To inject your own other container labels, see `matrix_bridge_mautrix_twitter_container_labels_additional_labels`. +matrix_bridge_mautrix_twitter_container_labels_traefik_enabled: true +matrix_bridge_mautrix_twitter_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_twitter_container_network }}" +matrix_bridge_mautrix_twitter_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_twitter_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-twitter's HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_twitter_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_twitter_exposure_enabled }}" +matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_twitter_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_twitter_exposure_path_prefix }}`)" +matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_twitter_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_twitter_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_twitter_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_twitter_container_labels_additional_labels: | +# matrix_bridge_mautrix_twitter_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_twitter_container_labels_additional_labels: '' +matrix_bridge_mautrix_twitter_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_twitter_container_extra_arguments: [] +matrix_bridge_mautrix_twitter_container_extra_arguments: [] # List of systemd services that matrix-mautrix-twitter.service depends on. -matrix_mautrix_twitter_systemd_required_services_list: "{{ matrix_mautrix_twitter_systemd_required_services_list_default + matrix_mautrix_twitter_systemd_required_services_list_auto + matrix_mautrix_twitter_systemd_required_services_list_custom }}" -matrix_mautrix_twitter_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_twitter_systemd_required_services_list_auto: [] -matrix_mautrix_twitter_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_twitter_systemd_required_services_list: "{{ matrix_bridge_mautrix_twitter_systemd_required_services_list_default + matrix_bridge_mautrix_twitter_systemd_required_services_list_auto + matrix_bridge_mautrix_twitter_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_twitter_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_twitter_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_twitter_systemd_required_services_list_custom: [] # List of systemd services that matrix-mautrix-twitter.service wants -matrix_mautrix_twitter_systemd_wanted_services_list: [] +matrix_bridge_mautrix_twitter_systemd_wanted_services_list: [] -matrix_mautrix_twitter_appservice_token: '' -matrix_mautrix_twitter_homeserver_token: '' +matrix_bridge_mautrix_twitter_appservice_token: '' +matrix_bridge_mautrix_twitter_homeserver_token: '' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_mautrix_twitter_matrix_federate_rooms: true +matrix_bridge_mautrix_twitter_matrix_federate_rooms: true # Database-related configuration fields. # # To use Postgres: -# - adjust your database credentials via the `matrix_mautrix_twitter_postgres_*` variables -matrix_mautrix_twitter_database_engine: 'postgres' +# - adjust your database credentials via the `matrix_bridge_mautrix_twitter_postgres_*` variables +matrix_bridge_mautrix_twitter_database_engine: 'postgres' -matrix_mautrix_twitter_database_username: 'matrix_mautrix_twitter' -matrix_mautrix_twitter_database_password: 'some-password' -matrix_mautrix_twitter_database_hostname: '' -matrix_mautrix_twitter_database_port: 5432 -matrix_mautrix_twitter_database_name: 'matrix_mautrix_twitter' -matrix_mautrix_twitter_database_sslmode: disable +matrix_bridge_mautrix_twitter_database_username: 'matrix_mautrix_twitter' +matrix_bridge_mautrix_twitter_database_password: 'some-password' +matrix_bridge_mautrix_twitter_database_hostname: '' +matrix_bridge_mautrix_twitter_database_port: 5432 +matrix_bridge_mautrix_twitter_database_name: 'matrix_mautrix_twitter' +matrix_bridge_mautrix_twitter_database_sslmode: disable -matrix_mautrix_twitter_database_connection_string: 'postgres://{{ matrix_mautrix_twitter_database_username }}:{{ matrix_mautrix_twitter_database_password }}@{{ matrix_mautrix_twitter_database_hostname }}:{{ matrix_mautrix_twitter_database_port }}/{{ matrix_mautrix_twitter_database_name }}?sslmode={{ matrix_mautrix_twitter_database_sslmode }}' +matrix_bridge_mautrix_twitter_database_connection_string: 'postgres://{{ matrix_bridge_mautrix_twitter_database_username }}:{{ matrix_bridge_mautrix_twitter_database_password }}@{{ matrix_bridge_mautrix_twitter_database_hostname }}:{{ matrix_bridge_mautrix_twitter_database_port }}/{{ matrix_bridge_mautrix_twitter_database_name }}?sslmode={{ matrix_bridge_mautrix_twitter_database_sslmode }}' -matrix_mautrix_twitter_database_uri: "{{ - { - 'postgres': matrix_mautrix_twitter_database_connection_string, - }[matrix_mautrix_twitter_database_engine] -}}" +matrix_bridge_mautrix_twitter_database_uri: "{{ { + 'postgres': matrix_bridge_mautrix_twitter_database_connection_string, +}[matrix_bridge_mautrix_twitter_database_engine] }}" -matrix_mautrix_twitter_double_puppet_secrets: "{{ matrix_mautrix_twitter_double_puppet_secrets_auto | combine(matrix_mautrix_twitter_double_puppet_secrets_custom) }}" -matrix_mautrix_twitter_double_puppet_secrets_auto: {} -matrix_mautrix_twitter_double_puppet_secrets_custom: {} +matrix_bridge_mautrix_twitter_double_puppet_secrets: "{{ matrix_bridge_mautrix_twitter_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_twitter_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_twitter_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_twitter_double_puppet_secrets_custom: {} -matrix_mautrix_twitter_appservice_bot_username: twitterbot -matrix_mautrix_twitter_appservice_bot_displayname: Twitter bridge bot -matrix_mautrix_twitter_appservice_bot_avatar: mxc://maunium.net/HVHcnusJkQcpVcsVGZRELLCn +matrix_bridge_mautrix_twitter_appservice_bot_username: twitterbot +matrix_bridge_mautrix_twitter_appservice_bot_displayname: Twitter bridge bot +matrix_bridge_mautrix_twitter_appservice_bot_avatar: mxc://maunium.net/HVHcnusJkQcpVcsVGZRELLCn -matrix_mautrix_twitter_backfill_enabled: true +matrix_bridge_mautrix_twitter_backfill_enabled: true # Maximum number of messages to backfill in empty rooms -matrix_mautrix_twitter_backfill_max_initial_messages: 50 +matrix_bridge_mautrix_twitter_backfill_max_initial_messages: 50 # Maximum number of missed messages to backfill after bridge restarts -matrix_mautrix_twitter_backfill_max_catchup_messages: 500 +matrix_bridge_mautrix_twitter_backfill_max_catchup_messages: 500 # Shared secret for authentication of provisioning API requests. # If set to "disable", the provisioning API will be disabled. -matrix_mautrix_twitter_provisioning_shared_secret: disable +matrix_bridge_mautrix_twitter_provisioning_shared_secret: disable # Minimum severity of journal log messages. # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_twitter_logging_level: 'warn' - -# Whether or not metrics endpoint should be enabled. -# Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_mautrix_twitter_metrics_proxying_enabled`. -matrix_mautrix_twitter_metrics_enabled: false +matrix_bridge_mautrix_twitter_logging_level: 'warn' -# Controls whether metrics should be exposed on a public URL. -matrix_mautrix_twitter_metrics_proxying_enabled: false -matrix_mautrix_twitter_metrics_proxying_hostname: '' -matrix_mautrix_twitter_metrics_proxying_path_prefix: '' +# Controls whether mautrix-twitter's HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_twitter_exposure_enabled: false +matrix_bridge_mautrix_twitter_exposure_hostname: '' +matrix_bridge_mautrix_twitter_exposure_path_prefix: '' # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_twitter_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_twitter_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_twitter_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_twitter_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_twitter_configuration_extension_yaml: | +matrix_bridge_mautrix_twitter_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_twitter_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_twitter_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_twitter_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_twitter_configuration_yaml`. -matrix_mautrix_twitter_configuration_extension: "{{ matrix_mautrix_twitter_configuration_extension_yaml | from_yaml if matrix_mautrix_twitter_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_twitter_configuration_extension: "{{ matrix_bridge_mautrix_twitter_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_twitter_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_twitter_configuration_yaml`. -matrix_mautrix_twitter_configuration: "{{ matrix_mautrix_twitter_configuration_yaml | from_yaml | combine(matrix_mautrix_twitter_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_twitter_configuration_yaml`. +matrix_bridge_mautrix_twitter_configuration: "{{ matrix_bridge_mautrix_twitter_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_twitter_configuration_extension, recursive=True) }}" -matrix_mautrix_twitter_registration_yaml: | +matrix_bridge_mautrix_twitter_registration_yaml: | id: twitter - as_token: "{{ matrix_mautrix_twitter_appservice_token }}" - hs_token: "{{ matrix_mautrix_twitter_homeserver_token }}" + as_token: "{{ matrix_bridge_mautrix_twitter_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_twitter_homeserver_token }}" namespaces: users: - exclusive: true - regex: '^@twitter_.+:{{ matrix_mautrix_twitter_homeserver_domain | regex_escape }}$' + regex: '^@twitter_.+:{{ matrix_bridge_mautrix_twitter_homeserver_domain | regex_escape }}$' - exclusive: true - regex: '^@{{ matrix_mautrix_twitter_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_twitter_homeserver_domain | regex_escape }}$' - url: {{ matrix_mautrix_twitter_appservice_address }} + regex: '^@{{ matrix_bridge_mautrix_twitter_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_twitter_homeserver_domain | regex_escape }}$' + url: {{ matrix_bridge_mautrix_twitter_appservice_address }} # See https://github.com/tulir/mautrix-twitter/issues/43 - sender_localpart: _bot_{{ matrix_mautrix_twitter_appservice_bot_username }} + sender_localpart: _bot_{{ matrix_bridge_mautrix_twitter_appservice_bot_username }} rate_limited: false de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_mautrix_twitter_msc4190_enabled | to_json }} + io.element.msc4190: {{ matrix_bridge_mautrix_twitter_msc4190_enabled | to_json }} -matrix_mautrix_twitter_registration: "{{ matrix_mautrix_twitter_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_twitter_registration: "{{ matrix_bridge_mautrix_twitter_registration_yaml | from_yaml }}" # Enable End-to-bridge encryption -matrix_mautrix_twitter_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_twitter_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_mautrix_twitter_bridge_encryption_require: false -matrix_mautrix_twitter_bridge_encryption_appservice: false -matrix_mautrix_twitter_bridge_encryption_key_sharing_allow: "{{ matrix_mautrix_twitter_bridge_encryption_allow }}" +matrix_bridge_mautrix_twitter_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_twitter_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_twitter_bridge_encryption_require: false +matrix_bridge_mautrix_twitter_bridge_encryption_appservice: false +matrix_bridge_mautrix_twitter_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_mautrix_twitter_bridge_encryption_allow }}" # This pickle key value is compatible with the old mautrix-twitter bridge (before bridgev2). -matrix_mautrix_twitter_bridge_encryption_pickle_key: mautrix.bridge.e2ee +matrix_bridge_mautrix_twitter_bridge_encryption_pickle_key: mautrix.bridge.e2ee -# matrix_mautrix_twitter_restart_necessary controls whether the service +# matrix_bridge_mautrix_twitter_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -228,4 +222,4 @@ matrix_mautrix_twitter_bridge_encryption_pickle_key: mautrix.bridge.e2ee # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_twitter_restart_necessary: false +matrix_bridge_mautrix_twitter_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/converge.yml new file mode 100644 index 000000000..b9dcc1c10 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-twitter Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-twitter Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-twitter is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-twitter systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-twitter.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/molecule.yml new file mode 100644 index 000000000..ccae40854 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/molecule.yml @@ -0,0 +1,99 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-twitter-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_twitter_container_network: mautrix-twitter-molecule + + # The stub prepare.yml starts is not a real homeserver, and the scenario carries + # no Twitter credentials. Logged out is the intended test boundary. + matrix_bridge_mautrix_twitter_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_mautrix_twitter_homeserver_domain: molecule.local + matrix_bridge_mautrix_twitter_homeserver_async_media: true + + # Postgres is the normal deployment path. Non-default names make the resulting + # schema evidence that the role composed and supplied this connection. + matrix_bridge_mautrix_twitter_database_engine: postgres + matrix_bridge_mautrix_twitter_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_twitter_database_name: molecule_twitter + matrix_bridge_mautrix_twitter_database_username: molecule_twitter + matrix_bridge_mautrix_twitter_database_password: molecule_pg_password_a6d239 + + # Test-only fixtures which must reach both config.yaml and registration.yaml. + matrix_bridge_mautrix_twitter_appservice_token: molecule_twitter_as_token_36c8b1 + matrix_bridge_mautrix_twitter_homeserver_token: molecule_twitter_hs_token_f6a142 + + # All differ from role defaults, allowing parsed checks to prove role rendering. + matrix_bridge_mautrix_twitter_appservice_bot_username: molecule-twitterbot + matrix_bridge_mautrix_twitter_appservice_bot_displayname: Molecule Twitter bridge + matrix_bridge_mautrix_twitter_appservice_bot_avatar: mxc://molecule.local/twitter-bot-avatar + matrix_bridge_mautrix_twitter_network_displayname_template: "{% raw %}{{ .Username }} / {{ .DisplayName }} (Molecule){% endraw %}" + matrix_bridge_mautrix_twitter_bridge_command_prefix: "!molecule-twitter" + matrix_bridge_mautrix_twitter_bridge_permissions: + "*": commands + molecule.local: admin + matrix_bridge_mautrix_twitter_matrix_federate_rooms: false + matrix_bridge_mautrix_twitter_backfill_enabled: false + matrix_bridge_mautrix_twitter_backfill_max_initial_messages: 23 + matrix_bridge_mautrix_twitter_backfill_max_catchup_messages: 37 + matrix_bridge_mautrix_twitter_provisioning_shared_secret: molecule_provisioning_secret_725ac8 + matrix_bridge_mautrix_twitter_double_puppet_secrets_custom: + molecule.remote: molecule_double_puppet_secret_e5c0a1 + matrix_bridge_mautrix_twitter_logging_level: info + + # Traefik is not started. These values exercise both the public address the bridge + # consumes and the exposure labels Docker consumes. + matrix_bridge_mautrix_twitter_exposure_enabled: true + matrix_bridge_mautrix_twitter_exposure_hostname: twitter-api.molecule.local + matrix_bridge_mautrix_twitter_exposure_path_prefix: /bridges/twitter-api + matrix_bridge_mautrix_twitter_scheme: http + matrix_bridge_mautrix_twitter_container_labels_traefik_entrypoints: web + matrix_bridge_mautrix_twitter_container_labels_additional_labels: | + molecule.twitter.coverage=enabled + + # verify.yml is a separate play, where role defaults are out of scope. + matrix_bridge_mautrix_twitter_base_path: /matrix/mautrix-twitter + matrix_bridge_mautrix_twitter_config_path: /matrix/mautrix-twitter/config + matrix_bridge_mautrix_twitter_data_path: /matrix/mautrix-twitter/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/prepare.yml new file mode 100644 index 000000000..c2d18a2e8 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/prepare.yml @@ -0,0 +1,87 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-twitter Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role creates this during converge, but both dependencies attach to it first. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_twitter_container_network }}" + register: mautrix_twitter_molecule_network + changed_when: mautrix_twitter_molecule_network.rc == 0 + failed_when: + - mautrix_twitter_molecule_network.rc != 0 + - "'already exists' not in mautrix_twitter_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_twitter_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_twitter_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_twitter_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_twitter_database_password }}" + + # The logged-out bridge still checks its appservice bot identity during startup. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_twitter_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_mautrix_twitter_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_twitter_appservice_bot_username }}:{{ matrix_bridge_mautrix_twitter_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/verify.yml new file mode 100644 index 000000000..9e52c1888 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-twitter/molecule/default/verify.yml @@ -0,0 +1,393 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the logged-out bridge starts, accepts the role-rendered configuration and +# registration, migrates real Postgres, and opens its appservice and provisioning +# APIs. Twitter credentials are deliberately outside the scenario boundary. +- name: Verify mautrix-twitter + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + mautrix_twitter_config: "{{ mautrix_twitter_config_file.content | b64decode | from_yaml }}" + mautrix_twitter_registration: "{{ mautrix_twitter_registration_file.content | b64decode | from_yaml }}" + mautrix_twitter_labels_rendered: "{{ mautrix_twitter_labels_file.content | b64decode }}" + mautrix_twitter_expected_public_address: http://twitter-api.molecule.local/bridges/twitter-api + gather_facts: false + + tasks: + # A Renovate bump changes this source of truth and therefore the image expectation. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_twitter_role_defaults + + - name: Wait for the mautrix-twitter service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-twitter.service + register: mautrix_twitter_service + until: mautrix_twitter_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes ActiveState insufficient for detecting a crash loop. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_twitter_service.status.ActiveState == 'active' + - mautrix_twitter_service.status.NRestarts is defined + - mautrix_twitter_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-twitter.service is + {{ mautrix_twitter_service.status.ActiveState | default('unknown') }} after + {{ mautrix_twitter_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-mautrix-twitter.service is active and has not restarted" + + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_twitter_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-twitter:29327/_matrix/mau/live + register: mautrix_twitter_live + changed_when: false + until: mautrix_twitter_live.rc == 0 and mautrix_twitter_live.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_twitter_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-mautrix-twitter:29327/_matrix/mau/ready + register: mautrix_twitter_ready + changed_when: false + until: mautrix_twitter_ready.rc == 0 and mautrix_twitter_ready.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on the configured appservice port + ansible.builtin.assert: + that: + - mautrix_twitter_live.rc == 0 + - mautrix_twitter_live.stdout == 'HTTP_STATUS=200' + - mautrix_twitter_ready.rc == 0 + - mautrix_twitter_ready.stdout == 'HTTP_STATUS=200' + fail_msg: >- + Health probes returned live={{ mautrix_twitter_live.stdout | default('none') }} + (rc={{ mautrix_twitter_live.rc | default('?') }}) and + ready={{ mautrix_twitter_ready.stdout | default('none') }} + (rc={{ mautrix_twitter_ready.rc | default('?') }}) + success_msg: "The bridge is live and ready on the configured appservice port" + + # This exercises the provisioning middleware and Twitter connector without logging in. + - name: Query the authenticated provisioning login flows + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_twitter_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --fail-with-body + - --header + - "Authorization: Bearer {{ matrix_bridge_mautrix_twitter_provisioning_shared_secret }}" + - "http://matrix-mautrix-twitter:29327/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_twitter_login_flows + changed_when: false + + - name: Query the provisioning API with an invalid secret + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_twitter_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - --header + - "Authorization: Bearer definitely-wrong-molecule-secret" + - "http://matrix-mautrix-twitter:29327/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: mautrix_twitter_login_flows_unauthorized + changed_when: false + failed_when: false + + - name: Assert the live provisioning API enforces auth and advertises login flows + ansible.builtin.assert: + that: + - mautrix_twitter_login_flows.rc == 0 + - (mautrix_twitter_login_flows.stdout | from_json).flows is sequence + - (mautrix_twitter_login_flows.stdout | from_json).flows | length > 0 + - mautrix_twitter_login_flows_unauthorized.rc == 0 + - mautrix_twitter_login_flows_unauthorized.stdout == 'HTTP_STATUS=401' + fail_msg: "The provisioning API did not enforce its secret or return Twitter login flows" + success_msg: "The provisioning API enforces its secret and returns Twitter login flows" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_twitter_config_path }}/config.yaml" + register: mautrix_twitter_config_file + + - name: Assert the rendered configuration carries the appservice identity + ansible.builtin.assert: + that: + - mautrix_twitter_config.homeserver.address == matrix_bridge_mautrix_twitter_homeserver_address + - mautrix_twitter_config.homeserver.domain == matrix_bridge_mautrix_twitter_homeserver_domain + - mautrix_twitter_config.homeserver.async_media + - mautrix_twitter_config.appservice.id == 'twitter' + - mautrix_twitter_config.appservice.address == 'http://matrix-mautrix-twitter:29327' + - mautrix_twitter_config.appservice.public_address == mautrix_twitter_expected_public_address + - mautrix_twitter_config.appservice.bot.username == matrix_bridge_mautrix_twitter_appservice_bot_username + - mautrix_twitter_config.appservice.bot.displayname == matrix_bridge_mautrix_twitter_appservice_bot_displayname + - mautrix_twitter_config.appservice.bot.avatar == matrix_bridge_mautrix_twitter_appservice_bot_avatar + - mautrix_twitter_config.appservice.as_token == matrix_bridge_mautrix_twitter_appservice_token + - mautrix_twitter_config.appservice.hs_token == matrix_bridge_mautrix_twitter_homeserver_token + fail_msg: "The rendered configuration does not carry the scenario's appservice identity" + success_msg: "The rendered configuration carries the scenario's appservice identity" + + - name: Assert the rendered configuration carries non-default Twitter behavior + ansible.builtin.assert: + that: + - mautrix_twitter_config.network.displayname_template == matrix_bridge_mautrix_twitter_network_displayname_template + - mautrix_twitter_config.bridge.command_prefix == matrix_bridge_mautrix_twitter_bridge_command_prefix + - mautrix_twitter_config.bridge.permissions['*'] == 'commands' + - mautrix_twitter_config.bridge.permissions[matrix_bridge_mautrix_twitter_homeserver_domain] == 'admin' + - not mautrix_twitter_config.matrix.federate_rooms + - mautrix_twitter_config.logging.min_level == matrix_bridge_mautrix_twitter_logging_level + fail_msg: "The rendered configuration does not carry the scenario's Twitter behavior" + success_msg: "The rendered configuration carries the scenario's Twitter behavior" + + - name: Assert the rendered configuration carries integration secrets + ansible.builtin.assert: + that: + - mautrix_twitter_config.provisioning.shared_secret == matrix_bridge_mautrix_twitter_provisioning_shared_secret + - mautrix_twitter_config.double_puppet.secrets['molecule.remote'] == 'molecule_double_puppet_secret_e5c0a1' + fail_msg: "The rendered configuration does not carry the scenario's integration secrets" + success_msg: "The rendered configuration carries the scenario's integration secrets" + + - name: Assert the rendered configuration carries the non-default backfill policy + ansible.builtin.assert: + that: + - not mautrix_twitter_config.backfill.enabled + - mautrix_twitter_config.backfill.max_initial_messages == 23 + - mautrix_twitter_config.backfill.max_catchup_messages == 37 + fail_msg: "The rendered configuration does not carry the scenario's backfill policy" + success_msg: "The rendered configuration carries the scenario's backfill policy" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - mautrix_twitter_config.database.type == matrix_bridge_mautrix_twitter_database_engine + - matrix_bridge_mautrix_twitter_database_username in mautrix_twitter_config.database.uri + - matrix_bridge_mautrix_twitter_database_hostname in mautrix_twitter_config.database.uri + - matrix_bridge_mautrix_twitter_database_name in mautrix_twitter_config.database.uri + fail_msg: >- + database.uri is {{ mautrix_twitter_config.database.uri | default('unset') }}, which + was not composed from the scenario's connection settings + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_twitter_config_path }}/registration.yaml" + register: mautrix_twitter_registration_file + + - name: Assert the registration carries the configured handshake values + ansible.builtin.assert: + that: + - mautrix_twitter_registration.id == 'twitter' + - mautrix_twitter_registration.as_token == matrix_bridge_mautrix_twitter_appservice_token + - mautrix_twitter_registration.hs_token == matrix_bridge_mautrix_twitter_homeserver_token + - mautrix_twitter_registration.sender_localpart == '_bot_' + matrix_bridge_mautrix_twitter_appservice_bot_username + - mautrix_twitter_registration.url == 'http://matrix-mautrix-twitter:29327' + - mautrix_twitter_registration['io.element.msc4190'] == false + fail_msg: "The registration does not carry the configured handshake values" + success_msg: "The registration carries the configured handshake values" + + - name: Assert the registration namespaces cover only Twitter ghosts and the bridge bot + ansible.builtin.assert: + that: + - mautrix_twitter_ghost_regex | length > 0 + - mautrix_twitter_bot_regex | length > 0 + - mautrix_twitter_ghost_mxid is match(mautrix_twitter_ghost_regex) + - mautrix_twitter_wrong_ghost_mxid is not match(mautrix_twitter_ghost_regex) + - mautrix_twitter_bot_mxid is match(mautrix_twitter_bot_regex) + fail_msg: "The registration namespaces do not cover only Twitter ghosts and the bot" + success_msg: "The registration namespaces cover only Twitter ghosts and the bot" + vars: + mautrix_twitter_user_regexes: "{{ mautrix_twitter_registration.namespaces.users | map(attribute='regex') | list }}" + mautrix_twitter_ghost_regex: "{{ mautrix_twitter_user_regexes | select('search', 'twitter_') | first | default('') }}" + mautrix_twitter_bot_regex: "{{ mautrix_twitter_user_regexes | reject('search', 'twitter_') | first | default('') }}" + mautrix_twitter_ghost_mxid: "@twitter_123456:{{ matrix_bridge_mautrix_twitter_homeserver_domain }}" + mautrix_twitter_wrong_ghost_mxid: "@linkedin_123456:{{ matrix_bridge_mautrix_twitter_homeserver_domain }}" + mautrix_twitter_bot_mxid: "@{{ matrix_bridge_mautrix_twitter_appservice_bot_username }}:{{ matrix_bridge_mautrix_twitter_homeserver_domain }}" + + # Tables can appear only after hostname resolution, authentication, and real migrations. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_twitter_database_username }} + - --dbname={{ matrix_bridge_mautrix_twitter_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: mautrix_twitter_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - mautrix_twitter_tables.rc == 0 + - "'version' in mautrix_twitter_table_names" + - "'portal' in mautrix_twitter_table_names" + - "'user_login' in mautrix_twitter_table_names" + - "'message' in mautrix_twitter_table_names" + - mautrix_twitter_table_names | length > 10 + fail_msg: >- + The bridge did not migrate its schema into {{ matrix_bridge_mautrix_twitter_database_name }} + (found {{ mautrix_twitter_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the configured database" + vars: + mautrix_twitter_table_names: "{{ mautrix_twitter_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_twitter_base_path }}/labels" + register: mautrix_twitter_labels_file + + - name: Assert the labels route the public endpoint to the appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in mautrix_twitter_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_mautrix_twitter_container_network in mautrix_twitter_labels_rendered" + - "'traefik.http.services.matrix-mautrix-twitter-exposure.loadbalancer.server.port=29327' in mautrix_twitter_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-twitter-exposure.rule=Host(`twitter-api.molecule.local`) && PathPrefix(`/bridges/twitter-api`)' in mautrix_twitter_labels_rendered" + - "'traefik.http.middlewares.matrix-mautrix-twitter-exposure-strip-prefix.stripprefix.prefixes=/bridges/twitter-api' in mautrix_twitter_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-twitter-exposure.entrypoints=web' in mautrix_twitter_labels_rendered" + - "'traefik.http.routers.matrix-mautrix-twitter-exposure.tls=false' in mautrix_twitter_labels_rendered" + - "'molecule.twitter.coverage=enabled' in mautrix_twitter_labels_rendered" + fail_msg: "The rendered labels do not carry the scenario's exposure configuration" + success_msg: "The rendered labels carry the scenario's exposure configuration" + + - name: Inspect the running bridge container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-twitter + register: mautrix_twitter_container_inspect + changed_when: false + + - name: Parse the running bridge container inspection + ansible.builtin.set_fact: + mautrix_twitter_container: "{{ (mautrix_twitter_container_inspect.stdout | from_json) | first }}" + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - mautrix_twitter_container.Config.Image == mautrix_twitter_expected_image + fail_msg: >- + The running container uses {{ mautrix_twitter_container.Config.Image }}, expected + {{ mautrix_twitter_expected_image }} + success_msg: "The running container uses the exact image pinned by the role" + vars: + mautrix_twitter_expected_image: >- + {{ mautrix_twitter_role_defaults.matrix_bridge_mautrix_twitter_container_image_registry_prefix_upstream_default }}mautrix/twitter:{{ mautrix_twitter_role_defaults.matrix_bridge_mautrix_twitter_version }} + + - name: Assert the running container uses the playbook-supplied runtime + ansible.builtin.assert: + that: + - mautrix_twitter_container.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + - mautrix_twitter_container.Config.Cmd == ['/usr/bin/mautrix-twitter', '-c', '/config/config.yaml', '-r', '/config/registration.yaml', '--no-update'] + - mautrix_twitter_container.HostConfig.RestartPolicy.Name == 'no' + - mautrix_twitter_container.HostConfig.AutoRemove + - mautrix_twitter_container.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container does not use the role's exact identity and command" + success_msg: "The running container uses the role's exact identity and command" + + - name: Assert the running container has the intended privilege isolation + ansible.builtin.assert: + that: + - "'ALL' in mautrix_twitter_container.HostConfig.CapDrop" + - not mautrix_twitter_container.HostConfig.Privileged + fail_msg: "The running container does not have the intended privilege isolation" + success_msg: "The running container drops all capabilities and is unprivileged" + + - name: Assert the running container carries the role's exact bind mounts + ansible.builtin.assert: + that: + - mautrix_twitter_config_mount | length > 0 + - mautrix_twitter_config_mount.Source == matrix_bridge_mautrix_twitter_config_path + - not mautrix_twitter_config_mount.RW + - mautrix_twitter_data_mount | length > 0 + - mautrix_twitter_data_mount.Source == matrix_bridge_mautrix_twitter_data_path + - mautrix_twitter_data_mount.RW + - mautrix_twitter_container.Mounts | length == 2 + fail_msg: "The running container does not carry the role's exact config and data mounts" + success_msg: "The running container carries read-only config and writable data mounts" + vars: + mautrix_twitter_config_mount: >- + {{ mautrix_twitter_container.Mounts + | selectattr('Destination', 'equalto', '/config') + | first | default({}) }} + mautrix_twitter_data_mount: >- + {{ mautrix_twitter_container.Mounts + | selectattr('Destination', 'equalto', '/data') + | first | default({}) }} + + - name: Assert the rendered labels are attached to the running container + ansible.builtin.assert: + that: + - mautrix_twitter_container.Config.Labels['traefik.enable'] == 'true' + - mautrix_twitter_container.Config.Labels['traefik.docker.network'] == matrix_bridge_mautrix_twitter_container_network + - mautrix_twitter_container.Config.Labels['traefik.http.services.matrix-mautrix-twitter-exposure.loadbalancer.server.port'] == '29327' + - mautrix_twitter_container.Config.Labels['molecule.twitter.coverage'] == 'enabled' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The running container carries the labels the role rendered" + + - name: Assert the running container has the exact network and port exposure + ansible.builtin.assert: + that: + - mautrix_twitter_container.HostConfig.NetworkMode == matrix_bridge_mautrix_twitter_container_network + - matrix_bridge_mautrix_twitter_container_network in mautrix_twitter_container.NetworkSettings.Networks + - mautrix_twitter_container.NetworkSettings.Networks | length == 1 + - mautrix_twitter_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: >- + The container has unexpected networks or host ports: + networks={{ mautrix_twitter_container.NetworkSettings.Networks.keys() | list }}, + ports={{ mautrix_twitter_container.HostConfig.PortBindings | default({}) }} + success_msg: "The container uses only its dedicated network and publishes no host ports" diff --git a/roles/custom/matrix-bridge-mautrix-twitter/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-twitter/tasks/main.yml index 39aff219b..f88a5f66d 100644 --- a/roles/custom/matrix-bridge-mautrix-twitter/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-twitter/tasks/main.yml @@ -13,15 +13,15 @@ - install-all - install-mautrix-twitter block: - - when: matrix_mautrix_twitter_enabled | bool + - when: matrix_bridge_mautrix_twitter_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_twitter_enabled | bool + - when: matrix_bridge_mautrix_twitter_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mautrix-twitter block: - - when: not matrix_mautrix_twitter_enabled | bool + - when: not matrix_bridge_mautrix_twitter_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-twitter/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-twitter/tasks/setup_install.yml index 6b5b50298..801039d89 100644 --- a/roles/custom/matrix-bridge-mautrix-twitter/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-twitter/tasks/setup_install.yml @@ -11,19 +11,17 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_twitter_migration_requires_restart: false + matrix_bridge_mautrix_twitter_migration_requires_restart: false - name: Ensure Mautrix Twitter image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_twitter_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_twitter_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_twitter_container_image_force_pull }}" - when: matrix_mautrix_twitter_enabled | bool and not matrix_mautrix_twitter_container_image_self_build - register: matrix_mautrix_twitter_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_twitter_container_image }}" + pull: always + when: matrix_bridge_mautrix_twitter_enabled | bool and not matrix_bridge_mautrix_twitter_container_image_self_build + register: matrix_bridge_mautrix_twitter_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_twitter_container_image_pull_result is not failed + until: matrix_bridge_mautrix_twitter_container_image_pull_result is not failed - name: Ensure Mautrix Twitter paths exist ansible.builtin.file: @@ -33,67 +31,77 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_twitter_base_path }}", when: true} - - {path: "{{ matrix_mautrix_twitter_config_path }}", when: true} - - {path: "{{ matrix_mautrix_twitter_data_path }}", when: true} - - {path: "{{ matrix_mautrix_twitter_container_src_files_path }}", when: "{{ matrix_mautrix_twitter_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_twitter_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_twitter_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_twitter_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_twitter_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_twitter_container_image_self_build }}"} when: item.when | bool +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix Twitter repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_twitter_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_twitter_enabled | bool and matrix_bridge_mautrix_twitter_container_image_self_build" + - name: Ensure Mautrix Twitter repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_mautrix_twitter_container_image_self_build_repo }}" - version: "{{ matrix_mautrix_twitter_container_image_self_build_repo_version }}" - dest: "{{ matrix_mautrix_twitter_container_src_files_path }}" + repo: "{{ matrix_bridge_mautrix_twitter_container_image_self_build_repo }}" + version: "{{ matrix_bridge_mautrix_twitter_container_image_self_build_repo_version }}" + dest: "{{ matrix_bridge_mautrix_twitter_container_src_files_path }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_twitter_git_pull_results - when: "matrix_mautrix_twitter_enabled | bool and matrix_mautrix_twitter_container_image_self_build" + register: matrix_bridge_mautrix_twitter_git_pull_results + when: "matrix_bridge_mautrix_twitter_enabled | bool and matrix_bridge_mautrix_twitter_container_image_self_build" - name: Ensure Mautrix Twitter Docker image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_twitter_container_image }}" - source: build - force_source: "{{ matrix_mautrix_twitter_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_twitter_container_src_files_path }}" - pull: true - when: "matrix_mautrix_twitter_enabled | bool and matrix_mautrix_twitter_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_twitter_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_twitter_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_twitter_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_twitter_enabled | bool and matrix_bridge_mautrix_twitter_container_image_self_build | bool" + register: matrix_bridge_mautrix_twitter_container_image_build_result - name: Ensure mautrix-twitter config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_twitter_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_twitter_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_twitter_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_twitter_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_twitter_config_result + register: matrix_bridge_mautrix_twitter_config_result - name: Ensure mautrix-twitter registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_twitter_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_twitter_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_twitter_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_twitter_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_twitter_registration_result + register: matrix_bridge_mautrix_twitter_registration_result - name: Ensure mautrix-twitter support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_twitter_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_twitter_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_mautrix_twitter_support_files_result + register: matrix_bridge_mautrix_twitter_support_files_result - name: Ensure matrix-mautrix-twitter container network is created + when: matrix_bridge_mautrix_twitter_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_twitter_container_network }}" + name: "{{ matrix_bridge_mautrix_twitter_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -102,18 +110,19 @@ src: "{{ role_path }}/templates/systemd/matrix-mautrix-twitter.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-twitter.service" mode: '0644' - register: matrix_mautrix_twitter_systemd_service_result + register: matrix_bridge_mautrix_twitter_systemd_service_result - name: Determine whether matrix-mautrix-twitter needs a restart ansible.builtin.set_fact: - matrix_mautrix_twitter_restart_necessary: >- + matrix_bridge_mautrix_twitter_restart_necessary: >- {{ - matrix_mautrix_twitter_migration_requires_restart | default(false) - or matrix_mautrix_twitter_config_result.changed | default(false) - or matrix_mautrix_twitter_registration_result.changed | default(false) - or matrix_mautrix_twitter_support_files_result.changed | default(false) - or matrix_mautrix_twitter_systemd_service_result.changed | default(false) - or matrix_mautrix_twitter_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_twitter_migration_requires_restart | default(false) + or matrix_bridge_mautrix_twitter_config_result.changed | default(false) + or matrix_bridge_mautrix_twitter_registration_result.changed | default(false) + or matrix_bridge_mautrix_twitter_support_files_result.changed | default(false) + or matrix_bridge_mautrix_twitter_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_twitter_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_twitter_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mautrix-twitter.service restarted, if necessary @@ -121,4 +130,4 @@ name: "matrix-mautrix-twitter.service" state: restarted daemon_reload: true - when: "matrix_mautrix_twitter_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_twitter_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-twitter/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-twitter/tasks/setup_uninstall.yml index be45fe4ac..b2fc07304 100644 --- a/roles/custom/matrix-bridge-mautrix-twitter/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-twitter/tasks/setup_uninstall.yml @@ -9,9 +9,9 @@ - name: Check existence of matrix-mautrix-twitter service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-twitter.service" - register: matrix_mautrix_twitter_service_stat + register: matrix_bridge_mautrix_twitter_service_stat -- when: matrix_mautrix_twitter_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_twitter_service_stat.stat.exists | bool block: - name: Ensure matrix-mautrix-twitter is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mautrix-twitter/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-twitter/tasks/validate_config.yml index f4d1f718c..896650f78 100644 --- a/roles/custom/matrix-bridge-mautrix-twitter/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-twitter/tasks/validate_config.yml @@ -14,20 +14,33 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_twitter_login_shared_secret', 'new': ''} - - {'old': 'matrix_mautrix_twitter_appservice_database', 'new': 'matrix_mautrix_twitter_database_uri'} - - {'old': 'matrix_mautrix_twitter_bridge_login_shared_secret_map', 'new': 'matrix_mautrix_twitter_double_puppet_secrets'} - - {'old': 'matrix_mautrix_twitter_bridge_login_shared_secret_map_auto', 'new': 'matrix_mautrix_twitter_double_puppet_secrets_auto'} - - {'old': 'matrix_mautrix_twitter_bridge_login_shared_secret_map_custom', 'new': 'matrix_mautrix_twitter_double_puppet_secrets_custom'} - - {'old': 'matrix_mautrix_twitter_federate_rooms', 'new': 'matrix_mautrix_twitter_matrix_federate_rooms'} - - {'old': 'matrix_mautrix_twitter_command_prefix', 'new': 'matrix_mautrix_twitter_bridge_command_prefix'} - - {'old': 'matrix_mautrix_twitter_docker_image_name_prefix', 'new': 'matrix_mautrix_twitter_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_twitter_docker_image', 'new': 'matrix_mautrix_twitter_container_image'} - - {'old': 'matrix_mautrix_twitter_docker_image_force_pull', 'new': 'matrix_mautrix_twitter_container_image_force_pull'} - - {'old': 'matrix_mautrix_twitter_docker_image_registry_prefix', 'new': 'matrix_mautrix_twitter_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_twitter_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_twitter_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_twitter_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_twitter_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_twitter_docker_src_files_path', 'new': 'matrix_mautrix_twitter_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_twitter_login_shared_secret', 'new': ''} + - {'old': 'matrix_bridge_mautrix_twitter_appservice_database', 'new': 'matrix_bridge_mautrix_twitter_database_uri'} + - {'old': 'matrix_bridge_mautrix_twitter_bridge_login_shared_secret_map', 'new': 'matrix_bridge_mautrix_twitter_double_puppet_secrets'} + - {'old': 'matrix_bridge_mautrix_twitter_bridge_login_shared_secret_map_auto', 'new': 'matrix_bridge_mautrix_twitter_double_puppet_secrets_auto'} + - {'old': 'matrix_bridge_mautrix_twitter_bridge_login_shared_secret_map_custom', 'new': 'matrix_bridge_mautrix_twitter_double_puppet_secrets_custom'} + - {'old': 'matrix_bridge_mautrix_twitter_federate_rooms', 'new': 'matrix_bridge_mautrix_twitter_matrix_federate_rooms'} + - {'old': 'matrix_bridge_mautrix_twitter_command_prefix', 'new': 'matrix_bridge_mautrix_twitter_bridge_command_prefix'} + - {'old': 'matrix_bridge_mautrix_twitter_docker_image_name_prefix', 'new': 'matrix_bridge_mautrix_twitter_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_twitter_docker_image', 'new': 'matrix_bridge_mautrix_twitter_container_image'} + - {'old': 'matrix_bridge_mautrix_twitter_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_twitter_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_twitter_docker_image_registry_prefix', 'new': 'matrix_bridge_mautrix_twitter_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_twitter_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mautrix_twitter_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mautrix_twitter_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mautrix_twitter_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mautrix_twitter_docker_src_files_path', 'new': 'matrix_bridge_mautrix_twitter_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_twitter_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_mautrix_twitter_metrics_enabled', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_metrics_proxying_enabled', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_metrics_proxying_hostname', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_metrics_proxying_path_prefix', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_container_labels_metrics_enabled', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_container_labels_metrics_traefik_rule', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_container_labels_metrics_traefik_priority', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_container_labels_metrics_traefik_entrypoints', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_container_labels_metrics_traefik_tls', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_container_labels_metrics_traefik_tls_certResolver', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (mautrix-twitter does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_twitter_container_labels_metrics_middleware_basic_auth_users', 'new': ' (mautrix-twitter does not support metrics)'} - name: Fail if required mautrix-twitter settings not defined ansible.builtin.fail: @@ -35,10 +48,8 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_twitter_appservice_token', when: true} - - {'name': 'matrix_mautrix_twitter_homeserver_address', when: true} - - {'name': 'matrix_mautrix_twitter_homeserver_token', when: true} - - {'name': 'matrix_mautrix_twitter_database_hostname', when: "{{ matrix_mautrix_twitter_database_engine == 'postgres' }}"} - - {'name': 'matrix_mautrix_twitter_container_network', when: true} - - {'name': 'matrix_mautrix_twitter_metrics_proxying_hostname', when: "{{ matrix_mautrix_twitter_metrics_proxying_enabled }}"} - - {'name': 'matrix_mautrix_twitter_metrics_proxying_path_prefix', when: "{{ matrix_mautrix_twitter_metrics_proxying_enabled }}"} + - {'name': 'matrix_bridge_mautrix_twitter_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_twitter_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_twitter_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_twitter_database_hostname', when: "{{ matrix_bridge_mautrix_twitter_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_twitter_container_network', when: true} diff --git a/roles/custom/matrix-bridge-mautrix-twitter/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-twitter/templates/config.yaml.j2 index 441f0ad41..1970bb1de 100644 --- a/roles/custom/matrix-bridge-mautrix-twitter/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-twitter/templates/config.yaml.j2 @@ -7,7 +7,7 @@ network: get_proxy_url: null # Displayname template for Twitter users. - displayname_template: {{ matrix_mautrix_twitter_network_displayname_template | to_json }} + displayname_template: {{ matrix_bridge_mautrix_twitter_network_displayname_template | to_json }} # Maximum number of conversations to sync on startup conversation_sync_limit: 20 @@ -16,7 +16,7 @@ network: # Config options that affect the central bridge module. bridge: # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_mautrix_twitter_bridge_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_mautrix_twitter_bridge_command_prefix | to_json }} # Should the bridge create a space for each login containing the rooms that account is in? personal_filtering_spaces: true # Whether the bridge should set names and avatars explicitly for DM portals. @@ -117,7 +117,7 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_twitter_bridge_permissions | to_json }} + permissions: {{ matrix_bridge_mautrix_twitter_bridge_permissions | to_json }} # Config for the bridge's database. database: @@ -128,7 +128,7 @@ database: # https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_mautrix_twitter_database_uri | to_json }} + uri: {{ matrix_bridge_mautrix_twitter_database_uri | to_json }} # Maximum number of connections. max_open_conns: 5 max_idle_conns: 1 @@ -142,9 +142,9 @@ homeserver: # The address that this appservice can use to connect to the homeserver. # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, # but https also works if they run on different machines. - address: {{ matrix_mautrix_twitter_homeserver_address | to_json }} + address: {{ matrix_bridge_mautrix_twitter_homeserver_address | to_json }} # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: {{ matrix_mautrix_twitter_homeserver_domain | to_json }} + domain: {{ matrix_bridge_mautrix_twitter_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -160,7 +160,7 @@ homeserver: # The bridge will use the appservice as_token to authorize requests. message_send_checkpoint_endpoint: # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_mautrix_twitter_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_mautrix_twitter_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -176,11 +176,11 @@ appservice: # Like the homeserver address, a local non-https address is recommended when the bridge is on the same machine. # If the bridge is elsewhere, you must secure the connection yourself (e.g. with https or wireguard) # If you want to use https, you need to use a reverse proxy. The bridge does not have TLS support built in. - address: {{ matrix_mautrix_twitter_appservice_address | to_json }} + address: {{ matrix_bridge_mautrix_twitter_appservice_address | to_json }} # A public address that external services can use to reach this appservice. # This is only needed for things like public media. A reverse proxy is generally necessary when using this field. # This value doesn't affect the registration file. - public_address: {{ matrix_mautrix_twitter_appservice_public_address | to_json }} + public_address: {{ matrix_bridge_mautrix_twitter_appservice_public_address | to_json }} # The hostname and port where this appservice should listen. # For Docker, you generally have to change the hostname to 0.0.0.0. @@ -192,11 +192,11 @@ appservice: # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_mautrix_twitter_appservice_bot_username | to_json }} + username: {{ matrix_bridge_mautrix_twitter_appservice_bot_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. - displayname: {{ matrix_mautrix_twitter_appservice_bot_displayname | to_json(ensure_ascii=False) }} - avatar: {{ matrix_mautrix_twitter_appservice_bot_avatar | to_json }} + displayname: {{ matrix_bridge_mautrix_twitter_appservice_bot_displayname | to_json(ensure_ascii=False) }} + avatar: {{ matrix_bridge_mautrix_twitter_appservice_bot_avatar | to_json }} # Whether to receive ephemeral events via appservice transactions. ephemeral_events: true @@ -207,8 +207,8 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_mautrix_twitter_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_twitter_homeserver_token | to_json }} + as_token: {{ matrix_bridge_mautrix_twitter_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_twitter_homeserver_token | to_json }} # Localpart template of MXIDs for remote users. # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. @@ -226,7 +226,7 @@ matrix: sync_direct_chat_list: true # Whether created rooms should have federation enabled. If false, created portal rooms # will never be federated. Changing this option requires recreating rooms. - federate_rooms: {{ matrix_mautrix_twitter_matrix_federate_rooms | to_json }} + federate_rooms: {{ matrix_bridge_mautrix_twitter_matrix_federate_rooms | to_json }} # The threshold as bytes after which the bridge should roundtrip uploads via the disk # rather than keeping the whole file in memory. upload_file_threshold: 5242880 @@ -246,7 +246,7 @@ provisioning: prefix: /_matrix/provision # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, # or if set to "disable", the provisioning API will be disabled. - shared_secret: {{ matrix_mautrix_twitter_provisioning_shared_secret | to_json }} + shared_secret: {{ matrix_bridge_mautrix_twitter_provisioning_shared_secret | to_json }} # Whether to allow provisioning API requests to be authed using Matrix access tokens. # This follows the same rules as double puppeting to determine which server to contact to check the token, # which means that by default, it only works for users on the same server as the bridge. @@ -296,11 +296,11 @@ direct_media: # See https://docs.mau.fi/bridges/general/backfill.html for more details. backfill: # Whether to do backfilling at all. - enabled: {{ matrix_mautrix_twitter_backfill_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_twitter_backfill_enabled | to_json }} # Maximum number of messages to backfill in empty rooms. - max_initial_messages: {{ matrix_mautrix_twitter_backfill_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_mautrix_twitter_backfill_max_initial_messages | to_json }} # Maximum number of missed messages to backfill after bridge restarts. - max_catchup_messages: {{ matrix_mautrix_twitter_backfill_max_catchup_messages | to_json }} + max_catchup_messages: {{ matrix_bridge_mautrix_twitter_backfill_max_catchup_messages | to_json }} # If a backfilled chat is older than this number of hours, # mark it as read even if it's unread on the remote network. unread_hours_threshold: 720 @@ -335,35 +335,35 @@ double_puppet: allow_discovery: false # Shared secrets for automatic double puppeting. # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. - secrets: {{ matrix_mautrix_twitter_double_puppet_secrets | to_json }} + secrets: {{ matrix_bridge_mautrix_twitter_double_puppet_secrets | to_json }} # End-to-bridge encryption support options. # # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. - allow: {{ matrix_mautrix_twitter_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_mautrix_twitter_bridge_encryption_allow | to_json }} # Whether to force-enable encryption in all bridged rooms. - default: {{ matrix_mautrix_twitter_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_mautrix_twitter_bridge_encryption_default | to_json }} # Whether to require all messages to be encrypted and drop any unencrypted messages. - require: {{ matrix_mautrix_twitter_bridge_encryption_require | to_json }} + require: {{ matrix_bridge_mautrix_twitter_bridge_encryption_require | to_json }} # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. # This option is not yet compatible with standard Matrix servers like Synapse and should not be used. - appservice: {{ matrix_mautrix_twitter_bridge_encryption_appservice | to_json }} + appservice: {{ matrix_bridge_mautrix_twitter_bridge_encryption_appservice | to_json }} # Whether to use MSC4190 instead of appservice login to create the bridge bot device. # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_mautrix_twitter_msc4190_enabled | to_json }} + msc4190: {{ matrix_bridge_mautrix_twitter_msc4190_enabled | to_json }} # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) # Requires msc4190 to replace keys on reset - self_sign: {{ matrix_mautrix_twitter_self_sign_enabled | to_json }} + self_sign: {{ matrix_bridge_mautrix_twitter_self_sign_enabled | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_mautrix_twitter_bridge_encryption_key_sharing_allow | to_json }} + allow_key_sharing: {{ matrix_bridge_mautrix_twitter_bridge_encryption_key_sharing_allow | to_json }} # Pickle key for encrypting encryption keys in the bridge database. # If set to generate, a random key will be generated. - pickle_key: {{ matrix_mautrix_twitter_bridge_encryption_pickle_key | to_json }} + pickle_key: {{ matrix_bridge_mautrix_twitter_bridge_encryption_pickle_key | to_json }} # Options for deleting megolm sessions from the bridge. delete_keys: # Beeper-specific: delete outbound sessions when hungryserv confirms @@ -422,7 +422,7 @@ encryption: # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_mautrix_twitter_logging_level | to_json }} + min_level: {{ matrix_bridge_mautrix_twitter_logging_level | to_json }} writers: - type: stdout format: pretty-colored diff --git a/roles/custom/matrix-bridge-mautrix-twitter/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-twitter/templates/labels.j2 index fbf530be4..3cc1703bc 100644 --- a/roles/custom/matrix-bridge-mautrix-twitter/templates/labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-twitter/templates/labels.j2 @@ -4,44 +4,42 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_twitter_container_labels_traefik_enabled %} +{% if matrix_bridge_mautrix_twitter_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_mautrix_twitter_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_twitter_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_twitter_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_twitter_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.matrix-mautrix-twitter-metrics.loadbalancer.server.port=8000 - -{% if matrix_mautrix_twitter_container_labels_metrics_enabled %} +{% if matrix_bridge_mautrix_twitter_container_labels_exposure_enabled %} ############################################################ # # -# Metrics # +# Bridge API exposure # # # ############################################################ -{% if matrix_mautrix_twitter_container_labels_metrics_middleware_basic_auth_enabled %} -traefik.http.middlewares.matrix-mautrix-twitter-metrics-basic-auth.basicauth.users={{ matrix_mautrix_twitter_container_labels_metrics_middleware_basic_auth_users }} -traefik.http.routers.matrix-mautrix-twitter-metrics.middlewares=matrix-mautrix-twitter-metrics-basic-auth -{% endif %} +traefik.http.services.matrix-mautrix-twitter-exposure.loadbalancer.server.port=29327 + +traefik.http.middlewares.matrix-mautrix-twitter-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_twitter_exposure_path_prefix }} +traefik.http.routers.matrix-mautrix-twitter-exposure.middlewares=matrix-mautrix-twitter-exposure-strip-prefix -traefik.http.routers.matrix-mautrix-twitter-metrics.rule={{ matrix_mautrix_twitter_container_labels_metrics_traefik_rule }} +traefik.http.routers.matrix-mautrix-twitter-exposure.rule={{ matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_rule }} -{% if matrix_mautrix_twitter_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-twitter-metrics.priority={{ matrix_mautrix_twitter_container_labels_metrics_traefik_priority }} +{% if matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-twitter-exposure.priority={{ matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_priority }} {% endif %} -traefik.http.routers.matrix-mautrix-twitter-metrics.service=matrix-mautrix-twitter-metrics -traefik.http.routers.matrix-mautrix-twitter-metrics.entrypoints={{ matrix_mautrix_twitter_container_labels_metrics_traefik_entrypoints }} +traefik.http.routers.matrix-mautrix-twitter-exposure.service=matrix-mautrix-twitter-exposure +traefik.http.routers.matrix-mautrix-twitter-exposure.entrypoints={{ matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_entrypoints }} -traefik.http.routers.matrix-mautrix-twitter-metrics.tls={{ matrix_mautrix_twitter_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_mautrix_twitter_container_labels_metrics_traefik_tls %} -traefik.http.routers.matrix-mautrix-twitter-metrics.tls.certResolver={{ matrix_mautrix_twitter_container_labels_metrics_traefik_tls_certResolver }} +traefik.http.routers.matrix-mautrix-twitter-exposure.tls={{ matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-mautrix-twitter-exposure.tls.certResolver={{ matrix_bridge_mautrix_twitter_container_labels_exposure_traefik_tls_certResolver }} {% endif %} ############################################################ # # -# /Metrics # +# /Bridge API exposure # # # ############################################################ {% endif %} @@ -49,4 +47,4 @@ traefik.http.routers.matrix-mautrix-twitter-metrics.tls.certResolver={{ matrix_m {% endif %} -{{ matrix_mautrix_twitter_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_twitter_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-twitter/templates/systemd/matrix-mautrix-twitter.service.j2 b/roles/custom/matrix-bridge-mautrix-twitter/templates/systemd/matrix-mautrix-twitter.service.j2 index c1ef8dc81..585e5023c 100644 --- a/roles/custom/matrix-bridge-mautrix-twitter/templates/systemd/matrix-mautrix-twitter.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-twitter/templates/systemd/matrix-mautrix-twitter.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix Twitter bridge -{% for service in matrix_mautrix_twitter_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_twitter_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_twitter_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_twitter_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,19 +22,21 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_twitter_container_network }} \ - --mount type=bind,src={{ matrix_mautrix_twitter_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_mautrix_twitter_data_path }},dst=/data \ - --label-file={{ matrix_mautrix_twitter_base_path }}/labels \ - {% for arg in matrix_mautrix_twitter_container_extra_arguments %} + --network={{ matrix_bridge_mautrix_twitter_container_network }} \ + --mount type=bind,src={{ matrix_bridge_mautrix_twitter_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_mautrix_twitter_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_twitter_base_path }}/labels \ + {% for arg in matrix_bridge_mautrix_twitter_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_twitter_container_image }} \ + {{ matrix_bridge_mautrix_twitter_container_image }} \ /usr/bin/mautrix-twitter -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_mautrix_twitter_container_additional_networks %} +{% if matrix_bridge_mautrix_twitter_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_twitter_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-twitter {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-twitter diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/defaults/main.yml index 01c23bf36..187b8e54b 100644 --- a/roles/custom/matrix-bridge-mautrix-whatsapp/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/defaults/main.yml @@ -21,233 +21,228 @@ # mautrix-whatsapp is a Matrix <-> Whatsapp bridge # Project source code URL: https://github.com/mautrix/whatsapp -matrix_mautrix_whatsapp_enabled: true +matrix_bridge_mautrix_whatsapp_enabled: true -matrix_mautrix_whatsapp_container_image_self_build: false -matrix_mautrix_whatsapp_container_image_self_build_repo: "https://mau.dev/mautrix/whatsapp.git" -matrix_mautrix_whatsapp_container_image_self_build_branch: "{{ 'master' if matrix_mautrix_whatsapp_version == 'latest' else matrix_mautrix_whatsapp_version }}" +matrix_bridge_mautrix_whatsapp_container_image_self_build: false +matrix_bridge_mautrix_whatsapp_container_image_self_build_repo: "https://mau.dev/mautrix/whatsapp.git" +matrix_bridge_mautrix_whatsapp_container_image_self_build_branch: "{{ 'master' if matrix_bridge_mautrix_whatsapp_version == 'latest' else matrix_bridge_mautrix_whatsapp_version }}" # renovate: datasource=docker depName=dock.mau.dev/mautrix/whatsapp -matrix_mautrix_whatsapp_version: v0.2603.0 +matrix_bridge_mautrix_whatsapp_version: v0.2608.0 # See: https://mau.dev/mautrix/whatsapp/container_registry -matrix_mautrix_whatsapp_container_image: "{{ matrix_mautrix_whatsapp_container_image_registry_prefix }}mautrix/whatsapp:{{ matrix_mautrix_whatsapp_version }}" -matrix_mautrix_whatsapp_container_image_registry_prefix: "{{ 'localhost/' if matrix_mautrix_whatsapp_container_image_self_build else matrix_mautrix_whatsapp_container_image_registry_prefix_upstream }}" -matrix_mautrix_whatsapp_container_image_registry_prefix_upstream: "{{ matrix_mautrix_whatsapp_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_whatsapp_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_whatsapp_container_image_force_pull: "{{ matrix_mautrix_whatsapp_container_image.endswith(':latest') }}" - -matrix_mautrix_whatsapp_base_path: "{{ matrix_base_data_path }}/mautrix-whatsapp" -matrix_mautrix_whatsapp_config_path: "{{ matrix_mautrix_whatsapp_base_path }}/config" -matrix_mautrix_whatsapp_data_path: "{{ matrix_mautrix_whatsapp_base_path }}/data" -matrix_mautrix_whatsapp_container_src_files_path: "{{ matrix_mautrix_whatsapp_base_path }}/docker-src" - -matrix_mautrix_whatsapp_homeserver_address: "" -matrix_mautrix_whatsapp_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_mautrix_whatsapp_container_image: "{{ matrix_bridge_mautrix_whatsapp_container_image_registry_prefix }}mautrix/whatsapp:{{ matrix_bridge_mautrix_whatsapp_version }}" +matrix_bridge_mautrix_whatsapp_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mautrix_whatsapp_container_image_self_build else matrix_bridge_mautrix_whatsapp_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_whatsapp_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_whatsapp_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_whatsapp_container_image_registry_prefix_upstream_default: "dock.mau.dev/" + +matrix_bridge_mautrix_whatsapp_base_path: "{{ matrix_base_data_path }}/mautrix-whatsapp" +matrix_bridge_mautrix_whatsapp_config_path: "{{ matrix_bridge_mautrix_whatsapp_base_path }}/config" +matrix_bridge_mautrix_whatsapp_data_path: "{{ matrix_bridge_mautrix_whatsapp_base_path }}/data" +matrix_bridge_mautrix_whatsapp_container_src_files_path: "{{ matrix_bridge_mautrix_whatsapp_base_path }}/docker-src" + +matrix_bridge_mautrix_whatsapp_homeserver_address: "" +matrix_bridge_mautrix_whatsapp_homeserver_domain: "{{ matrix_domain }}" # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_mautrix_whatsapp_homeserver_async_media: false -matrix_mautrix_whatsapp_appservice_address: "http://matrix-mautrix-whatsapp:8080" +matrix_bridge_mautrix_whatsapp_homeserver_async_media: false +matrix_bridge_mautrix_whatsapp_appservice_address: "http://matrix-mautrix-whatsapp:8080" -matrix_mautrix_whatsapp_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" -matrix_mautrix_whatsapp_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" +# Scheme of the bridge's public address (see `matrix_bridge_mautrix_whatsapp_bridge_public_address`). +matrix_bridge_mautrix_whatsapp_scheme: https -matrix_mautrix_whatsapp_extev_polls: false +# The public base URL at which this bridge's HTTP API is reachable from outside (when exposed). +# Used for the provisioning API's external-server (OpenID) flow and for public media links. +matrix_bridge_mautrix_whatsapp_bridge_public_address: "{{ (matrix_bridge_mautrix_whatsapp_scheme + '://' + matrix_bridge_mautrix_whatsapp_exposure_hostname + matrix_bridge_mautrix_whatsapp_exposure_path_prefix) if matrix_bridge_mautrix_whatsapp_exposure_enabled else '' }}" -matrix_mautrix_whatsapp_command_prefix: "!wa" +matrix_bridge_mautrix_whatsapp_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_mautrix_whatsapp_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" -matrix_mautrix_whatsapp_container_network: "" +matrix_bridge_mautrix_whatsapp_extev_polls: false -matrix_mautrix_whatsapp_container_additional_networks: "{{ matrix_mautrix_whatsapp_container_additional_networks_auto + matrix_mautrix_whatsapp_container_additional_networks_custom }}" -matrix_mautrix_whatsapp_container_additional_networks_auto: [] -matrix_mautrix_whatsapp_container_additional_networks_custom: [] +matrix_bridge_mautrix_whatsapp_command_prefix: "!wa" -# matrix_mautrix_whatsapp_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +matrix_bridge_mautrix_whatsapp_container_network: "" + +matrix_bridge_mautrix_whatsapp_container_additional_networks: "{{ matrix_bridge_mautrix_whatsapp_container_additional_networks_auto + matrix_bridge_mautrix_whatsapp_container_additional_networks_custom }}" +matrix_bridge_mautrix_whatsapp_container_additional_networks_auto: [] +matrix_bridge_mautrix_whatsapp_container_additional_networks_custom: [] + +# matrix_bridge_mautrix_whatsapp_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_whatsapp_container_labels_additional_labels`. -matrix_mautrix_whatsapp_container_labels_traefik_enabled: true -matrix_mautrix_whatsapp_container_labels_traefik_docker_network: "{{ matrix_mautrix_whatsapp_container_network }}" -matrix_mautrix_whatsapp_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_whatsapp_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose mautrix-whatsapp's metrics -matrix_mautrix_whatsapp_container_labels_metrics_enabled: "{{ matrix_mautrix_whatsapp_metrics_enabled and matrix_mautrix_whatsapp_metrics_proxying_enabled }}" -matrix_mautrix_whatsapp_container_labels_metrics_traefik_rule: "Host(`{{ matrix_mautrix_whatsapp_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_mautrix_whatsapp_metrics_proxying_path_prefix }}`)" -matrix_mautrix_whatsapp_container_labels_metrics_traefik_priority: 0 -matrix_mautrix_whatsapp_container_labels_metrics_traefik_entrypoints: "{{ matrix_mautrix_whatsapp_container_labels_traefik_entrypoints }}" -matrix_mautrix_whatsapp_container_labels_metrics_traefik_tls: "{{ matrix_mautrix_whatsapp_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_mautrix_whatsapp_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_mautrix_whatsapp_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_mautrix_whatsapp_container_labels_metrics_middleware_basic_auth_enabled: false -# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_mautrix_whatsapp_container_labels_metrics_middleware_basic_auth_users: '' - -# matrix_mautrix_whatsapp_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# To inject your own other container labels, see `matrix_bridge_mautrix_whatsapp_container_labels_additional_labels`. +matrix_bridge_mautrix_whatsapp_container_labels_traefik_enabled: true +matrix_bridge_mautrix_whatsapp_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_whatsapp_container_network }}" +matrix_bridge_mautrix_whatsapp_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_whatsapp_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose mautrix-whatsapp's HTTP API +# (used by tools like mautrix-manager for bridge login) at `https://`. +matrix_bridge_mautrix_whatsapp_container_labels_exposure_enabled: "{{ matrix_bridge_mautrix_whatsapp_exposure_enabled }}" +matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_mautrix_whatsapp_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_mautrix_whatsapp_exposure_path_prefix }}`)" +matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_priority: 0 +matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_mautrix_whatsapp_container_labels_traefik_entrypoints }}" +matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_tls: "{{ matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_mautrix_whatsapp_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_mautrix_whatsapp_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_whatsapp_container_labels_additional_labels: | +# matrix_bridge_mautrix_whatsapp_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_whatsapp_container_labels_additional_labels: '' +matrix_bridge_mautrix_whatsapp_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_whatsapp_container_extra_arguments: [] +matrix_bridge_mautrix_whatsapp_container_extra_arguments: [] # List of systemd services that matrix-mautrix-whatsapp.service depends on. -matrix_mautrix_whatsapp_systemd_required_services_list: "{{ matrix_mautrix_whatsapp_systemd_required_services_list_default + matrix_mautrix_whatsapp_systemd_required_services_list_auto + matrix_mautrix_whatsapp_systemd_required_services_list_custom }}" -matrix_mautrix_whatsapp_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_whatsapp_systemd_required_services_list_auto: [] -matrix_mautrix_whatsapp_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_whatsapp_systemd_required_services_list: "{{ matrix_bridge_mautrix_whatsapp_systemd_required_services_list_default + matrix_bridge_mautrix_whatsapp_systemd_required_services_list_auto + matrix_bridge_mautrix_whatsapp_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_whatsapp_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_whatsapp_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_whatsapp_systemd_required_services_list_custom: [] # List of systemd services that matrix-mautrix-whatsapp.service wants -matrix_mautrix_whatsapp_systemd_wanted_services_list: [] +matrix_bridge_mautrix_whatsapp_systemd_wanted_services_list: [] -matrix_mautrix_whatsapp_appservice_token: '' -matrix_mautrix_whatsapp_homeserver_token: '' +matrix_bridge_mautrix_whatsapp_appservice_token: '' +matrix_bridge_mautrix_whatsapp_homeserver_token: '' -matrix_mautrix_whatsapp_appservice_bot_username: whatsappbot +matrix_bridge_mautrix_whatsapp_appservice_bot_username: whatsappbot # Minimum severity of journal log messages. # Valid values: fatal, error, warn, info, debug, trace -matrix_mautrix_whatsapp_logging_level: 'warn' +matrix_bridge_mautrix_whatsapp_logging_level: 'warn' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_mautrix_whatsapp_federate_rooms: true - -# Whether or not metrics endpoint should be enabled. -# Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_mautrix_whatsapp_metrics_proxying_enabled`. -matrix_mautrix_whatsapp_metrics_enabled: false +matrix_bridge_mautrix_whatsapp_federate_rooms: true -# Controls whether metrics should be proxied (exposed) on a public URL -matrix_mautrix_whatsapp_metrics_proxying_enabled: false -matrix_mautrix_whatsapp_metrics_proxying_hostname: '' -matrix_mautrix_whatsapp_metrics_proxying_path_prefix: '' +# Controls whether mautrix-whatsapp's HTTP API is exposed publicly (used by tools like mautrix-manager for bridge login). +matrix_bridge_mautrix_whatsapp_exposure_enabled: false +matrix_bridge_mautrix_whatsapp_exposure_hostname: '' +matrix_bridge_mautrix_whatsapp_exposure_path_prefix: '' # Database-related configuration fields. # # To use SQLite, stick to these defaults. # # To use Postgres: -# - change the engine (`matrix_mautrix_whatsapp_database_engine: 'postgres'`) -# - adjust your database credentials via the `matrix_mautrix_whatsapp_database_*` variables -matrix_mautrix_whatsapp_database_engine: 'sqlite' - -matrix_mautrix_whatsapp_sqlite_database_path_local: "{{ matrix_mautrix_whatsapp_data_path }}/mautrix-whatsapp.db" -matrix_mautrix_whatsapp_sqlite_database_path_in_container: "/data/mautrix-whatsapp.db" - -matrix_mautrix_whatsapp_database_username: 'matrix_mautrix_whatsapp' -matrix_mautrix_whatsapp_database_password: 'some-password' -matrix_mautrix_whatsapp_database_hostname: '' -matrix_mautrix_whatsapp_database_port: 5432 -matrix_mautrix_whatsapp_database_name: 'matrix_mautrix_whatsapp' -matrix_mautrix_whatsapp_database_sslmode: disable - -matrix_mautrix_whatsapp_database_connection_string: 'postgresql://{{ matrix_mautrix_whatsapp_database_username }}:{{ matrix_mautrix_whatsapp_database_password }}@{{ matrix_mautrix_whatsapp_database_hostname }}:{{ matrix_mautrix_whatsapp_database_port }}/{{ matrix_mautrix_whatsapp_database_name }}?sslmode={{ matrix_mautrix_whatsapp_database_sslmode }}' - -matrix_mautrix_whatsapp_appservice_database_type: "{{ - { - 'sqlite': 'sqlite3-fk-wal', - 'postgres':'postgres', - }[matrix_mautrix_whatsapp_database_engine] -}}" - -matrix_mautrix_whatsapp_appservice_database_uri: "{{ - { - 'sqlite': matrix_mautrix_whatsapp_sqlite_database_path_in_container, - 'postgres': matrix_mautrix_whatsapp_database_connection_string, - }[matrix_mautrix_whatsapp_database_engine] -}}" - -matrix_mautrix_whatsapp_double_puppet_secrets: "{{ matrix_mautrix_whatsapp_double_puppet_secrets_auto | combine(matrix_mautrix_whatsapp_double_puppet_secrets_custom) }}" -matrix_mautrix_whatsapp_double_puppet_secrets_auto: {} -matrix_mautrix_whatsapp_double_puppet_secrets_custom: {} +# - change the engine (`matrix_bridge_mautrix_whatsapp_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_mautrix_whatsapp_database_*` variables +matrix_bridge_mautrix_whatsapp_database_engine: 'sqlite' + +matrix_bridge_mautrix_whatsapp_sqlite_database_path_local: "{{ matrix_bridge_mautrix_whatsapp_data_path }}/mautrix-whatsapp.db" +matrix_bridge_mautrix_whatsapp_sqlite_database_path_in_container: "/data/mautrix-whatsapp.db" + +matrix_bridge_mautrix_whatsapp_database_username: 'matrix_mautrix_whatsapp' +matrix_bridge_mautrix_whatsapp_database_password: 'some-password' +matrix_bridge_mautrix_whatsapp_database_hostname: '' +matrix_bridge_mautrix_whatsapp_database_port: 5432 +matrix_bridge_mautrix_whatsapp_database_name: 'matrix_mautrix_whatsapp' +matrix_bridge_mautrix_whatsapp_database_sslmode: disable + +matrix_bridge_mautrix_whatsapp_database_connection_string: 'postgresql://{{ matrix_bridge_mautrix_whatsapp_database_username }}:{{ matrix_bridge_mautrix_whatsapp_database_password }}@{{ matrix_bridge_mautrix_whatsapp_database_hostname }}:{{ matrix_bridge_mautrix_whatsapp_database_port }}/{{ matrix_bridge_mautrix_whatsapp_database_name }}?sslmode={{ matrix_bridge_mautrix_whatsapp_database_sslmode }}' + +matrix_bridge_mautrix_whatsapp_appservice_database_type: "{{ { + 'sqlite': 'sqlite3-fk-wal', + 'postgres': 'postgres', +}[matrix_bridge_mautrix_whatsapp_database_engine] }}" + +matrix_bridge_mautrix_whatsapp_appservice_database_uri: "{{ { + 'sqlite': matrix_bridge_mautrix_whatsapp_sqlite_database_path_in_container, + 'postgres': matrix_bridge_mautrix_whatsapp_database_connection_string, +}[matrix_bridge_mautrix_whatsapp_database_engine] }}" + +matrix_bridge_mautrix_whatsapp_double_puppet_secrets: "{{ matrix_bridge_mautrix_whatsapp_double_puppet_secrets_auto | combine(matrix_bridge_mautrix_whatsapp_double_puppet_secrets_custom) }}" +matrix_bridge_mautrix_whatsapp_double_puppet_secrets_auto: {} +matrix_bridge_mautrix_whatsapp_double_puppet_secrets_custom: {} # Displayname template for WhatsApp users. # {{.PushName}} - nickname set by the WhatsApp user # {{.BusinessName}} - validated WhatsApp business name # {{.Phone}} - phone number (international format) # {{.FullName}} - Name you set in the contacts list -matrix_mautrix_whatsapp_network_displayname_template: '{% raw %}{{or .BusinessName .PushName .Phone}} (WA){% endraw %}' +matrix_bridge_mautrix_whatsapp_network_displayname_template: '{% raw %}{{or .BusinessName .PushName .Phone}} (WA){% endraw %}' # Enable End-to-bridge encryption -matrix_mautrix_whatsapp_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_mautrix_whatsapp_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_mautrix_whatsapp_bridge_encryption_require: false -matrix_mautrix_whatsapp_bridge_encryption_key_sharing_allow: "{{ matrix_mautrix_whatsapp_bridge_encryption_allow }}" +matrix_bridge_mautrix_whatsapp_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_mautrix_whatsapp_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_mautrix_whatsapp_bridge_encryption_require: false +matrix_bridge_mautrix_whatsapp_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_mautrix_whatsapp_bridge_encryption_allow }}" # This pickle key value is backward-compatible with the old bridge. # See: https://github.com/mautrix/whatsapp/blob/v0.11.0/cmd/mautrix-whatsapp/legacymigrate.go#L44 -matrix_mautrix_whatsapp_bridge_encryption_pickle_key: maunium.net/go/mautrix-whatsapp +matrix_bridge_mautrix_whatsapp_bridge_encryption_pickle_key: maunium.net/go/mautrix-whatsapp -matrix_mautrix_whatsapp_bridge_personal_filtering_spaces: true -matrix_mautrix_whatsapp_bridge_enable_status_broadcast: true +matrix_bridge_mautrix_whatsapp_bridge_personal_filtering_spaces: true +matrix_bridge_mautrix_whatsapp_bridge_enable_status_broadcast: true -matrix_mautrix_whatsapp_provisioning_shared_secret: '' -matrix_mautrix_whatsapp_public_media_signing_key: '' +matrix_bridge_mautrix_whatsapp_provisioning_shared_secret: '' +matrix_bridge_mautrix_whatsapp_public_media_signing_key: '' -matrix_mautrix_whatsapp_bridge_permissions: | +matrix_bridge_mautrix_whatsapp_bridge_permissions: | {{ - {'*': 'relay', matrix_mautrix_whatsapp_homeserver_domain: 'user'} + {'*': 'relay', matrix_bridge_mautrix_whatsapp_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} # Enable bridge relay functionality -matrix_mautrix_whatsapp_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" +matrix_bridge_mautrix_whatsapp_bridge_relay_enabled: "{{ matrix_bridges_relay_enabled }}" # Only allow admins on this home server to set themselves as a relay user -matrix_mautrix_whatsapp_bridge_relay_admin_only: true +matrix_bridge_mautrix_whatsapp_bridge_relay_admin_only: true # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. -matrix_mautrix_whatsapp_bridge_relay_default_relays: [] +matrix_bridge_mautrix_whatsapp_bridge_relay_default_relays: [] # Controls whether to do backfilling at all. -matrix_mautrix_whatsapp_backfill_enabled: true +matrix_bridge_mautrix_whatsapp_backfill_enabled: true # Default mautrix-whatsapp configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_whatsapp_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_whatsapp_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_whatsapp_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_whatsapp_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_whatsapp_configuration_extension_yaml: | +matrix_bridge_mautrix_whatsapp_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_whatsapp_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_whatsapp_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_whatsapp_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_whatsapp_configuration_yaml`. -matrix_mautrix_whatsapp_configuration_extension: "{{ matrix_mautrix_whatsapp_configuration_extension_yaml | from_yaml if matrix_mautrix_whatsapp_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_whatsapp_configuration_extension: "{{ matrix_bridge_mautrix_whatsapp_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_whatsapp_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_whatsapp_configuration_yaml`. -matrix_mautrix_whatsapp_configuration: "{{ matrix_mautrix_whatsapp_configuration_yaml | from_yaml | combine(matrix_mautrix_whatsapp_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_whatsapp_configuration_yaml`. +matrix_bridge_mautrix_whatsapp_configuration: "{{ matrix_bridge_mautrix_whatsapp_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_whatsapp_configuration_extension, recursive=True) }}" -matrix_mautrix_whatsapp_registration_yaml: | +matrix_bridge_mautrix_whatsapp_registration_yaml: | id: whatsapp - url: {{ matrix_mautrix_whatsapp_appservice_address }} - as_token: "{{ matrix_mautrix_whatsapp_appservice_token }}" - hs_token: "{{ matrix_mautrix_whatsapp_homeserver_token }}" + url: {{ matrix_bridge_mautrix_whatsapp_appservice_address }} + as_token: "{{ matrix_bridge_mautrix_whatsapp_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_whatsapp_homeserver_token }}" # See https://github.com/mautrix/signal/issues/43 - sender_localpart: _bot_{{ matrix_mautrix_whatsapp_appservice_bot_username }} + sender_localpart: _bot_{{ matrix_bridge_mautrix_whatsapp_appservice_bot_username }} rate_limited: false namespaces: users: - - regex: '^@whatsapp_.*:{{ matrix_mautrix_whatsapp_homeserver_domain | regex_escape }}$' + - regex: '^@whatsapp_.*:{{ matrix_bridge_mautrix_whatsapp_homeserver_domain | regex_escape }}$' exclusive: true - exclusive: true - regex: '^@{{ matrix_mautrix_whatsapp_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_whatsapp_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_mautrix_whatsapp_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_whatsapp_homeserver_domain | regex_escape }}$' de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_mautrix_whatsapp_msc4190_enabled | to_json }} + io.element.msc4190: {{ matrix_bridge_mautrix_whatsapp_msc4190_enabled | to_json }} -matrix_mautrix_whatsapp_registration: "{{ matrix_mautrix_whatsapp_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_whatsapp_registration: "{{ matrix_bridge_mautrix_whatsapp_registration_yaml | from_yaml }}" -# matrix_mautrix_whatsapp_restart_necessary controls whether the service +# matrix_bridge_mautrix_whatsapp_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -255,4 +250,4 @@ matrix_mautrix_whatsapp_registration: "{{ matrix_mautrix_whatsapp_registration_y # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_whatsapp_restart_necessary: false +matrix_bridge_mautrix_whatsapp_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/converge.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/converge.yml new file mode 100644 index 000000000..6c617e9ea --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for mautrix-whatsapp Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for mautrix-whatsapp Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure mautrix-whatsapp is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the mautrix-whatsapp systemd service is started + ansible.builtin.systemd_service: + name: matrix-mautrix-whatsapp.service + state: started diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/molecule.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/molecule.yml new file mode 100644 index 000000000..44565f562 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/molecule.yml @@ -0,0 +1,84 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: mautrix-whatsapp-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_mautrix_whatsapp_container_network: mautrix-whatsapp-molecule + + # The stub prepare.yml stands up. Not a real homeserver, and nothing is asserted + # about it. + matrix_bridge_mautrix_whatsapp_homeserver_address: http://matrix.molecule.local:8008 + + # Postgres, because that is what `group_vars/matrix_servers` selects whenever postgres + # is enabled - which is the default, so it is what essentially every real deployment + # runs. prepare.yml stands one up. The password differs from the role's default, so + # reaching the database at all means the role's connection string was built from these. + # Database name and user differ from the role's defaults, so the bridge reaching the + # database at all proves the role built its connection string out of these rather + # than out of anything it would have picked on its own. prepare.yml creates them. + matrix_bridge_mautrix_whatsapp_database_engine: postgres + matrix_bridge_mautrix_whatsapp_database_hostname: matrix-postgres-molecule + matrix_bridge_mautrix_whatsapp_database_name: molecule_whatsapp + matrix_bridge_mautrix_whatsapp_database_username: molecule_whatsapp + matrix_bridge_mautrix_whatsapp_database_password: molecule_pg_password_5e8c21 + + # Here these only have to reach the rendered configuration and the registration. + matrix_bridge_mautrix_whatsapp_appservice_token: molecule_as_token_4f2a91 + matrix_bridge_mautrix_whatsapp_homeserver_token: molecule_hs_token_9b3e77 + + # Different from the role's defaults, so verify.yml can tell what the role rendered + # apart from what the bridge would have chosen. + matrix_bridge_mautrix_whatsapp_appservice_bot_username: molecule-whatsappbot + matrix_bridge_mautrix_whatsapp_homeserver_domain: molecule.local + + # Traefik is not deployed here, so the labels the role would render for it are + # switched off and their absence is asserted instead. + matrix_bridge_mautrix_whatsapp_container_labels_traefik_enabled: false + + # verify.yml runs as its own play, where the role's defaults are out of scope, + # so the paths it reads are pinned here to match what the role derives. + matrix_bridge_mautrix_whatsapp_base_path: /matrix/mautrix-whatsapp + matrix_bridge_mautrix_whatsapp_config_path: /matrix/mautrix-whatsapp/config + matrix_bridge_mautrix_whatsapp_data_path: /matrix/mautrix-whatsapp/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/prepare.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/prepare.yml new file mode 100644 index 000000000..f4df73e35 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/prepare.yml @@ -0,0 +1,89 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare mautrix-whatsapp Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks set owner/group by name, which Ansible resolves through the + # passwd database, so they have to exist first. `matrix-base` creates them for real. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_mautrix_whatsapp_container_network }}" + register: mautrix_whatsapp_molecule_network + changed_when: mautrix_whatsapp_molecule_network.rc == 0 + failed_when: + - mautrix_whatsapp_molecule_network.rc != 0 + - "'already exists' not in mautrix_whatsapp_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_mautrix_whatsapp_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_mautrix_whatsapp_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_mautrix_whatsapp_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_mautrix_whatsapp_database_password }}" + + # The bridge contacts the homeserver as it starts. It is not being asked to bridge + # anything. See molecule-shared/homeserver-stub.py. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_mautrix_whatsapp_container_network }}" + molecule_shared_stub_server_name: molecule.local + molecule_shared_stub_user_id: "@{{ matrix_bridge_mautrix_whatsapp_appservice_bot_username }}:{{ matrix_bridge_mautrix_whatsapp_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/requirements.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/verify.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/verify.yml new file mode 100644 index 000000000..c1cdd55aa --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/molecule/default/verify.yml @@ -0,0 +1,186 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the bridge starts, reads the configuration and registration the role rendered, opens +# its appservice port, and is the version the role pins. +# +# It does NOT bridge anything: there is no WhatsApp on the other side, and deliberately never +# will be. See docs/molecule-testing.md. +- name: Verify mautrix-whatsapp + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + + tasks: + # From the role's own defaults rather than pinned in molecule.yml, so the version + # assertion compares the running image against what the role ships, not the scenario. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: mautrix_whatsapp_role_defaults + + - name: Wait for the mautrix-whatsapp service to become active + ansible.builtin.systemd_service: + name: matrix-mautrix-whatsapp.service + register: mautrix_whatsapp_service + until: mautrix_whatsapp_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # `Restart=always` means a bridge crash-looping on unreadable config still reports + # `active`, so the restart counter is checked too. Asserted `is defined` because + # `| int` turns a missing property into 0 and would pass vacuously. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - mautrix_whatsapp_service.status.ActiveState == 'active' + - mautrix_whatsapp_service.status.NRestarts is defined + - mautrix_whatsapp_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-mautrix-whatsapp.service is + {{ mautrix_whatsapp_service.status.ActiveState | default('unknown') }} + after {{ mautrix_whatsapp_service.status.NRestarts | default('?') }} + automatic restart(s) + success_msg: "matrix-mautrix-whatsapp.service is active and has not restarted" + + # The appservice listener is where a homeserver would push transactions. It opening at all + # means the bridge got through reading its configuration and setting itself up. + - name: Wait for the bridge to open its appservice port + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_mautrix_whatsapp_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - "http://matrix-mautrix-whatsapp:8080/_matrix/mau/live" + register: mautrix_whatsapp_live + changed_when: false + until: "'HTTP_STATUS=000' not in mautrix_whatsapp_live.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge answers on its appservice port + ansible.builtin.assert: + that: + - "'HTTP_STATUS=000' not in mautrix_whatsapp_live.stdout" + fail_msg: >- + The bridge did not answer on its appservice port + ({{ mautrix_whatsapp_live.stdout | default('no output') }}) + success_msg: "The bridge answers on its appservice port" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_whatsapp_config_path }}/config.yaml" + register: mautrix_whatsapp_config_file + + # Each differs from what the bridge would use on its own, so their presence rules out + # a coincidence. + - name: Assert the rendered configuration carries this scenario's values + ansible.builtin.assert: + that: + - matrix_bridge_mautrix_whatsapp_homeserver_address in mautrix_whatsapp_config_rendered + - matrix_bridge_mautrix_whatsapp_appservice_bot_username in mautrix_whatsapp_config_rendered + - matrix_bridge_mautrix_whatsapp_appservice_token in mautrix_whatsapp_config_rendered + fail_msg: "The rendered configuration does not carry the scenario's values" + success_msg: "The rendered configuration carries the scenario's values" + vars: + mautrix_whatsapp_config_rendered: "{{ mautrix_whatsapp_config_file.content | b64decode }}" + + # The role generates the registration; the bridge only consumes it. Worth checking on its + # own, as it is the half of the handshake the homeserver reads. + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_whatsapp_config_path }}/registration.yaml" + register: mautrix_whatsapp_registration_file + + - name: Assert the registration carries the scenario's tokens and bot user + ansible.builtin.assert: + that: + - matrix_bridge_mautrix_whatsapp_appservice_token in mautrix_whatsapp_registration_rendered + - matrix_bridge_mautrix_whatsapp_homeserver_token in mautrix_whatsapp_registration_rendered + - matrix_bridge_mautrix_whatsapp_appservice_bot_username in mautrix_whatsapp_registration_rendered + fail_msg: "The appservice registration does not carry the scenario's tokens and bot user" + success_msg: "The appservice registration carries the scenario's tokens and bot user" + vars: + mautrix_whatsapp_registration_rendered: "{{ mautrix_whatsapp_registration_file.content | b64decode }}" + + # Stronger than the file-on-disk check sqlite allowed: the bridge can only have created + # tables here by resolving the hostname, authenticating with the credentials the role + # rendered, and running its migrations to completion. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_mautrix_whatsapp_database_username }} + - --dbname={{ matrix_bridge_mautrix_whatsapp_database_name }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: mautrix_whatsapp_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the database the role pointed it at + ansible.builtin.assert: + that: + - mautrix_whatsapp_tables.rc == 0 + - "'version' in mautrix_whatsapp_table_names" + - mautrix_whatsapp_table_names | length > 5 + fail_msg: >- + The bridge did not create its schema in + {{ matrix_bridge_mautrix_whatsapp_database_name }} + (found {{ mautrix_whatsapp_table_names | length }} table(s)) + success_msg: "The bridge migrated its schema into the database the role pointed it at" + vars: + mautrix_whatsapp_table_names: "{{ mautrix_whatsapp_tables.stdout_lines | select | list }}" + + - name: Read the image of the running container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-mautrix-whatsapp + - --format + - "{{ '{{' }} .Config.Image {{ '}}' }}" + register: mautrix_whatsapp_image + changed_when: false + + - name: Assert the running container is the version defaults/main.yml pins + ansible.builtin.assert: + that: + - mautrix_whatsapp_role_defaults.matrix_bridge_mautrix_whatsapp_version in mautrix_whatsapp_image.stdout + fail_msg: >- + The running container is {{ mautrix_whatsapp_image.stdout }}, which does + not carry the pinned version + {{ mautrix_whatsapp_role_defaults.matrix_bridge_mautrix_whatsapp_version }} + success_msg: "The running container is the version defaults/main.yml pins" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_mautrix_whatsapp_base_path }}/labels" + register: mautrix_whatsapp_labels + + - name: Assert no Traefik labels are emitted while Traefik support is disabled + ansible.builtin.assert: + that: + - "'traefik.' not in (mautrix_whatsapp_labels.content | b64decode)" + fail_msg: >- + Traefik labels were emitted even though + matrix_bridge_mautrix_whatsapp_container_labels_traefik_enabled is false + success_msg: "No Traefik labels are emitted while Traefik support is disabled" diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/main.yml index 4fb583f66..beba84a06 100644 --- a/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/main.yml @@ -13,15 +13,15 @@ - install-all - install-mautrix-whatsapp block: - - when: matrix_mautrix_whatsapp_enabled | bool + - when: matrix_bridge_mautrix_whatsapp_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_whatsapp_enabled | bool + - when: matrix_bridge_mautrix_whatsapp_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mautrix-whatsapp block: - - when: not matrix_mautrix_whatsapp_enabled | bool + - when: not matrix_bridge_mautrix_whatsapp_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/setup_install.yml index 3656bd816..9f1eaaa6e 100644 --- a/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/setup_install.yml @@ -18,32 +18,32 @@ --- - ansible.builtin.set_fact: - matrix_mautrix_whatsapp_migration_requires_restart: false + matrix_bridge_mautrix_whatsapp_migration_requires_restart: false -- when: "matrix_mautrix_whatsapp_database_engine == 'postgres'" +- when: "matrix_bridge_mautrix_whatsapp_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mautrix_whatsapp_sqlite_database_path_local }}" - register: matrix_mautrix_whatsapp_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mautrix_whatsapp_sqlite_database_path_local }}" + register: matrix_bridge_mautrix_whatsapp_sqlite_database_path_local_stat_result - - when: "matrix_mautrix_whatsapp_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mautrix_whatsapp_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mautrix_whatsapp_sqlite_database_path_local }}" - dst: "{{ matrix_mautrix_whatsapp_database_connection_string }}" + src: "{{ matrix_bridge_mautrix_whatsapp_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mautrix_whatsapp_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mautrix_whatsapp_database_engine' + engine_variable_name: 'matrix_bridge_mautrix_whatsapp_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-mautrix-whatsapp.service'] pgloader_options: ['--with "quote identifiers"'] - ansible.builtin.set_fact: - matrix_mautrix_whatsapp_migration_requires_restart: true + matrix_bridge_mautrix_whatsapp_migration_requires_restart: true - name: Ensure Mautrix Whatsapp paths exists ansible.builtin.file: @@ -53,56 +53,62 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mautrix_whatsapp_base_path }}", when: true} - - {path: "{{ matrix_mautrix_whatsapp_config_path }}", when: true} - - {path: "{{ matrix_mautrix_whatsapp_data_path }}", when: true} - - {path: "{{ matrix_mautrix_whatsapp_container_src_files_path }}", when: "{{ matrix_mautrix_whatsapp_container_image_self_build }}"} + - {path: "{{ matrix_bridge_mautrix_whatsapp_base_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_whatsapp_config_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_whatsapp_data_path }}", when: true} + - {path: "{{ matrix_bridge_mautrix_whatsapp_container_src_files_path }}", when: "{{ matrix_bridge_mautrix_whatsapp_container_image_self_build }}"} when: item.when | bool - name: Ensure Mautrix Whatsapp image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_whatsapp_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_whatsapp_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_whatsapp_container_image_force_pull }}" - when: not matrix_mautrix_whatsapp_container_image_self_build - register: matrix_mautrix_whatsapp_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_whatsapp_container_image }}" + pull: always + when: not matrix_bridge_mautrix_whatsapp_container_image_self_build + register: matrix_bridge_mautrix_whatsapp_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mautrix_whatsapp_container_image_pull_result is not failed + until: matrix_bridge_mautrix_whatsapp_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Mautrix Whatsapp repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_mautrix_whatsapp_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mautrix_whatsapp_container_image_self_build | bool" - name: Ensure Mautrix Whatsapp repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_mautrix_whatsapp_container_image_self_build_repo }}" - dest: "{{ matrix_mautrix_whatsapp_container_src_files_path }}" - version: "{{ matrix_mautrix_whatsapp_container_image_self_build_branch }}" + repo: "{{ matrix_bridge_mautrix_whatsapp_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_mautrix_whatsapp_container_src_files_path }}" + version: "{{ matrix_bridge_mautrix_whatsapp_container_image_self_build_branch }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mautrix_whatsapp_git_pull_results - when: "matrix_mautrix_whatsapp_container_image_self_build | bool" + register: matrix_bridge_mautrix_whatsapp_git_pull_results + when: "matrix_bridge_mautrix_whatsapp_container_image_self_build | bool" - name: Ensure Mautrix Whatsapp Docker image is built - community.docker.docker_image: - name: "{{ matrix_mautrix_whatsapp_container_image }}" - source: build - force_source: "{{ matrix_mautrix_whatsapp_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_whatsapp_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mautrix_whatsapp_container_src_files_path }}" - pull: true - when: "matrix_mautrix_whatsapp_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_mautrix_whatsapp_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mautrix_whatsapp_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mautrix_whatsapp_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mautrix_whatsapp_container_image_self_build | bool" + register: matrix_bridge_mautrix_whatsapp_container_image_build_result - name: Check if an old database file exists ansible.builtin.stat: - path: "{{ matrix_mautrix_whatsapp_base_path }}/mautrix-whatsapp.db" - register: matrix_mautrix_whatsapp_stat_database + path: "{{ matrix_bridge_mautrix_whatsapp_base_path }}/mautrix-whatsapp.db" + register: matrix_bridge_mautrix_whatsapp_stat_database - name: Check if an old Matrix state file exists ansible.builtin.stat: - path: "{{ matrix_mautrix_whatsapp_base_path }}/mx-state.json" - register: matrix_mautrix_whatsapp_stat_mx_state + path: "{{ matrix_bridge_mautrix_whatsapp_base_path }}/mx-state.json" + register: matrix_bridge_mautrix_whatsapp_stat_mx_state - name: (Data relocation) Ensure matrix-mautrix-whatsapp.service is stopped ansible.builtin.service: @@ -111,55 +117,56 @@ enabled: false daemon_reload: true failed_when: false - when: "matrix_mautrix_whatsapp_stat_database.stat.exists" + when: "matrix_bridge_mautrix_whatsapp_stat_database.stat.exists" - name: (Data relocation) Move mautrix-whatsapp database file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_mautrix_whatsapp_base_path }}/mautrix-whatsapp.db {{ matrix_mautrix_whatsapp_data_path }}/mautrix-whatsapp.db" - creates: "{{ matrix_mautrix_whatsapp_data_path }}/mautrix-whatsapp.db" - removes: "{{ matrix_mautrix_whatsapp_base_path }}/mautrix-whatsapp.db" - when: "matrix_mautrix_whatsapp_stat_database.stat.exists" + cmd: "mv {{ matrix_bridge_mautrix_whatsapp_base_path }}/mautrix-whatsapp.db {{ matrix_bridge_mautrix_whatsapp_data_path }}/mautrix-whatsapp.db" + creates: "{{ matrix_bridge_mautrix_whatsapp_data_path }}/mautrix-whatsapp.db" + removes: "{{ matrix_bridge_mautrix_whatsapp_base_path }}/mautrix-whatsapp.db" + when: "matrix_bridge_mautrix_whatsapp_stat_database.stat.exists" - name: (Data relocation) Move mautrix-whatsapp mx-state file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_mautrix_whatsapp_base_path }}/mx-state.json {{ matrix_mautrix_whatsapp_data_path }}/mx-state.json" - creates: "{{ matrix_mautrix_whatsapp_data_path }}/mx-state.json" - removes: "{{ matrix_mautrix_whatsapp_base_path }}/mx-state.json" - when: "matrix_mautrix_whatsapp_stat_mx_state.stat.exists" + cmd: "mv {{ matrix_bridge_mautrix_whatsapp_base_path }}/mx-state.json {{ matrix_bridge_mautrix_whatsapp_data_path }}/mx-state.json" + creates: "{{ matrix_bridge_mautrix_whatsapp_data_path }}/mx-state.json" + removes: "{{ matrix_bridge_mautrix_whatsapp_base_path }}/mx-state.json" + when: "matrix_bridge_mautrix_whatsapp_stat_mx_state.stat.exists" - name: Ensure mautrix-whatsapp config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_whatsapp_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_whatsapp_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_whatsapp_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_whatsapp_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_whatsapp_config_result + register: matrix_bridge_mautrix_whatsapp_config_result - name: Ensure mautrix-whatsapp registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_whatsapp_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mautrix_whatsapp_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mautrix_whatsapp_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mautrix_whatsapp_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_whatsapp_registration_result + register: matrix_bridge_mautrix_whatsapp_registration_result - name: Ensure mautrix-whatsapp support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_whatsapp_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_whatsapp_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_mautrix_whatsapp_support_files_result + register: matrix_bridge_mautrix_whatsapp_support_files_result - name: Ensure matrix-mautrix-whatsapp container network is created + when: matrix_bridge_mautrix_whatsapp_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_whatsapp_container_network }}" + name: "{{ matrix_bridge_mautrix_whatsapp_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -168,18 +175,19 @@ src: "{{ role_path }}/templates/systemd/matrix-mautrix-whatsapp.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-whatsapp.service" mode: '0644' - register: matrix_mautrix_whatsapp_systemd_service_result + register: matrix_bridge_mautrix_whatsapp_systemd_service_result - name: Determine whether matrix-mautrix-whatsapp needs a restart ansible.builtin.set_fact: - matrix_mautrix_whatsapp_restart_necessary: >- + matrix_bridge_mautrix_whatsapp_restart_necessary: >- {{ - matrix_mautrix_whatsapp_migration_requires_restart | default(false) - or matrix_mautrix_whatsapp_config_result.changed | default(false) - or matrix_mautrix_whatsapp_registration_result.changed | default(false) - or matrix_mautrix_whatsapp_support_files_result.changed | default(false) - or matrix_mautrix_whatsapp_systemd_service_result.changed | default(false) - or matrix_mautrix_whatsapp_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_whatsapp_migration_requires_restart | default(false) + or matrix_bridge_mautrix_whatsapp_config_result.changed | default(false) + or matrix_bridge_mautrix_whatsapp_registration_result.changed | default(false) + or matrix_bridge_mautrix_whatsapp_support_files_result.changed | default(false) + or matrix_bridge_mautrix_whatsapp_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_whatsapp_container_image_pull_result.changed | default(false) + or matrix_bridge_mautrix_whatsapp_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mautrix-whatsapp.service restarted, if necessary @@ -187,4 +195,4 @@ name: "matrix-mautrix-whatsapp.service" state: restarted daemon_reload: true - when: "matrix_mautrix_whatsapp_migration_requires_restart | bool" + when: "matrix_bridge_mautrix_whatsapp_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/setup_uninstall.yml index 9a0beafd5..9f7ceb158 100644 --- a/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/setup_uninstall.yml @@ -9,9 +9,9 @@ - name: Check existence of matrix-mautrix-whatsapp service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-whatsapp.service" - register: matrix_mautrix_whatsapp_service_stat + register: matrix_bridge_mautrix_whatsapp_service_stat -- when: matrix_mautrix_whatsapp_service_stat.stat.exists | bool +- when: matrix_bridge_mautrix_whatsapp_service_stat.stat.exists | bool block: - name: Ensure matrix-mautrix-whatsapp is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/validate_config.yml index fd81494be..dad3db699 100644 --- a/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/tasks/validate_config.yml @@ -15,19 +15,32 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_whatsapp_log_level', 'new': 'matrix_mautrix_whatsapp_logging_level'} - - {'old': 'matrix_mautrix_whatsapp_login_shared_secret', 'new': ''} - - {'old': 'matrix_mautrix_whatsapp_bridge_login_shared_secret_map', 'new': ''} - - {'old': 'matrix_mautrix_whatsapp_bridge_double_puppet_server_map', 'new': ''} - - {'old': 'matrix_mautrix_whatsapp_bridge_allow_user_invite', 'new': ''} - - {'old': 'matrix_mautrix_whatsapp_bridge_mute_bridging', 'new': ''} - - {'old': 'matrix_mautrix_whatsapp_docker_image_name_prefix', 'new': 'matrix_mautrix_whatsapp_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_whatsapp_docker_image', 'new': 'matrix_mautrix_whatsapp_container_image'} - - {'old': 'matrix_mautrix_whatsapp_docker_image_force_pull', 'new': 'matrix_mautrix_whatsapp_container_image_force_pull'} - - {'old': 'matrix_mautrix_whatsapp_docker_image_registry_prefix', 'new': 'matrix_mautrix_whatsapp_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_whatsapp_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_whatsapp_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_whatsapp_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_whatsapp_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_whatsapp_docker_src_files_path', 'new': 'matrix_mautrix_whatsapp_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_whatsapp_log_level', 'new': 'matrix_bridge_mautrix_whatsapp_logging_level'} + - {'old': 'matrix_bridge_mautrix_whatsapp_login_shared_secret', 'new': ''} + - {'old': 'matrix_bridge_mautrix_whatsapp_bridge_login_shared_secret_map', 'new': ''} + - {'old': 'matrix_bridge_mautrix_whatsapp_bridge_double_puppet_server_map', 'new': ''} + - {'old': 'matrix_bridge_mautrix_whatsapp_bridge_allow_user_invite', 'new': ''} + - {'old': 'matrix_bridge_mautrix_whatsapp_bridge_mute_bridging', 'new': ''} + - {'old': 'matrix_bridge_mautrix_whatsapp_docker_image_name_prefix', 'new': 'matrix_bridge_mautrix_whatsapp_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_whatsapp_docker_image', 'new': 'matrix_bridge_mautrix_whatsapp_container_image'} + - {'old': 'matrix_bridge_mautrix_whatsapp_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_whatsapp_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_whatsapp_docker_image_registry_prefix', 'new': 'matrix_bridge_mautrix_whatsapp_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_whatsapp_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mautrix_whatsapp_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mautrix_whatsapp_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mautrix_whatsapp_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mautrix_whatsapp_docker_src_files_path', 'new': 'matrix_bridge_mautrix_whatsapp_container_src_files_path'} + - {'old': 'matrix_bridge_mautrix_whatsapp_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_metrics_enabled', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_metrics_proxying_enabled', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_metrics_proxying_hostname', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_metrics_proxying_path_prefix', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_container_labels_metrics_enabled', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_container_labels_metrics_traefik_rule', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_container_labels_metrics_traefik_priority', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_container_labels_metrics_traefik_entrypoints', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_container_labels_metrics_traefik_tls', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_container_labels_metrics_traefik_tls_certResolver', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (mautrix-whatsapp does not support metrics)'} + - {'old': 'matrix_bridge_mautrix_whatsapp_container_labels_metrics_middleware_basic_auth_users', 'new': ' (mautrix-whatsapp does not support metrics)'} - name: Fail if required mautrix-whatsapp settings not defined ansible.builtin.fail: @@ -35,7 +48,7 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mautrix_whatsapp_appservice_token', when: true} - - {'name': 'matrix_mautrix_whatsapp_homeserver_address', when: true} - - {'name': 'matrix_mautrix_whatsapp_homeserver_token', when: true} - - {'name': 'matrix_mautrix_whatsapp_database_hostname', when: "{{ matrix_mautrix_whatsapp_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mautrix_whatsapp_appservice_token', when: true} + - {'name': 'matrix_bridge_mautrix_whatsapp_homeserver_address', when: true} + - {'name': 'matrix_bridge_mautrix_whatsapp_homeserver_token', when: true} + - {'name': 'matrix_bridge_mautrix_whatsapp_database_hostname', when: "{{ matrix_bridge_mautrix_whatsapp_database_engine == 'postgres' }}"} diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-whatsapp/templates/config.yaml.j2 index 91b3e801e..30fe68e7c 100644 --- a/roles/custom/matrix-bridge-mautrix-whatsapp/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/templates/config.yaml.j2 @@ -16,7 +16,7 @@ network: proxy_only_login: false # Displayname template for WhatsApp users. - displayname_template: {{ matrix_mautrix_whatsapp_network_displayname_template | to_json }} + displayname_template: {{ matrix_bridge_mautrix_whatsapp_network_displayname_template | to_json }} # Should incoming calls send a message to the Matrix room? call_start_notices: true @@ -28,7 +28,7 @@ network: send_presence_on_typing: false # Should WhatsApp status messages be bridged into a Matrix room? # Disabling this won't affect already created status broadcast rooms. - enable_status_broadcast: {{ matrix_mautrix_whatsapp_bridge_enable_status_broadcast | to_json }} + enable_status_broadcast: {{ matrix_bridge_mautrix_whatsapp_bridge_enable_status_broadcast | to_json }} # Should sending WhatsApp status messages be allowed? # This can cause issues if the user has lots of contacts, so it's disabled by default. disable_status_broadcast_send: true @@ -45,7 +45,7 @@ network: # key in the event content even if this is disabled. url_previews: false # Should polls be sent using unstable MSC3381 event types? - extev_polls: {{ matrix_mautrix_whatsapp_extev_polls | to_json }} + extev_polls: {{ matrix_bridge_mautrix_whatsapp_extev_polls | to_json }} # Should view-once messages be disabled entirely? disable_view_once: false # Should the bridge always send "active" delivery receipts (two gray ticks on WhatsApp) @@ -107,9 +107,9 @@ network: # Config options that affect the central bridge module. bridge: # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_mautrix_whatsapp_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_mautrix_whatsapp_command_prefix | to_json }} # Should the bridge create a space for each login containing the rooms that account is in? - personal_filtering_spaces: {{ matrix_mautrix_whatsapp_bridge_personal_filtering_spaces | to_json }} + personal_filtering_spaces: {{ matrix_bridge_mautrix_whatsapp_bridge_personal_filtering_spaces | to_json }} # Whether the bridge should set names and avatars explicitly for DM portals. # This is only necessary when using clients that don't support MSC4171. private_chat_portal_meta: true @@ -165,12 +165,12 @@ bridge: relay: # Whether relay mode should be allowed. If allowed, the set-relay command can be used to turn any # authenticated user into a relaybot for that chat. - enabled: {{ matrix_mautrix_whatsapp_bridge_relay_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_whatsapp_bridge_relay_enabled | to_json }} # Should only admins be allowed to set themselves as relay users? # If true, non-admins can only set users listed in default_relays as relays in a room. - admin_only: {{ matrix_mautrix_whatsapp_bridge_relay_admin_only | to_json }} + admin_only: {{ matrix_bridge_mautrix_whatsapp_bridge_relay_admin_only | to_json }} # List of user login IDs which anyone can set as a relay, as long as the relay user is in the room. - default_relays: {{ matrix_mautrix_whatsapp_bridge_relay_default_relays | to_json }} + default_relays: {{ matrix_bridge_mautrix_whatsapp_bridge_relay_default_relays | to_json }} # The formats to use when sending messages via the relaybot. # Available variables: # .Sender.UserID - The Matrix user ID of the sender. @@ -206,18 +206,18 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_mautrix_whatsapp_bridge_permissions|to_json }} + permissions: {{ matrix_bridge_mautrix_whatsapp_bridge_permissions|to_json }} # Config for the bridge's database. database: # The database type. "sqlite3-fk-wal" and "postgres" are supported. - type: {{ matrix_mautrix_whatsapp_appservice_database_type | to_json }} + type: {{ matrix_bridge_mautrix_whatsapp_appservice_database_type | to_json }} # The database URI. # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. # https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_mautrix_whatsapp_appservice_database_uri | to_json }} + uri: {{ matrix_bridge_mautrix_whatsapp_appservice_database_uri | to_json }} # Maximum number of connections. max_open_conns: 20 max_idle_conns: 2 @@ -231,9 +231,9 @@ homeserver: # The address that this appservice can use to connect to the homeserver. # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, # but https also works if they run on different machines. - address: {{ matrix_mautrix_whatsapp_homeserver_address | to_json }} + address: {{ matrix_bridge_mautrix_whatsapp_homeserver_address | to_json }} # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: {{ matrix_mautrix_whatsapp_homeserver_domain | to_json }} + domain: {{ matrix_bridge_mautrix_whatsapp_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -249,7 +249,7 @@ homeserver: # The bridge will use the appservice as_token to authorize requests. message_send_checkpoint_endpoint: # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_mautrix_whatsapp_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_mautrix_whatsapp_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -265,11 +265,11 @@ appservice: # Like the homeserver address, a local non-https address is recommended when the bridge is on the same machine. # If the bridge is elsewhere, you must secure the connection yourself (e.g. with https or wireguard) # If you want to use https, you need to use a reverse proxy. The bridge does not have TLS support built in. - address: {{ matrix_mautrix_whatsapp_appservice_address | to_json }} + address: {{ matrix_bridge_mautrix_whatsapp_appservice_address | to_json }} # A public address that external services can use to reach this appservice. # This is only needed for things like public media. A reverse proxy is generally necessary when using this field. # This value doesn't affect the registration file. - public_address: "" + public_address: {{ matrix_bridge_mautrix_whatsapp_bridge_public_address | to_json }} # The hostname and port where this appservice should listen. # For Docker, you generally have to change the hostname to 0.0.0.0. @@ -281,7 +281,7 @@ appservice: # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_mautrix_whatsapp_appservice_bot_username | to_json }} + username: {{ matrix_bridge_mautrix_whatsapp_appservice_bot_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. displayname: WhatsApp bridge bot @@ -296,8 +296,8 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_mautrix_whatsapp_appservice_token | to_json }} - hs_token: {{ matrix_mautrix_whatsapp_homeserver_token | to_json }} + as_token: {{ matrix_bridge_mautrix_whatsapp_appservice_token | to_json }} + hs_token: {{ matrix_bridge_mautrix_whatsapp_homeserver_token | to_json }} # Localpart template of MXIDs for remote users. # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. @@ -315,7 +315,7 @@ matrix: sync_direct_chat_list: true # Whether created rooms should have federation enabled. If false, created portal rooms # will never be federated. Changing this option requires recreating rooms. - federate_rooms: {{ matrix_mautrix_whatsapp_federate_rooms|to_json }} + federate_rooms: {{ matrix_bridge_mautrix_whatsapp_federate_rooms|to_json }} # The threshold as bytes after which the bridge should roundtrip uploads via the disk # rather than keeping the whole file in memory. upload_file_threshold: 5242880 @@ -335,7 +335,7 @@ provisioning: prefix: /_matrix/provision # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, # or if set to "disable", the provisioning API will be disabled. - shared_secret: {{ matrix_mautrix_whatsapp_provisioning_shared_secret | to_json }} + shared_secret: {{ matrix_bridge_mautrix_whatsapp_provisioning_shared_secret | to_json }} # Whether to allow provisioning API requests to be authed using Matrix access tokens. # This follows the same rules as double puppeting to determine which server to contact to check the token, # which means that by default, it only works for users on the same server as the bridge. @@ -351,7 +351,7 @@ public_media: enabled: false # A key for signing public media URLs. # If set to "generate", a random key will be generated. - signing_key: {{ matrix_mautrix_whatsapp_public_media_signing_key | to_json }} + signing_key: {{ matrix_bridge_mautrix_whatsapp_public_media_signing_key | to_json }} # Number of seconds that public media URLs are valid for. # If set to 0, URLs will never expire. expiry: 0 @@ -385,7 +385,7 @@ direct_media: # See https://docs.mau.fi/bridges/general/backfill.html for more details. backfill: # Whether to do backfilling at all. - enabled: {{ matrix_mautrix_whatsapp_backfill_enabled | to_json }} + enabled: {{ matrix_bridge_mautrix_whatsapp_backfill_enabled | to_json }} # Maximum number of messages to backfill in empty rooms. max_initial_messages: 50 # Maximum number of missed messages to backfill after bridge restarts. @@ -424,18 +424,18 @@ double_puppet: allow_discovery: false # Shared secrets for automatic double puppeting. # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. - secrets: {{ matrix_mautrix_whatsapp_double_puppet_secrets | to_json }} + secrets: {{ matrix_bridge_mautrix_whatsapp_double_puppet_secrets | to_json }} # End-to-bridge encryption support options. # # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. - allow: {{ matrix_mautrix_whatsapp_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_mautrix_whatsapp_bridge_encryption_allow | to_json }} # Whether to force-enable encryption in all bridged rooms. - default: {{ matrix_mautrix_whatsapp_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_mautrix_whatsapp_bridge_encryption_default | to_json }} # Whether to require all messages to be encrypted and drop any unencrypted messages. - require: {{ matrix_mautrix_whatsapp_bridge_encryption_require | to_json }} + require: {{ matrix_bridge_mautrix_whatsapp_bridge_encryption_require | to_json }} # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. # This option is not yet compatible with standard Matrix servers like Synapse and should not be used. appservice: false @@ -443,16 +443,16 @@ encryption: # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_mautrix_whatsapp_msc4190_enabled | to_json }} + msc4190: {{ matrix_bridge_mautrix_whatsapp_msc4190_enabled | to_json }} # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) # Requires msc4190 to replace keys on reset - self_sign: {{ matrix_mautrix_whatsapp_self_sign_enabled | to_json }} + self_sign: {{ matrix_bridge_mautrix_whatsapp_self_sign_enabled | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_mautrix_whatsapp_bridge_encryption_key_sharing_allow | to_json }} + allow_key_sharing: {{ matrix_bridge_mautrix_whatsapp_bridge_encryption_key_sharing_allow | to_json }} # Pickle key for encrypting encryption keys in the bridge database. # If set to generate, a random key will be generated. - pickle_key: {{ matrix_mautrix_whatsapp_bridge_encryption_pickle_key | to_json }} + pickle_key: {{ matrix_bridge_mautrix_whatsapp_bridge_encryption_pickle_key | to_json }} # Options for deleting megolm sessions from the bridge. delete_keys: # Beeper-specific: delete outbound sessions when hungryserv confirms @@ -511,7 +511,7 @@ encryption: # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_mautrix_whatsapp_logging_level | to_json }} + min_level: {{ matrix_bridge_mautrix_whatsapp_logging_level | to_json }} writers: - type: stdout format: pretty-colored diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-whatsapp/templates/labels.j2 index 74bd55954..953af9dac 100644 --- a/roles/custom/matrix-bridge-mautrix-whatsapp/templates/labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/templates/labels.j2 @@ -4,44 +4,42 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_whatsapp_container_labels_traefik_enabled %} +{% if matrix_bridge_mautrix_whatsapp_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_mautrix_whatsapp_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_whatsapp_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_whatsapp_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_whatsapp_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.matrix-mautrix-whatsapp-metrics.loadbalancer.server.port=8001 - -{% if matrix_mautrix_whatsapp_container_labels_metrics_enabled %} +{% if matrix_bridge_mautrix_whatsapp_container_labels_exposure_enabled %} ############################################################ # # -# Metrics # +# Bridge API exposure # # # ############################################################ -{% if matrix_mautrix_whatsapp_container_labels_metrics_middleware_basic_auth_enabled %} -traefik.http.middlewares.matrix-mautrix-whatsapp-metrics-basic-auth.basicauth.users={{ matrix_mautrix_whatsapp_container_labels_metrics_middleware_basic_auth_users }} -traefik.http.routers.matrix-mautrix-whatsapp-metrics.middlewares=matrix-mautrix-whatsapp-metrics-basic-auth -{% endif %} +traefik.http.services.matrix-mautrix-whatsapp-exposure.loadbalancer.server.port=8080 + +traefik.http.middlewares.matrix-mautrix-whatsapp-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_mautrix_whatsapp_exposure_path_prefix }} +traefik.http.routers.matrix-mautrix-whatsapp-exposure.middlewares=matrix-mautrix-whatsapp-exposure-strip-prefix -traefik.http.routers.matrix-mautrix-whatsapp-metrics.rule={{ matrix_mautrix_whatsapp_container_labels_metrics_traefik_rule }} +traefik.http.routers.matrix-mautrix-whatsapp-exposure.rule={{ matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_rule }} -{% if matrix_mautrix_whatsapp_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-whatsapp-metrics.priority={{ matrix_mautrix_whatsapp_container_labels_metrics_traefik_priority }} +{% if matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-whatsapp-exposure.priority={{ matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_priority }} {% endif %} -traefik.http.routers.matrix-mautrix-whatsapp-metrics.service=matrix-mautrix-whatsapp-metrics -traefik.http.routers.matrix-mautrix-whatsapp-metrics.entrypoints={{ matrix_mautrix_whatsapp_container_labels_metrics_traefik_entrypoints }} +traefik.http.routers.matrix-mautrix-whatsapp-exposure.service=matrix-mautrix-whatsapp-exposure +traefik.http.routers.matrix-mautrix-whatsapp-exposure.entrypoints={{ matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_entrypoints }} -traefik.http.routers.matrix-mautrix-whatsapp-metrics.tls={{ matrix_mautrix_whatsapp_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_mautrix_whatsapp_container_labels_metrics_traefik_tls %} -traefik.http.routers.matrix-mautrix-whatsapp-metrics.tls.certResolver={{ matrix_mautrix_whatsapp_container_labels_metrics_traefik_tls_certResolver }} +traefik.http.routers.matrix-mautrix-whatsapp-exposure.tls={{ matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-mautrix-whatsapp-exposure.tls.certResolver={{ matrix_bridge_mautrix_whatsapp_container_labels_exposure_traefik_tls_certResolver }} {% endif %} ############################################################ # # -# /Metrics # +# /Bridge API exposure # # # ############################################################ {% endif %} @@ -49,4 +47,4 @@ traefik.http.routers.matrix-mautrix-whatsapp-metrics.tls.certResolver={{ matrix_ {% endif %} -{{ matrix_mautrix_whatsapp_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_whatsapp_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-mautrix-whatsapp/templates/systemd/matrix-mautrix-whatsapp.service.j2 b/roles/custom/matrix-bridge-mautrix-whatsapp/templates/systemd/matrix-mautrix-whatsapp.service.j2 index e659cf7ae..5970dfd94 100644 --- a/roles/custom/matrix-bridge-mautrix-whatsapp/templates/systemd/matrix-mautrix-whatsapp.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-whatsapp/templates/systemd/matrix-mautrix-whatsapp.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix Whatsapp bridge -{% for service in matrix_mautrix_whatsapp_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_whatsapp_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_whatsapp_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_whatsapp_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,20 +22,22 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_whatsapp_container_network }} \ - --mount type=bind,src={{ matrix_mautrix_whatsapp_config_path }},dst=/config \ - --mount type=bind,src={{ matrix_mautrix_whatsapp_data_path }},dst=/data \ - --label-file={{ matrix_mautrix_whatsapp_base_path }}/labels \ + --network={{ matrix_bridge_mautrix_whatsapp_container_network }} \ + --mount type=bind,src={{ matrix_bridge_mautrix_whatsapp_config_path }},dst=/config \ + --mount type=bind,src={{ matrix_bridge_mautrix_whatsapp_data_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_whatsapp_base_path }}/labels \ --workdir=/data \ - {% for arg in matrix_mautrix_whatsapp_container_extra_arguments %} + {% for arg in matrix_bridge_mautrix_whatsapp_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_whatsapp_container_image }} \ + {{ matrix_bridge_mautrix_whatsapp_container_image }} \ /usr/bin/mautrix-whatsapp -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_mautrix_whatsapp_container_additional_networks %} +{% if matrix_bridge_mautrix_whatsapp_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_whatsapp_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-whatsapp {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-whatsapp diff --git a/roles/custom/matrix-bridge-mautrix-wsproxy/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-wsproxy/defaults/main.yml index f3248ca78..8592b3529 100644 --- a/roles/custom/matrix-bridge-mautrix-wsproxy/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-wsproxy/defaults/main.yml @@ -9,177 +9,175 @@ # mautrix-wsproxy is a Matrix <-> websocket bridge # See: https://github.com/mautrix/wsproxy -matrix_mautrix_wsproxy_enabled: true +matrix_bridge_mautrix_wsproxy_enabled: true -matrix_mautrix_wsproxy_version: latest +matrix_bridge_mautrix_wsproxy_version: latest # See: https://mau.dev/mautrix/wsproxy/container_registry -matrix_mautrix_wsproxy_container_image: "{{ matrix_mautrix_wsproxy_container_image_registry_prefix }}mautrix/wsproxy:{{ matrix_mautrix_wsproxy_version }}" -matrix_mautrix_wsproxy_container_image_registry_prefix: "{{ matrix_mautrix_wsproxy_container_image_registry_prefix_upstream }}" -matrix_mautrix_wsproxy_container_image_registry_prefix_upstream: "{{ matrix_mautrix_wsproxy_container_image_registry_prefix_upstream_default }}" -matrix_mautrix_wsproxy_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_wsproxy_container_image_force_pull: "{{ matrix_mautrix_wsproxy_container_image.endswith(':latest') }}" +matrix_bridge_mautrix_wsproxy_container_image: "{{ matrix_bridge_mautrix_wsproxy_container_image_registry_prefix }}mautrix/wsproxy:{{ matrix_bridge_mautrix_wsproxy_version }}" +matrix_bridge_mautrix_wsproxy_container_image_registry_prefix: "{{ matrix_bridge_mautrix_wsproxy_container_image_registry_prefix_upstream }}" +matrix_bridge_mautrix_wsproxy_container_image_registry_prefix_upstream: "{{ matrix_bridge_mautrix_wsproxy_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mautrix_wsproxy_container_image_registry_prefix_upstream_default: "dock.mau.dev/" -matrix_mautrix_wsproxy_base_path: "{{ matrix_base_data_path }}/wsproxy" -matrix_mautrix_wsproxy_config_path: "{{ matrix_mautrix_wsproxy_base_path }}/config" +matrix_bridge_mautrix_wsproxy_base_path: "{{ matrix_base_data_path }}/wsproxy" +matrix_bridge_mautrix_wsproxy_config_path: "{{ matrix_bridge_mautrix_wsproxy_base_path }}/config" -matrix_mautrix_wsproxy_homeserver_address: "" -matrix_mautrix_wsproxy_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_mautrix_wsproxy_homeserver_address: "" +matrix_bridge_mautrix_wsproxy_homeserver_domain: "{{ matrix_domain }}" -matrix_mautrix_wsproxy_bind_port: false -matrix_mautrix_wsproxy_port: 29331 +matrix_bridge_mautrix_wsproxy_bind_port: false +matrix_bridge_mautrix_wsproxy_port: 29331 -matrix_mautrix_wsproxy_appservice_address: "http://matrix-mautrix-wsproxy:{{ matrix_mautrix_wsproxy_port }}" +matrix_bridge_mautrix_wsproxy_appservice_address: "http://matrix-mautrix-wsproxy:{{ matrix_bridge_mautrix_wsproxy_port }}" -matrix_mautrix_wsproxy_hostname: "" +matrix_bridge_mautrix_wsproxy_hostname: "" # The base container network. It will be auto-created by this role if it doesn't exist already. -matrix_mautrix_wsproxy_container_network: matrix-mautrix-wsproxy +matrix_bridge_mautrix_wsproxy_container_network: matrix-mautrix-wsproxy -matrix_mautrix_wsproxy_twitter_container_additional_networks: "{{ matrix_mautrix_wsproxy_twitter_container_additional_networks_auto + matrix_mautrix_wsproxy_twitter_container_additional_networks_custom }}" -matrix_mautrix_wsproxy_twitter_container_additional_networks_auto: [] -matrix_mautrix_wsproxy_twitter_container_additional_networks_custom: [] +matrix_bridge_mautrix_wsproxy_twitter_container_additional_networks: "{{ matrix_bridge_mautrix_wsproxy_twitter_container_additional_networks_auto + matrix_bridge_mautrix_wsproxy_twitter_container_additional_networks_custom }}" +matrix_bridge_mautrix_wsproxy_twitter_container_additional_networks_auto: [] +matrix_bridge_mautrix_wsproxy_twitter_container_additional_networks_custom: [] -# matrix_mautrix_wsproxy_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_mautrix_wsproxy_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_mautrix_wsproxy_container_labels_additional_labels`. -matrix_mautrix_wsproxy_container_labels_traefik_enabled: true -matrix_mautrix_wsproxy_container_labels_traefik_docker_network: "{{ matrix_mautrix_wsproxy_container_network }}" -matrix_mautrix_wsproxy_container_labels_traefik_hostname: "{{ matrix_mautrix_wsproxy_hostname }}" +# To inject your own other container labels, see `matrix_bridge_mautrix_wsproxy_container_labels_additional_labels`. +matrix_bridge_mautrix_wsproxy_container_labels_traefik_enabled: true +matrix_bridge_mautrix_wsproxy_container_labels_traefik_docker_network: "{{ matrix_bridge_mautrix_wsproxy_container_network }}" +matrix_bridge_mautrix_wsproxy_container_labels_traefik_hostname: "{{ matrix_bridge_mautrix_wsproxy_hostname }}" # The path prefix must either be `/` or not end with a slash (e.g. `/wsproxy`). -matrix_mautrix_wsproxy_container_labels_traefik_rule: "Host(`{{ matrix_mautrix_wsproxy_container_labels_traefik_hostname }}`)" -matrix_mautrix_wsproxy_container_labels_traefik_priority: 0 -matrix_mautrix_wsproxy_container_labels_traefik_entrypoints: web-secure -matrix_mautrix_wsproxy_container_labels_traefik_tls: "{{ matrix_mautrix_wsproxy_container_labels_traefik_entrypoints != 'web' }}" -matrix_mautrix_wsproxy_container_labels_traefik_tls_certResolver: default # noqa var-naming +matrix_bridge_mautrix_wsproxy_container_labels_traefik_rule: "Host(`{{ matrix_bridge_mautrix_wsproxy_container_labels_traefik_hostname }}`)" +matrix_bridge_mautrix_wsproxy_container_labels_traefik_priority: 0 +matrix_bridge_mautrix_wsproxy_container_labels_traefik_entrypoints: web-secure +matrix_bridge_mautrix_wsproxy_container_labels_traefik_tls: "{{ matrix_bridge_mautrix_wsproxy_container_labels_traefik_entrypoints != 'web' }}" +matrix_bridge_mautrix_wsproxy_container_labels_traefik_tls_certResolver: default # noqa var-naming # Controls which additional headers to attach to all HTTP responses. -# To add your own headers, use `matrix_mautrix_wsproxy_container_labels_traefik_additional_response_headers_custom` -matrix_mautrix_wsproxy_container_labels_traefik_additional_response_headers_auto: {} -matrix_mautrix_wsproxy_container_labels_traefik_additional_response_headers_custom: {} -matrix_mautrix_wsproxy_container_labels_traefik_additional_response_headers: "{{ matrix_mautrix_wsproxy_container_labels_traefik_additional_response_headers_auto | combine(matrix_mautrix_wsproxy_container_labels_traefik_additional_response_headers_custom) }}" +# To add your own headers, use `matrix_bridge_mautrix_wsproxy_container_labels_traefik_additional_response_headers_custom` +matrix_bridge_mautrix_wsproxy_container_labels_traefik_additional_response_headers_auto: {} +matrix_bridge_mautrix_wsproxy_container_labels_traefik_additional_response_headers_custom: {} +matrix_bridge_mautrix_wsproxy_container_labels_traefik_additional_response_headers: "{{ matrix_bridge_mautrix_wsproxy_container_labels_traefik_additional_response_headers_auto | combine(matrix_bridge_mautrix_wsproxy_container_labels_traefik_additional_response_headers_custom) }}" -# matrix_mautrix_wsproxy_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# matrix_bridge_mautrix_wsproxy_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_mautrix_wsproxy_container_labels_additional_labels: | +# matrix_bridge_mautrix_wsproxy_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_mautrix_wsproxy_container_labels_additional_labels: '' +matrix_bridge_mautrix_wsproxy_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_mautrix_wsproxy_container_extra_arguments: [] +matrix_bridge_mautrix_wsproxy_container_extra_arguments: [] # List of systemd services that matrix-mautrix-wsproxy.service depends on. -matrix_mautrix_wsproxy_systemd_required_services_list: "{{ matrix_mautrix_wsproxy_systemd_required_services_list_default + matrix_mautrix_wsproxy_systemd_required_services_list_auto + matrix_mautrix_wsproxy_systemd_required_services_list_custom }}" -matrix_mautrix_wsproxy_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mautrix_wsproxy_systemd_required_services_list_auto: [] -matrix_mautrix_wsproxy_systemd_required_services_list_custom: [] +matrix_bridge_mautrix_wsproxy_systemd_required_services_list: "{{ matrix_bridge_mautrix_wsproxy_systemd_required_services_list_default + matrix_bridge_mautrix_wsproxy_systemd_required_services_list_auto + matrix_bridge_mautrix_wsproxy_systemd_required_services_list_custom }}" +matrix_bridge_mautrix_wsproxy_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mautrix_wsproxy_systemd_required_services_list_auto: [] +matrix_bridge_mautrix_wsproxy_systemd_required_services_list_custom: [] # List of systemd services that matrix-mautrix-wsproxy.service wants -matrix_mautrix_wsproxy_systemd_wanted_services_list: [] +matrix_bridge_mautrix_wsproxy_systemd_wanted_services_list: [] -matrix_mautrix_androidsms_appservice_token: '' -matrix_mautrix_androidsms_homeserver_token: '' +matrix_bridge_mautrix_wsproxy_androidsms_appservice_token: '' +matrix_bridge_mautrix_wsproxy_androidsms_homeserver_token: '' -matrix_mautrix_imessage_appservice_token: '' -matrix_mautrix_imessage_homeserver_token: '' +matrix_bridge_mautrix_wsproxy_imessage_appservice_token: '' +matrix_bridge_mautrix_wsproxy_imessage_homeserver_token: '' -matrix_mautrix_androidsms_appservice_bot_username: androidsmsbot -matrix_mautrix_imessage_appservice_bot_username: imessagebot +matrix_bridge_mautrix_wsproxy_androidsms_appservice_bot_username: androidsmsbot +matrix_bridge_mautrix_wsproxy_imessage_appservice_bot_username: imessagebot # Default mautrix-wsproxy configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mautrix_wsproxy_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mautrix_wsproxy_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mautrix_wsproxy_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mautrix_wsproxy_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mautrix_wsproxy_configuration_extension_yaml: | +matrix_bridge_mautrix_wsproxy_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mautrix_wsproxy_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mautrix_wsproxy_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mautrix_wsproxy_configuration_yaml`. + # completely redefining `matrix_bridge_mautrix_wsproxy_configuration_yaml`. -matrix_mautrix_wsproxy_configuration_extension: "{{ matrix_mautrix_wsproxy_configuration_extension_yaml | from_yaml if matrix_mautrix_wsproxy_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mautrix_wsproxy_configuration_extension: "{{ matrix_bridge_mautrix_wsproxy_configuration_extension_yaml | from_yaml if matrix_bridge_mautrix_wsproxy_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mautrix_wsproxy_configuration_yaml`. -matrix_mautrix_wsproxy_configuration: "{{ matrix_mautrix_wsproxy_configuration_yaml | from_yaml | combine(matrix_mautrix_wsproxy_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mautrix_wsproxy_configuration_yaml`. +matrix_bridge_mautrix_wsproxy_configuration: "{{ matrix_bridge_mautrix_wsproxy_configuration_yaml | from_yaml | combine(matrix_bridge_mautrix_wsproxy_configuration_extension, recursive=True) }}" -matrix_mautrix_androidsms_registration_yaml: | +matrix_bridge_mautrix_wsproxy_androidsms_registration_yaml: | id: androidsms - url: {{ matrix_mautrix_wsproxy_appservice_address }} - as_token: "{{ matrix_mautrix_androidsms_appservice_token }}" - hs_token: "{{ matrix_mautrix_androidsms_homeserver_token }}" - sender_localpart: _bot_{{ matrix_mautrix_androidsms_appservice_bot_username }} + url: {{ matrix_bridge_mautrix_wsproxy_appservice_address }} + as_token: "{{ matrix_bridge_mautrix_wsproxy_androidsms_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_wsproxy_androidsms_homeserver_token }}" + sender_localpart: _bot_{{ matrix_bridge_mautrix_wsproxy_androidsms_appservice_bot_username }} rate_limited: false namespaces: users: - - regex: '@androidsms_.+:{{ matrix_mautrix_wsproxy_homeserver_domain | regex_escape }}$' + - regex: '@androidsms_.+:{{ matrix_bridge_mautrix_wsproxy_homeserver_domain | regex_escape }}$' exclusive: true - exclusive: true - regex: '^@{{ matrix_mautrix_androidsms_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_wsproxy_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_mautrix_wsproxy_androidsms_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_wsproxy_homeserver_domain | regex_escape }}$' -matrix_mautrix_androidsms_registration: "{{ matrix_mautrix_androidsms_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_wsproxy_androidsms_registration: "{{ matrix_bridge_mautrix_wsproxy_androidsms_registration_yaml | from_yaml }}" -matrix_mautrix_imessage_registration_yaml: | +matrix_bridge_mautrix_wsproxy_imessage_registration_yaml: | id: imessage - url: {{ matrix_mautrix_wsproxy_appservice_address }} - as_token: "{{ matrix_mautrix_imessage_appservice_token }}" - hs_token: "{{ matrix_mautrix_imessage_homeserver_token }}" - sender_localpart: _bot_{{ matrix_mautrix_imessage_appservice_bot_username }} + url: {{ matrix_bridge_mautrix_wsproxy_appservice_address }} + as_token: "{{ matrix_bridge_mautrix_wsproxy_imessage_appservice_token }}" + hs_token: "{{ matrix_bridge_mautrix_wsproxy_imessage_homeserver_token }}" + sender_localpart: _bot_{{ matrix_bridge_mautrix_wsproxy_imessage_appservice_bot_username }} rate_limited: false namespaces: users: - - regex: '@imessage_.+:{{ matrix_mautrix_wsproxy_homeserver_domain | regex_escape }}$' + - regex: '@imessage_.+:{{ matrix_bridge_mautrix_wsproxy_homeserver_domain | regex_escape }}$' exclusive: true - exclusive: true - regex: '^@{{ matrix_mautrix_imessage_appservice_bot_username | regex_escape }}:{{ matrix_mautrix_wsproxy_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_mautrix_wsproxy_imessage_appservice_bot_username | regex_escape }}:{{ matrix_bridge_mautrix_wsproxy_homeserver_domain | regex_escape }}$' -matrix_mautrix_imessage_registration: "{{ matrix_mautrix_imessage_registration_yaml | from_yaml }}" +matrix_bridge_mautrix_wsproxy_imessage_registration: "{{ matrix_bridge_mautrix_wsproxy_imessage_registration_yaml | from_yaml }}" # Syncproxy-related configuration fields # renovate: datasource=docker depName=dock.mau.dev/mautrix/syncproxy -matrix_mautrix_wsproxy_syncproxy_version: latest +matrix_bridge_mautrix_wsproxy_syncproxy_version: latest # See: https://mau.dev/mautrix/wsproxy/container_registry -matrix_mautrix_wsproxy_syncproxy_container_image: "dock.mau.dev/mautrix/syncproxy:{{ matrix_mautrix_wsproxy_syncproxy_version }}" -matrix_mautrix_wsproxy_syncproxy_container_image_force_pull: "{{ matrix_mautrix_wsproxy_syncproxy_container_image.endswith(':latest') }}" -matrix_mautrix_wsproxy_syncproxy_container_extra_arguments: [] +matrix_bridge_mautrix_wsproxy_syncproxy_container_image: "dock.mau.dev/mautrix/syncproxy:{{ matrix_bridge_mautrix_wsproxy_syncproxy_version }}" +matrix_bridge_mautrix_wsproxy_syncproxy_container_extra_arguments: [] -matrix_mautrix_wsproxy_syncproxy_systemd_required_services_list: |- +matrix_bridge_mautrix_wsproxy_syncproxy_systemd_required_services_list: |- {{ ([devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else []) + ['matrix-mautrix-wsproxy.service'] }} -matrix_mautrix_wsproxy_syncproxy_systemd_wanted_services_list: [] +matrix_bridge_mautrix_wsproxy_syncproxy_systemd_wanted_services_list: [] -matrix_mautrix_wsproxy_syncproxy_homeserver_url: '' +matrix_bridge_mautrix_wsproxy_syncproxy_homeserver_url: '' -matrix_mautrix_wsproxy_syncproxy_shared_secret: '' -matrix_mautrix_wsproxy_syncproxy_port: 29332 -matrix_mautrix_wsproxy_syncproxy_appservice_address: "http://matrix-mautrix-wsproxy-syncproxy:{{ matrix_mautrix_wsproxy_syncproxy_port }}" +matrix_bridge_mautrix_wsproxy_syncproxy_shared_secret: '' +matrix_bridge_mautrix_wsproxy_syncproxy_port: 29332 +matrix_bridge_mautrix_wsproxy_syncproxy_appservice_address: "http://matrix-mautrix-wsproxy-syncproxy:{{ matrix_bridge_mautrix_wsproxy_syncproxy_port }}" # Database-related configuration fields # # This bridge supports Postgres and SQLite. # -matrix_mautrix_wsproxy_syncproxy_database_engine: 'postgres' +matrix_bridge_mautrix_wsproxy_syncproxy_database_engine: 'postgres' -matrix_mautrix_wsproxy_syncproxy_database_username: 'matrix_mautrix_wsproxy_syncproxy' -matrix_mautrix_wsproxy_syncproxy_database_password: '' -matrix_mautrix_wsproxy_syncproxy_database_hostname: '' -matrix_mautrix_wsproxy_syncproxy_database_port: 5432 -matrix_mautrix_wsproxy_syncproxy_database_name: 'matrix_mautrix_wsproxy_syncproxy' +matrix_bridge_mautrix_wsproxy_syncproxy_database_username: 'matrix_bridge_mautrix_wsproxy_syncproxy' +matrix_bridge_mautrix_wsproxy_syncproxy_database_password: '' +matrix_bridge_mautrix_wsproxy_syncproxy_database_hostname: '' +matrix_bridge_mautrix_wsproxy_syncproxy_database_port: 5432 +matrix_bridge_mautrix_wsproxy_syncproxy_database_name: 'matrix_bridge_mautrix_wsproxy_syncproxy' -matrix_mautrix_signal_wsproxy_syncproxy_connection_string: 'postgres://{{ matrix_mautrix_wsproxy_syncproxy_database_username }}:{{ matrix_mautrix_wsproxy_syncproxy_database_password }}@{{ matrix_mautrix_wsproxy_syncproxy_database_hostname }}:{{ matrix_mautrix_wsproxy_syncproxy_database_port }}/{{ matrix_mautrix_wsproxy_syncproxy_database_name }}' +matrix_bridge_mautrix_wsproxy_syncproxy_connection_string: 'postgres://{{ matrix_bridge_mautrix_wsproxy_syncproxy_database_username }}:{{ matrix_bridge_mautrix_wsproxy_syncproxy_database_password }}@{{ matrix_bridge_mautrix_wsproxy_syncproxy_database_hostname }}:{{ matrix_bridge_mautrix_wsproxy_syncproxy_database_port }}/{{ matrix_bridge_mautrix_wsproxy_syncproxy_database_name }}' -# matrix_mautrix_wsproxy_restart_necessary controls whether the service +# matrix_bridge_mautrix_wsproxy_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -187,9 +185,9 @@ matrix_mautrix_signal_wsproxy_syncproxy_connection_string: 'postgres://{{ matrix # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_wsproxy_restart_necessary: false +matrix_bridge_mautrix_wsproxy_restart_necessary: false -# matrix_mautrix_wsproxy_syncproxy_restart_necessary controls whether the service +# matrix_bridge_mautrix_wsproxy_syncproxy_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -197,4 +195,4 @@ matrix_mautrix_wsproxy_restart_necessary: false # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mautrix_wsproxy_syncproxy_restart_necessary: false +matrix_bridge_mautrix_wsproxy_syncproxy_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/main.yml b/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/main.yml index dd2cee331..f1be51571 100644 --- a/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/main.yml +++ b/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/main.yml @@ -11,15 +11,15 @@ - install-all - install-mautrix-wsproxy block: - - when: matrix_mautrix_wsproxy_enabled | bool + - when: matrix_bridge_mautrix_wsproxy_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mautrix_wsproxy_enabled | bool + - when: matrix_bridge_mautrix_wsproxy_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mautrix-wsproxy block: - - when: not matrix_mautrix_wsproxy_enabled | bool + - when: not matrix_bridge_mautrix_wsproxy_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/setup_install.yml b/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/setup_install.yml index c3e8fddf9..3396ff4d9 100644 --- a/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/setup_install.yml @@ -16,10 +16,10 @@ when: "matrix_synapse_role_executed|default(False)" - ansible.builtin.set_fact: - matrix_mautrix_wsproxy_migration_requires_restart: false + matrix_bridge_mautrix_wsproxy_migration_requires_restart: false - ansible.builtin.set_fact: - matrix_mautrix_wsproxy_syncproxy_migration_requires_restart: false + matrix_bridge_mautrix_wsproxy_syncproxy_migration_requires_restart: false - name: Ensure Mautrix wsproxy paths exist ansible.builtin.file: @@ -29,37 +29,39 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - path: "{{ matrix_mautrix_wsproxy_base_path }}" + - path: "{{ matrix_bridge_mautrix_wsproxy_base_path }}" when: true when: item.when | bool - name: Ensure Mautrix wsproxy support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_mautrix_wsproxy_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_mautrix_wsproxy_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - syncproxy-env - wsproxy-labels - register: matrix_mautrix_wsproxy_support_files_result + register: matrix_bridge_mautrix_wsproxy_support_files_result - name: Ensure Mautrix wsproxy image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_wsproxy_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_wsproxy_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_wsproxy_container_image_force_pull }}" - register: matrix_mautrix_wsproxy_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_wsproxy_container_image }}" + pull: always + register: matrix_bridge_mautrix_wsproxy_container_image_pull_result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: matrix_bridge_mautrix_wsproxy_container_image_pull_result is not failed - name: Ensure Mautrix syncproxy image is pulled - community.docker.docker_image: - name: "{{ matrix_mautrix_wsproxy_syncproxy_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mautrix_wsproxy_syncproxy_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mautrix_wsproxy_syncproxy_container_image_force_pull }}" - register: matrix_mautrix_wsproxy_syncproxy_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mautrix_wsproxy_syncproxy_container_image }}" + pull: always + register: matrix_bridge_mautrix_wsproxy_syncproxy_container_image_pull_result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: matrix_bridge_mautrix_wsproxy_syncproxy_container_image_pull_result is not failed - name: Ensure Mautrix wsproxy paths exists ansible.builtin.file: @@ -69,45 +71,46 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - "{{ matrix_mautrix_wsproxy_base_path }}" - - "{{ matrix_mautrix_wsproxy_config_path }}" + - "{{ matrix_bridge_mautrix_wsproxy_base_path }}" + - "{{ matrix_bridge_mautrix_wsproxy_config_path }}" - name: Check if an old Matrix state file exists ansible.builtin.stat: - path: "{{ matrix_mautrix_wsproxy_base_path }}/mx-state.json" - register: matrix_mautrix_wsproxy_stat_mx_state + path: "{{ matrix_bridge_mautrix_wsproxy_base_path }}/mx-state.json" + register: matrix_bridge_mautrix_wsproxy_stat_mx_state - name: Ensure mautrix-wsproxy config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_wsproxy_configuration | to_nice_yaml }}" - dest: "{{ matrix_mautrix_wsproxy_config_path }}/config.yaml" + content: "{{ matrix_bridge_mautrix_wsproxy_configuration | to_nice_yaml }}" + dest: "{{ matrix_bridge_mautrix_wsproxy_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_wsproxy_config_result + register: matrix_bridge_mautrix_wsproxy_config_result - name: Ensure mautrix-androidsms registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_androidsms_registration | to_nice_yaml }}" - dest: "{{ matrix_mautrix_wsproxy_config_path }}/androidsms-registration.yaml" + content: "{{ matrix_bridge_mautrix_wsproxy_androidsms_registration | to_nice_yaml }}" + dest: "{{ matrix_bridge_mautrix_wsproxy_config_path }}/androidsms-registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_wsproxy_registration_androidsms_result + register: matrix_bridge_mautrix_wsproxy_registration_androidsms_result - name: Ensure mautrix-imessage registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mautrix_imessage_registration | to_nice_yaml }}" - dest: "{{ matrix_mautrix_wsproxy_config_path }}/imessage-registration.yaml" + content: "{{ matrix_bridge_mautrix_wsproxy_imessage_registration | to_nice_yaml }}" + dest: "{{ matrix_bridge_mautrix_wsproxy_config_path }}/imessage-registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mautrix_wsproxy_registration_imessage_result + register: matrix_bridge_mautrix_wsproxy_registration_imessage_result - name: Ensure mautrix-wsproxy container network is created + when: matrix_bridge_mautrix_wsproxy_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mautrix_wsproxy_container_network }}" + name: "{{ matrix_bridge_mautrix_wsproxy_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -116,55 +119,55 @@ src: "{{ role_path }}/templates/systemd/matrix-mautrix-wsproxy.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-wsproxy.service" mode: '0644' - register: matrix_mautrix_wsproxy_systemd_service_result + register: matrix_bridge_mautrix_wsproxy_systemd_service_result - name: Determine whether Mautrix wsproxy needs a restart ansible.builtin.set_fact: - matrix_mautrix_wsproxy_restart_necessary: >- + matrix_bridge_mautrix_wsproxy_restart_necessary: >- {{ - matrix_mautrix_wsproxy_migration_requires_restart | default(false) - or matrix_mautrix_wsproxy_support_files_result.changed | default(false) - or matrix_mautrix_wsproxy_config_result.changed | default(false) - or matrix_mautrix_wsproxy_registration_androidsms_result.changed | default(false) - or matrix_mautrix_wsproxy_registration_imessage_result.changed | default(false) - or matrix_mautrix_wsproxy_systemd_service_result.changed | default(false) - or matrix_mautrix_wsproxy_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_wsproxy_migration_requires_restart | default(false) + or matrix_bridge_mautrix_wsproxy_support_files_result.changed | default(false) + or matrix_bridge_mautrix_wsproxy_config_result.changed | default(false) + or matrix_bridge_mautrix_wsproxy_registration_androidsms_result.changed | default(false) + or matrix_bridge_mautrix_wsproxy_registration_imessage_result.changed | default(false) + or matrix_bridge_mautrix_wsproxy_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_wsproxy_container_image_pull_result.changed | default(false) }} - name: Ensure systemd reloaded after matrix-mautrix-wsproxy.service installation ansible.builtin.service: daemon_reload: true - when: "matrix_mautrix_wsproxy_systemd_service_result.changed" + when: "matrix_bridge_mautrix_wsproxy_systemd_service_result.changed" - name: Ensure matrix-mautrix-wsproxy.service restarted, if necessary ansible.builtin.service: name: "matrix-mautrix-wsproxy.service" state: restarted - when: "matrix_mautrix_wsproxy_migration_requires_restart|bool" + when: "matrix_bridge_mautrix_wsproxy_migration_requires_restart|bool" - name: Ensure matrix-mautrix-wsproxy-syncproxy.service installed ansible.builtin.template: src: "{{ role_path }}/templates/systemd/matrix-mautrix-wsproxy-syncproxy.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-wsproxy-syncproxy.service" mode: '0644' - register: matrix_mautrix_wsproxy_syncproxy_systemd_service_result + register: matrix_bridge_mautrix_wsproxy_syncproxy_systemd_service_result - name: Determine whether Mautrix wsproxy syncproxy needs a restart ansible.builtin.set_fact: - matrix_mautrix_wsproxy_syncproxy_restart_necessary: >- + matrix_bridge_mautrix_wsproxy_syncproxy_restart_necessary: >- {{ - matrix_mautrix_wsproxy_syncproxy_migration_requires_restart | default(false) - or matrix_mautrix_wsproxy_syncproxy_systemd_service_result.changed | default(false) - or matrix_mautrix_wsproxy_syncproxy_container_image_pull_result.changed | default(false) + matrix_bridge_mautrix_wsproxy_syncproxy_migration_requires_restart | default(false) + or matrix_bridge_mautrix_wsproxy_syncproxy_systemd_service_result.changed | default(false) + or matrix_bridge_mautrix_wsproxy_syncproxy_container_image_pull_result.changed | default(false) }} - name: Ensure systemd reloaded after matrix-mautrix-wsproxy-syncproxy.service installation ansible.builtin.service: daemon_reload: true - when: "matrix_mautrix_wsproxy_syncproxy_systemd_service_result.changed" + when: "matrix_bridge_mautrix_wsproxy_syncproxy_systemd_service_result.changed" - name: Ensure matrix-mautrix-wsproxy-syncproxy.service restarted, if necessary ansible.builtin.service: name: "matrix-mautrix-wsproxy-syncproxy.service" state: restarted - when: "matrix_mautrix_wsproxy_syncproxy_migration_requires_restart|bool" + when: "matrix_bridge_mautrix_wsproxy_syncproxy_migration_requires_restart|bool" diff --git a/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/setup_uninstall.yml index 0326fcb96..12572d3a8 100644 --- a/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/setup_uninstall.yml @@ -7,45 +7,45 @@ - name: Check existence of matrix-mautrix-wsproxy service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-wsproxy.service" - register: matrix_mautrix_wsproxy_service_stat + register: matrix_bridge_mautrix_wsproxy_service_stat - name: Ensure matrix-mautrix-wsproxy is stopped ansible.builtin.service: name: matrix-mautrix-wsproxy state: stopped daemon_reload: true - when: "matrix_mautrix_wsproxy_service_stat.stat.exists" + when: "matrix_bridge_mautrix_wsproxy_service_stat.stat.exists" - name: Ensure matrix-mautrix-wsproxy.service doesn't exist ansible.builtin.file: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-wsproxy.service" state: absent - when: "matrix_mautrix_wsproxy_service_stat.stat.exists" + when: "matrix_bridge_mautrix_wsproxy_service_stat.stat.exists" - name: Ensure systemd reloaded after matrix-mautrix-wsproxy.service removal ansible.builtin.service: daemon_reload: true - when: "matrix_mautrix_wsproxy_service_stat.stat.exists" + when: "matrix_bridge_mautrix_wsproxy_service_stat.stat.exists" - name: Check existence of matrix-mautrix-wsproxy-syncproxy service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-wsproxy-syncproxy.service" - register: matrix_mautrix_wsproxy_syncproxy_service_stat + register: matrix_bridge_mautrix_wsproxy_syncproxy_service_stat - name: Ensure matrix-mautrix-wsproxy-syncproxy is stopped ansible.builtin.service: name: matrix-mautrix-wsproxy-syncproxy state: stopped daemon_reload: true - when: "matrix_mautrix_wsproxy_syncproxy_service_stat.stat.exists" + when: "matrix_bridge_mautrix_wsproxy_syncproxy_service_stat.stat.exists" - name: Ensure matrix-mautrix-wsproxy-syncproxy.service doesn't exist ansible.builtin.file: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-mautrix-wsproxy-syncproxy.service" state: absent - when: "matrix_mautrix_wsproxy_syncproxy_service_stat.stat.exists" + when: "matrix_bridge_mautrix_wsproxy_syncproxy_service_stat.stat.exists" - name: Ensure systemd reloaded after matrix-mautrix-wsproxy-syncproxy.service removal ansible.builtin.service: daemon_reload: true - when: "matrix_mautrix_wsproxy_syncproxy_service_stat.stat.exists" + when: "matrix_bridge_mautrix_wsproxy_syncproxy_service_stat.stat.exists" diff --git a/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/validate_config.yml b/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/validate_config.yml index 46f060c9f..b3f6c8a46 100644 --- a/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-wsproxy/tasks/validate_config.yml @@ -12,13 +12,15 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mautrix_wsproxy_docker_image', 'new': 'matrix_mautrix_wsproxy_container_image'} - - {'old': 'matrix_mautrix_wsproxy_docker_image_force_pull', 'new': 'matrix_mautrix_wsproxy_container_image_force_pull'} - - {'old': 'matrix_mautrix_wsproxy_docker_image_registry_prefix', 'new': 'matrix_mautrix_wsproxy_container_image_registry_prefix'} - - {'old': 'matrix_mautrix_wsproxy_docker_image_registry_prefix_upstream', 'new': 'matrix_mautrix_wsproxy_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mautrix_wsproxy_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mautrix_wsproxy_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mautrix_wsproxy_syncproxy_docker_image', 'new': 'matrix_mautrix_wsproxy_syncproxy_container_image'} - - {'old': 'matrix_mautrix_wsproxy_syncproxy_docker_image_force_pull', 'new': 'matrix_mautrix_wsproxy_syncproxy_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_wsproxy_docker_image', 'new': 'matrix_bridge_mautrix_wsproxy_container_image'} + - {'old': 'matrix_bridge_mautrix_wsproxy_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_wsproxy_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_wsproxy_docker_image_registry_prefix', 'new': 'matrix_bridge_mautrix_wsproxy_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mautrix_wsproxy_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mautrix_wsproxy_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mautrix_wsproxy_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mautrix_wsproxy_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mautrix_wsproxy_syncproxy_docker_image', 'new': 'matrix_bridge_mautrix_wsproxy_syncproxy_container_image'} + - {'old': 'matrix_bridge_mautrix_wsproxy_syncproxy_docker_image_force_pull', 'new': 'matrix_bridge_mautrix_wsproxy_syncproxy_container_image_force_pull'} + - {'old': 'matrix_bridge_mautrix_wsproxy_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_mautrix_wsproxy_syncproxy_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required settings not defined @@ -27,12 +29,12 @@ You need to define a required configuration setting (`{{ item }}`). when: "lookup('vars', item, default='') == ''" with_items: - - "matrix_mautrix_androidsms_appservice_token" - - "matrix_mautrix_androidsms_homeserver_token" - - "matrix_mautrix_imessage_appservice_token" - - "matrix_mautrix_imessage_homeserver_token" - - "matrix_mautrix_wsproxy_homeserver_address" - - "matrix_mautrix_wsproxy_syncproxy_shared_secret" - - "matrix_mautrix_wsproxy_syncproxy_homeserver_url" - - "matrix_mautrix_wsproxy_syncproxy_database_hostname" - - "matrix_mautrix_wsproxy_syncproxy_database_password" + - "matrix_bridge_mautrix_wsproxy_androidsms_appservice_token" + - "matrix_bridge_mautrix_wsproxy_androidsms_homeserver_token" + - "matrix_bridge_mautrix_wsproxy_imessage_appservice_token" + - "matrix_bridge_mautrix_wsproxy_imessage_homeserver_token" + - "matrix_bridge_mautrix_wsproxy_homeserver_address" + - "matrix_bridge_mautrix_wsproxy_syncproxy_shared_secret" + - "matrix_bridge_mautrix_wsproxy_syncproxy_homeserver_url" + - "matrix_bridge_mautrix_wsproxy_syncproxy_database_hostname" + - "matrix_bridge_mautrix_wsproxy_syncproxy_database_password" diff --git a/roles/custom/matrix-bridge-mautrix-wsproxy/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mautrix-wsproxy/templates/config.yaml.j2 index b0eae9f68..0f07636db 100644 --- a/roles/custom/matrix-bridge-mautrix-wsproxy/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mautrix-wsproxy/templates/config.yaml.j2 @@ -7,14 +7,14 @@ SPDX-License-Identifier: AGPL-3.0-or-later listen_address: 0.0.0.0:29331 appservices: - id: androidsms - as: {{ matrix_mautrix_androidsms_appservice_token | to_json }} - hs: {{ matrix_mautrix_androidsms_homeserver_token | to_json }} + as: {{ matrix_bridge_mautrix_wsproxy_androidsms_appservice_token | to_json }} + hs: {{ matrix_bridge_mautrix_wsproxy_androidsms_homeserver_token | to_json }} - id: imessage - as: {{ matrix_mautrix_imessage_appservice_token | to_json }} - hs: {{ matrix_mautrix_imessage_homeserver_token | to_json }} + as: {{ matrix_bridge_mautrix_wsproxy_imessage_appservice_token | to_json }} + hs: {{ matrix_bridge_mautrix_wsproxy_imessage_homeserver_token | to_json }} sync_proxy: # The URL that mautrix-wsproxy can use to reach mautrix-syncproxy - url: {{ matrix_mautrix_wsproxy_syncproxy_appservice_address | to_json }} + url: {{ matrix_bridge_mautrix_wsproxy_syncproxy_appservice_address | to_json }} # The URL that mautrix-syncproxy can use to reach mautrix-wsproxy - wsproxy_url: {{ matrix_mautrix_wsproxy_appservice_address | to_json }} - shared_secret: {{ matrix_mautrix_wsproxy_syncproxy_shared_secret | to_json }} + wsproxy_url: {{ matrix_bridge_mautrix_wsproxy_appservice_address | to_json }} + shared_secret: {{ matrix_bridge_mautrix_wsproxy_syncproxy_shared_secret | to_json }} diff --git a/roles/custom/matrix-bridge-mautrix-wsproxy/templates/syncproxy-env.j2 b/roles/custom/matrix-bridge-mautrix-wsproxy/templates/syncproxy-env.j2 index 45ff0d9b6..277f8303e 100644 --- a/roles/custom/matrix-bridge-mautrix-wsproxy/templates/syncproxy-env.j2 +++ b/roles/custom/matrix-bridge-mautrix-wsproxy/templates/syncproxy-env.j2 @@ -5,6 +5,6 @@ SPDX-FileCopyrightText: 2024 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} -DATABASE_URL={{ matrix_mautrix_signal_wsproxy_syncproxy_connection_string }} -HOMESERVER_URL={{ matrix_mautrix_wsproxy_syncproxy_homeserver_url }} -SHARED_SECRET={{ matrix_mautrix_wsproxy_syncproxy_shared_secret }} +DATABASE_URL={{ matrix_bridge_mautrix_wsproxy_syncproxy_connection_string }} +HOMESERVER_URL={{ matrix_bridge_mautrix_wsproxy_syncproxy_homeserver_url }} +SHARED_SECRET={{ matrix_bridge_mautrix_wsproxy_syncproxy_shared_secret }} diff --git a/roles/custom/matrix-bridge-mautrix-wsproxy/templates/systemd/matrix-mautrix-wsproxy-syncproxy.service.j2 b/roles/custom/matrix-bridge-mautrix-wsproxy/templates/systemd/matrix-mautrix-wsproxy-syncproxy.service.j2 index 0f0aa3768..32f60703c 100644 --- a/roles/custom/matrix-bridge-mautrix-wsproxy/templates/systemd/matrix-mautrix-wsproxy-syncproxy.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-wsproxy/templates/systemd/matrix-mautrix-wsproxy-syncproxy.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix wsproxy syncproxy -{% for service in matrix_mautrix_wsproxy_syncproxy_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_wsproxy_syncproxy_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_wsproxy_syncproxy_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_wsproxy_syncproxy_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,16 +22,18 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_wsproxy_container_network }} \ - --env-file={{ matrix_mautrix_wsproxy_base_path }}/syncproxy-env \ - {% for arg in matrix_mautrix_wsproxy_syncproxy_container_extra_arguments %} + --network={{ matrix_bridge_mautrix_wsproxy_container_network }} \ + --env-file={{ matrix_bridge_mautrix_wsproxy_base_path }}/syncproxy-env \ + {% for arg in matrix_bridge_mautrix_wsproxy_syncproxy_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_wsproxy_syncproxy_container_image }} + {{ matrix_bridge_mautrix_wsproxy_syncproxy_container_image }} -{% for network in matrix_mautrix_wsproxy_container_additional_networks %} +{% if matrix_bridge_mautrix_wsproxy_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_wsproxy_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-wsproxy-syncproxy {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-wsproxy-syncproxy diff --git a/roles/custom/matrix-bridge-mautrix-wsproxy/templates/systemd/matrix-mautrix-wsproxy.service.j2 b/roles/custom/matrix-bridge-mautrix-wsproxy/templates/systemd/matrix-mautrix-wsproxy.service.j2 index ca0e102da..e1a91cebb 100644 --- a/roles/custom/matrix-bridge-mautrix-wsproxy/templates/systemd/matrix-mautrix-wsproxy.service.j2 +++ b/roles/custom/matrix-bridge-mautrix-wsproxy/templates/systemd/matrix-mautrix-wsproxy.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mautrix wsproxy bridge -{% for service in matrix_mautrix_wsproxy_systemd_required_services_list %} +{% for service in matrix_bridge_mautrix_wsproxy_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mautrix_wsproxy_systemd_wanted_services_list %} +{% for service in matrix_bridge_mautrix_wsproxy_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -20,21 +20,23 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create --rm - --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mautrix_wsproxy_container_network }} \ - {% if matrix_mautrix_wsproxy_bind_port %} - -p {{ matrix_mautrix_wsproxy_port }}:29331 \ + --network={{ matrix_bridge_mautrix_wsproxy_container_network }} \ + {% if matrix_bridge_mautrix_wsproxy_bind_port %} + -p {{ matrix_bridge_mautrix_wsproxy_port }}:29331 \ {% endif %} - --mount type=bind,src={{ matrix_mautrix_wsproxy_config_path }},dst=/data \ - --label-file={{ matrix_mautrix_wsproxy_base_path }}/wsproxy-labels \ - {% for arg in matrix_mautrix_wsproxy_container_extra_arguments %} + --mount type=bind,src={{ matrix_bridge_mautrix_wsproxy_config_path }},dst=/data \ + --label-file={{ matrix_bridge_mautrix_wsproxy_base_path }}/wsproxy-labels \ + {% for arg in matrix_bridge_mautrix_wsproxy_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mautrix_wsproxy_container_image }} \ + {{ matrix_bridge_mautrix_wsproxy_container_image }} \ /usr/bin/mautrix-wsproxy -config /data/config.yaml -{% for network in matrix_mautrix_wsproxy_container_additional_networks %} +{% if matrix_bridge_mautrix_wsproxy_container_network != 'host' %} +{% for network in matrix_bridge_mautrix_wsproxy_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mautrix-wsproxy {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mautrix-wsproxy diff --git a/roles/custom/matrix-bridge-mautrix-wsproxy/templates/wsproxy-labels.j2 b/roles/custom/matrix-bridge-mautrix-wsproxy/templates/wsproxy-labels.j2 index 06a879b9c..5f0c94322 100644 --- a/roles/custom/matrix-bridge-mautrix-wsproxy/templates/wsproxy-labels.j2 +++ b/roles/custom/matrix-bridge-mautrix-wsproxy/templates/wsproxy-labels.j2 @@ -4,37 +4,37 @@ SPDX-FileCopyrightText: 2023 Johan Swetzén SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_mautrix_wsproxy_container_labels_traefik_enabled %} +{% if matrix_bridge_mautrix_wsproxy_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_mautrix_wsproxy_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_mautrix_wsproxy_container_labels_traefik_docker_network }} +{% if matrix_bridge_mautrix_wsproxy_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_mautrix_wsproxy_container_labels_traefik_docker_network }} {% endif %} {% set middlewares = [] %} -{% if matrix_mautrix_wsproxy_container_labels_traefik_additional_response_headers.keys() | length > 0 %} -{% for name, value in matrix_mautrix_wsproxy_container_labels_traefik_additional_response_headers.items() %} +{% if matrix_bridge_mautrix_wsproxy_container_labels_traefik_additional_response_headers.keys() | length > 0 %} +{% for name, value in matrix_bridge_mautrix_wsproxy_container_labels_traefik_additional_response_headers.items() %} traefik.http.middlewares.matrix-mautrix-wsproxy-add-headers.headers.customresponseheaders.{{ name }}={{ value }} {% endfor %} {% set middlewares = middlewares + ['matrix-mautrix-wsproxy-add-headers'] %} {% endif %} -traefik.http.routers.matrix-mautrix-wsproxy.rule={{ matrix_mautrix_wsproxy_container_labels_traefik_rule }} -{% if matrix_mautrix_wsproxy_container_labels_traefik_priority | int > 0 %} -traefik.http.routers.matrix-mautrix-wsproxy.priority={{ matrix_mautrix_wsproxy_container_labels_traefik_priority }} +traefik.http.routers.matrix-mautrix-wsproxy.rule={{ matrix_bridge_mautrix_wsproxy_container_labels_traefik_rule }} +{% if matrix_bridge_mautrix_wsproxy_container_labels_traefik_priority | int > 0 %} +traefik.http.routers.matrix-mautrix-wsproxy.priority={{ matrix_bridge_mautrix_wsproxy_container_labels_traefik_priority }} {% endif %} traefik.http.routers.matrix-mautrix-wsproxy.service=matrix-mautrix-wsproxy {% if middlewares | length > 0 %} traefik.http.routers.matrix-mautrix-wsproxy.middlewares={{ middlewares | join(',') }} {% endif %} -traefik.http.routers.matrix-mautrix-wsproxy.entrypoints={{ matrix_mautrix_wsproxy_container_labels_traefik_entrypoints }} -traefik.http.routers.matrix-mautrix-wsproxy.tls={{ matrix_mautrix_wsproxy_container_labels_traefik_tls | to_json }} -{% if matrix_mautrix_wsproxy_container_labels_traefik_tls %} -traefik.http.routers.matrix-mautrix-wsproxy.tls.certResolver={{ matrix_mautrix_wsproxy_container_labels_traefik_tls_certResolver }} +traefik.http.routers.matrix-mautrix-wsproxy.entrypoints={{ matrix_bridge_mautrix_wsproxy_container_labels_traefik_entrypoints }} +traefik.http.routers.matrix-mautrix-wsproxy.tls={{ matrix_bridge_mautrix_wsproxy_container_labels_traefik_tls | to_json }} +{% if matrix_bridge_mautrix_wsproxy_container_labels_traefik_tls %} +traefik.http.routers.matrix-mautrix-wsproxy.tls.certResolver={{ matrix_bridge_mautrix_wsproxy_container_labels_traefik_tls_certResolver }} {% endif %} -traefik.http.services.matrix-mautrix-wsproxy.loadbalancer.server.port={{ matrix_mautrix_wsproxy_port }} +traefik.http.services.matrix-mautrix-wsproxy.loadbalancer.server.port={{ matrix_bridge_mautrix_wsproxy_port }} {% endif %} -{{ matrix_mautrix_wsproxy_container_labels_additional_labels }} +{{ matrix_bridge_mautrix_wsproxy_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-meshtastic-relay/defaults/main.yml b/roles/custom/matrix-bridge-meshtastic-relay/defaults/main.yml new file mode 100644 index 000000000..ef2fddc3c --- /dev/null +++ b/roles/custom/matrix-bridge-meshtastic-relay/defaults/main.yml @@ -0,0 +1,201 @@ +# SPDX-FileCopyrightText: 2025 - 2026 luschmar +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# matrix-meshtastic-relay is a Matrix <-> Meshtastic bridge. +# Project source code URL: https://github.com/jeremiah-k/meshtastic-matrix-relay + +matrix_bridge_meshtastic_relay_enabled: true + +# renovate: datasource=docker depName=jeremiah-k/mmrelay packageName=ghcr.io/jeremiah-k/mmrelay +matrix_bridge_meshtastic_relay_version: 1.4.0 +matrix_bridge_meshtastic_relay_container_image: "{{ matrix_bridge_meshtastic_relay_container_image_registry_prefix }}jeremiah-k/mmrelay:{{ matrix_bridge_meshtastic_relay_version }}" +matrix_bridge_meshtastic_relay_container_image_registry_prefix: "{{ matrix_bridge_meshtastic_relay_container_image_registry_prefix_upstream }}" +matrix_bridge_meshtastic_relay_container_image_registry_prefix_upstream: "{{ matrix_bridge_meshtastic_relay_container_image_registry_prefix_upstream_default }}" +matrix_bridge_meshtastic_relay_container_image_registry_prefix_upstream_default: "ghcr.io/" + +matrix_bridge_meshtastic_relay_base_path: "{{ matrix_base_data_path }}/meshtastic-relay" + +# Holds the Ansible-managed `config.yaml`. Mounted read-only at `/config` in the +# container; mmrelay is pointed at `/config/config.yaml` via the `--config` CLI flag. +matrix_bridge_meshtastic_relay_config_path: "{{ matrix_bridge_meshtastic_relay_base_path }}/config" + +# Runtime data directory. Mounted read-write at `/data` (MMRELAY_HOME) in the container. +# mmrelay auto-creates `database/`, `logs/`, `matrix/` (credentials + E2EE store) +# and `plugins/` subdirectories underneath as needed. +matrix_bridge_meshtastic_relay_data_path: "{{ matrix_bridge_meshtastic_relay_base_path }}/data" + +matrix_bridge_meshtastic_relay_container_network: "" + +matrix_bridge_meshtastic_relay_container_additional_networks: "{{ matrix_bridge_meshtastic_relay_container_additional_networks_auto + matrix_bridge_meshtastic_relay_container_additional_networks_custom }}" +matrix_bridge_meshtastic_relay_container_additional_networks_auto: [] +matrix_bridge_meshtastic_relay_container_additional_networks_custom: [] + +# A list of extra arguments to pass to the container +matrix_bridge_meshtastic_relay_container_extra_arguments: [] + +# List of systemd services that matrix-meshtastic-relay.service depends on. +matrix_bridge_meshtastic_relay_systemd_required_services_list: "{{ matrix_bridge_meshtastic_relay_systemd_required_services_list_default + matrix_bridge_meshtastic_relay_systemd_required_services_list_auto + matrix_bridge_meshtastic_relay_systemd_required_services_list_custom }}" +matrix_bridge_meshtastic_relay_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_meshtastic_relay_systemd_required_services_list_auto: [] +matrix_bridge_meshtastic_relay_systemd_required_services_list_custom: [] + +# List of systemd services that matrix-meshtastic-relay.service wants +matrix_bridge_meshtastic_relay_systemd_wanted_services_list: [] + +# Hostname of the Matrix homeserver the bot connects to. +matrix_bridge_meshtastic_relay_matrix_host: "" + +# URL of the Matrix homeserver the bot connects to. +matrix_bridge_meshtastic_relay_matrix_homeserver_url: "https://{{ matrix_bridge_meshtastic_relay_matrix_host }}" + +# Fully-qualified Matrix ID of the bot user. +matrix_bridge_meshtastic_relay_matrix_bot_user_id: "@meshtasticbot:{{ matrix_bridge_meshtastic_relay_matrix_host }}" + +# Password for the bot's Matrix account. +# On first startup, mmrelay uses this to log in and persist credentials (including E2EE +# material) under `{{ matrix_bridge_meshtastic_relay_data_path }}/matrix/` on the host. After +# that, the password can (and should) be cleared from configuration. +matrix_bridge_meshtastic_relay_matrix_bot_password: "" + +# Controls whether End-to-End Encryption is enabled. +# Requires password-based login on first start so that mmrelay can create `credentials.json`. +matrix_bridge_meshtastic_relay_e2ee_enabled: true + +# Connection type to the Meshtastic device. One of: "tcp", "serial", "ble". +matrix_bridge_meshtastic_relay_connection_type: "" + +# For `tcp` connection type: hostname/IP of the Meshtastic device to connect to. +matrix_bridge_meshtastic_relay_tcp_host: "meshtastic.local" + +# For `serial` connection type: path of the serial device to connect to. +# This device is passed through to the container. The host must have it available. +matrix_bridge_meshtastic_relay_serial_port: "/dev/ttyUSB0" + +# For `ble` connection type: BLE MAC address of the Meshtastic device to connect to. +# BLE requires `--network=host` and a DBus bind-mount (see the systemd service template). +matrix_bridge_meshtastic_relay_ble_address: "AA:BB:CC:DD:EE:FF" + +# Display name of the Meshtastic network. +matrix_bridge_meshtastic_relay_meshnet_name: "MediumFast" + +# Whether relaying from Matrix to Meshtastic is enabled. +matrix_bridge_meshtastic_relay_meshtastic_broadcast_enabled: true + +# Matrix rooms to bridge to Meshtastic channels. +# Each entry should have an `id` (Matrix room alias or room ID) and a `meshtastic_channel`. +matrix_bridge_meshtastic_relay_matrix_rooms_list: + - id: "#meshtastic:{{ matrix_bridge_meshtastic_relay_matrix_host }}" + meshtastic_channel: "0" + +# Whether plugins should only respond when the bot is explicitly mentioned. +matrix_bridge_meshtastic_relay_plugin_global_require_bot_mention: true + +# Enabled built-in ("core") plugins. +# See: https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki/Core-Plugins +matrix_bridge_meshtastic_relay_plugins_ping_enabled: true +matrix_bridge_meshtastic_relay_plugins_health_enabled: true +matrix_bridge_meshtastic_relay_plugins_weather_enabled: true +matrix_bridge_meshtastic_relay_plugins_weather_units: metric +matrix_bridge_meshtastic_relay_plugins_telemetry_enabled: true +matrix_bridge_meshtastic_relay_plugins_map_enabled: true +matrix_bridge_meshtastic_relay_plugins_nodes_enabled: true + +# Default configuration passed to the bridge via config.yaml. +# See `../templates/config.yaml.j2` for what's rendered. +# Use `matrix_bridge_meshtastic_relay_configuration_extension_yaml` to override +# specific values or add/remove keys without having to maintain a full copy here. +matrix_bridge_meshtastic_relay_configuration_default: + matrix: + homeserver: "{{ matrix_bridge_meshtastic_relay_matrix_homeserver_url }}" + password: "{{ matrix_bridge_meshtastic_relay_matrix_bot_password }}" + bot_user_id: "{{ matrix_bridge_meshtastic_relay_matrix_bot_user_id }}" + e2ee: + enabled: "{{ matrix_bridge_meshtastic_relay_e2ee_enabled }}" + matrix_rooms: "{{ matrix_bridge_meshtastic_relay_matrix_rooms_list }}" + meshtastic: "{{ matrix_bridge_meshtastic_relay_meshtastic_configuration }}" + logging: + level: info + log_to_file: false + database: + enable_wal: true + busy_timeout_ms: 5000 + pragmas: + synchronous: NORMAL + temp_store: MEMORY + msg_map: + msgs_to_keep: 500 + wipe_on_restart: true + plugins: + require_bot_mention: "{{ matrix_bridge_meshtastic_relay_plugin_global_require_bot_mention }}" + ping: + active: "{{ matrix_bridge_meshtastic_relay_plugins_ping_enabled }}" + health: + active: "{{ matrix_bridge_meshtastic_relay_plugins_health_enabled }}" + weather: + active: "{{ matrix_bridge_meshtastic_relay_plugins_weather_enabled }}" + units: "{{ matrix_bridge_meshtastic_relay_plugins_weather_units }}" + telemetry: + active: "{{ matrix_bridge_meshtastic_relay_plugins_telemetry_enabled }}" + map: + active: "{{ matrix_bridge_meshtastic_relay_plugins_map_enabled }}" + nodes: + active: "{{ matrix_bridge_meshtastic_relay_plugins_nodes_enabled }}" + +# Connection-type-specific `meshtastic` configuration block used by +# `matrix_bridge_meshtastic_relay_configuration_default`. +matrix_bridge_meshtastic_relay_meshtastic_configuration: | + {{ + ( + {'connection_type': 'tcp', 'host': matrix_bridge_meshtastic_relay_tcp_host} + if matrix_bridge_meshtastic_relay_connection_type == 'tcp' else + ( + {'connection_type': 'serial', 'serial_port': matrix_bridge_meshtastic_relay_serial_port} + if matrix_bridge_meshtastic_relay_connection_type == 'serial' else + ( + {'connection_type': 'ble', 'ble_address': matrix_bridge_meshtastic_relay_ble_address} + if matrix_bridge_meshtastic_relay_connection_type == 'ble' else {} + ) + ) + ) | combine({ + 'meshnet_name': matrix_bridge_meshtastic_relay_meshnet_name, + 'broadcast_enabled': matrix_bridge_meshtastic_relay_meshtastic_broadcast_enabled, + 'message_interactions': { + 'reactions': false, + 'replies': false, + }, + }) + }} + +# Holds additional configuration values that get merged into the default +# configuration (see `matrix_bridge_meshtastic_relay_configuration_default`). +# +# If you need something more special, you can take full control by changing +# `matrix_bridge_meshtastic_relay_configuration` directly. +matrix_bridge_meshtastic_relay_configuration_extension_yaml: | + # Your custom YAML configuration goes here. + # This configuration extends the default starting configuration (`matrix_bridge_meshtastic_relay_configuration_default`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by + # redefining `matrix_bridge_meshtastic_relay_configuration` directly. + +matrix_bridge_meshtastic_relay_configuration_extension: "{{ matrix_bridge_meshtastic_relay_configuration_extension_yaml | from_yaml if matrix_bridge_meshtastic_relay_configuration_extension_yaml | from_yaml is mapping else {} }}" + +# Holds the final configuration rendered to `config.yaml`. +# Normally, you don't need to change this variable — use +# `matrix_bridge_meshtastic_relay_configuration_extension_yaml` instead. +matrix_bridge_meshtastic_relay_configuration: "{{ matrix_bridge_meshtastic_relay_configuration_default | combine(matrix_bridge_meshtastic_relay_configuration_extension, recursive=True) }}" + +# matrix_bridge_meshtastic_relay_restart_necessary controls whether the service +# will be restarted (when true) or merely started (when false) by the +# systemd service manager role (when conditional restart is enabled). +# +# This value is automatically computed during installation based on whether +# any configuration files, the systemd service file, or the container image changed. +# The default of `false` means "no restart needed" — appropriate when the role's +# installation tasks haven't run (e.g., due to --tags skipping them). +matrix_bridge_meshtastic_relay_restart_necessary: false diff --git a/roles/custom/matrix-bridge-meshtastic-relay/tasks/main.yml b/roles/custom/matrix-bridge-meshtastic-relay/tasks/main.yml new file mode 100644 index 000000000..957dc456a --- /dev/null +++ b/roles/custom/matrix-bridge-meshtastic-relay/tasks/main.yml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2025 - 2026 luschmar +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- tags: + - setup-all + - setup-meshtastic-relay + - install-all + - install-meshtastic-relay + block: + - when: matrix_bridge_meshtastic_relay_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" + + - when: matrix_bridge_meshtastic_relay_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" + +- tags: + - setup-all + - setup-meshtastic-relay + block: + - when: not matrix_bridge_meshtastic_relay_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-meshtastic-relay/tasks/setup_install.yml b/roles/custom/matrix-bridge-meshtastic-relay/tasks/setup_install.yml new file mode 100644 index 000000000..184ef5826 --- /dev/null +++ b/roles/custom/matrix-bridge-meshtastic-relay/tasks/setup_install.yml @@ -0,0 +1,62 @@ +# SPDX-FileCopyrightText: 2025 - 2026 luschmar +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Ensure matrix-meshtastic-relay image is pulled + community.docker.docker_image_pull: + name: "{{ matrix_bridge_meshtastic_relay_container_image }}" + pull: always + register: matrix_bridge_meshtastic_relay_container_image_pull_result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: matrix_bridge_meshtastic_relay_container_image_pull_result is not failed + +- name: Ensure matrix-meshtastic-relay paths exist + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: '0750' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - "{{ matrix_bridge_meshtastic_relay_base_path }}" + - "{{ matrix_bridge_meshtastic_relay_config_path }}" + - "{{ matrix_bridge_meshtastic_relay_data_path }}" + +- name: Ensure matrix-meshtastic-relay config.yaml is installed + ansible.builtin.copy: + content: "{{ matrix_bridge_meshtastic_relay_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_meshtastic_relay_config_path }}/config.yaml" + mode: '0600' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bridge_meshtastic_relay_config_result + +- name: Ensure matrix-meshtastic-relay container network is created + when: + - matrix_bridge_meshtastic_relay_connection_type != 'ble' + - matrix_bridge_meshtastic_relay_container_network != 'host' + community.general.docker_network: + enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" + name: "{{ matrix_bridge_meshtastic_relay_container_network }}" + driver: bridge + driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" + +- name: Ensure matrix-meshtastic-relay.service installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-meshtastic-relay.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-meshtastic-relay.service" + mode: '0644' + register: matrix_bridge_meshtastic_relay_systemd_service_result + +- name: Determine whether matrix-meshtastic-relay needs a restart + ansible.builtin.set_fact: + matrix_bridge_meshtastic_relay_restart_necessary: >- + {{ + matrix_bridge_meshtastic_relay_config_result.changed | default(false) + or matrix_bridge_meshtastic_relay_systemd_service_result.changed | default(false) + or matrix_bridge_meshtastic_relay_container_image_pull_result.changed | default(false) + }} diff --git a/roles/custom/matrix-bridge-meshtastic-relay/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-meshtastic-relay/tasks/setup_uninstall.yml new file mode 100644 index 000000000..fe475262f --- /dev/null +++ b/roles/custom/matrix-bridge-meshtastic-relay/tasks/setup_uninstall.yml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2025 - 2026 luschmar +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Check existence of matrix-meshtastic-relay service + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-meshtastic-relay.service" + register: matrix_bridge_meshtastic_relay_service_stat + +- when: matrix_bridge_meshtastic_relay_service_stat.stat.exists | bool + block: + - name: Ensure matrix-meshtastic-relay is stopped + ansible.builtin.service: + name: matrix-meshtastic-relay + state: stopped + enabled: false + daemon_reload: true + + - name: Ensure matrix-meshtastic-relay.service doesn't exist + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-meshtastic-relay.service" + state: absent diff --git a/roles/custom/matrix-bridge-meshtastic-relay/tasks/validate_config.yml b/roles/custom/matrix-bridge-meshtastic-relay/tasks/validate_config.yml new file mode 100644 index 000000000..face586be --- /dev/null +++ b/roles/custom/matrix-bridge-meshtastic-relay/tasks/validate_config.yml @@ -0,0 +1,31 @@ +# SPDX-FileCopyrightText: 2025 - 2026 luschmar +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Fail if required matrix-meshtastic-relay settings not defined + ansible.builtin.fail: + msg: >- + You need to define a required configuration setting (`{{ item.name }}`). + when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" + with_items: + - {'name': 'matrix_bridge_meshtastic_relay_matrix_host', when: true} + - {'name': 'matrix_bridge_meshtastic_relay_matrix_bot_password', when: true} + - {'name': 'matrix_bridge_meshtastic_relay_connection_type', when: true} + +- name: Fail if matrix_bridge_meshtastic_relay_connection_type is invalid + ansible.builtin.fail: + msg: >- + `matrix_bridge_meshtastic_relay_connection_type` must be one of: `tcp`, `serial`, `ble`. + Got: `{{ matrix_bridge_meshtastic_relay_connection_type }}`. + when: "matrix_bridge_meshtastic_relay_connection_type not in ['tcp', 'serial', 'ble']" + +- name: (Deprecation) Catch and report renamed matrix-meshtastic-relay variables + ansible.builtin.fail: + msg: >- + The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_bridge_meshtastic_relay_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-bridge-meshtastic-relay/templates/systemd/matrix-meshtastic-relay.service.j2 b/roles/custom/matrix-bridge-meshtastic-relay/templates/systemd/matrix-meshtastic-relay.service.j2 new file mode 100644 index 000000000..dfc2110de --- /dev/null +++ b/roles/custom/matrix-bridge-meshtastic-relay/templates/systemd/matrix-meshtastic-relay.service.j2 @@ -0,0 +1,61 @@ +#jinja2: lstrip_blocks: True +[Unit] +Description=Matrix <-> Meshtastic bridge +{% for service in matrix_bridge_meshtastic_relay_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_bridge_meshtastic_relay_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[Service] +Type=simple +Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" +ExecStartPre=-{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-meshtastic-relay +ExecStartPre=-{{ devture_systemd_docker_base_host_command_docker }} rm matrix-meshtastic-relay + +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ + --rm \ + --name=matrix-meshtastic-relay \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --tmpfs=/tmp:rw,noexec,nosuid,size=50m \ + --tmpfs=/.cache:rw,noexec,nosuid,size=50m \ + --mount type=bind,src={{ matrix_bridge_meshtastic_relay_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_meshtastic_relay_data_path }},dst=/data \ + {% if matrix_bridge_meshtastic_relay_connection_type == 'ble' %} + --network=host \ + --security-opt apparmor=unconfined \ + --mount type=bind,src=/var/run/dbus,dst=/var/run/dbus,ro \ + {% else %} + --network={{ matrix_bridge_meshtastic_relay_container_network }} \ + {% endif %} + {% if matrix_bridge_meshtastic_relay_connection_type == 'serial' %} + --device={{ matrix_bridge_meshtastic_relay_serial_port }} \ + {% endif %} + {% for arg in matrix_bridge_meshtastic_relay_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_bridge_meshtastic_relay_container_image }} \ + mmrelay --config /config/config.yaml + +{% if matrix_bridge_meshtastic_relay_container_network != 'host' %} +{% for network in matrix_bridge_meshtastic_relay_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-meshtastic-relay +{% endfor %} +{% endif %} + +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-meshtastic-relay + +ExecStop=-{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-meshtastic-relay +ExecStop=-{{ devture_systemd_docker_base_host_command_docker }} rm matrix-meshtastic-relay +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-meshtastic-relay + +[Install] +WantedBy=multi-user.target diff --git a/roles/custom/matrix-bridge-meshtastic-relay/templates/systemd/matrix-meshtastic-relay.service.j2.license b/roles/custom/matrix-bridge-meshtastic-relay/templates/systemd/matrix-meshtastic-relay.service.j2.license new file mode 100644 index 000000000..59b1edbf7 --- /dev/null +++ b/roles/custom/matrix-bridge-meshtastic-relay/templates/systemd/matrix-meshtastic-relay.service.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2025 - 2026 luschmar +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-mx-puppet-groupme/defaults/main.yml b/roles/custom/matrix-bridge-mx-puppet-groupme/defaults/main.yml index cd78da450..9321516c0 100644 --- a/roles/custom/matrix-bridge-mx-puppet-groupme/defaults/main.yml +++ b/roles/custom/matrix-bridge-mx-puppet-groupme/defaults/main.yml @@ -13,131 +13,130 @@ # Mx Puppet GroupMe is a Matrix <-> GroupMe bridge # Project source code URL: https://gitlab.com/xangelix-pub/matrix/mx-puppet-groupme -matrix_mx_puppet_groupme_enabled: true +matrix_bridge_mx_puppet_groupme_enabled: true -matrix_mx_puppet_groupme_container_image_self_build: false -matrix_mx_puppet_groupme_container_image_self_build_repo: "https://gitlab.com/xangelix-pub/matrix/mx-puppet-groupme" -matrix_mx_puppet_groupme_container_image_self_build_repo_version: "{{ 'main' if matrix_mx_puppet_groupme_version == 'latest' else matrix_mx_puppet_groupme_version }}" +matrix_bridge_mx_puppet_groupme_container_image_self_build: false +matrix_bridge_mx_puppet_groupme_container_image_self_build_repo: "https://gitlab.com/xangelix-pub/matrix/mx-puppet-groupme" +matrix_bridge_mx_puppet_groupme_container_image_self_build_repo_version: "{{ 'main' if matrix_bridge_mx_puppet_groupme_version == 'latest' else matrix_bridge_mx_puppet_groupme_version }}" # Controls whether the mx-puppet-groupme container exposes its HTTP port (tcp/8437 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:8437"), or empty string to not expose. -matrix_mx_puppet_groupme_container_http_host_bind_port: '' +matrix_bridge_mx_puppet_groupme_container_http_host_bind_port: '' -matrix_mx_puppet_groupme_version: 533cccc8 -matrix_mx_puppet_groupme_container_image: "{{ matrix_mx_puppet_groupme_container_image_registry_prefix }}xangelix-pub/matrix/mx-puppet-groupme:{{ matrix_mx_puppet_groupme_version }}" -matrix_mx_puppet_groupme_container_image_registry_prefix: "{{ 'localhost/' if matrix_mx_puppet_groupme_container_image_self_build else matrix_mx_puppet_groupme_container_image_registry_prefix_upstream }}" -matrix_mx_puppet_groupme_container_image_registry_prefix_upstream: "{{ matrix_mx_puppet_groupme_container_image_registry_prefix_upstream_default }}" -matrix_mx_puppet_groupme_container_image_registry_prefix_upstream_default: "registry.gitlab.com/" -matrix_mx_puppet_groupme_container_image_force_pull: "{{ matrix_mx_puppet_groupme_container_image.endswith(':latest') }}" +matrix_bridge_mx_puppet_groupme_version: 533cccc8 +matrix_bridge_mx_puppet_groupme_container_image: "{{ matrix_bridge_mx_puppet_groupme_container_image_registry_prefix }}xangelix-pub/matrix/mx-puppet-groupme:{{ matrix_bridge_mx_puppet_groupme_version }}" +matrix_bridge_mx_puppet_groupme_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mx_puppet_groupme_container_image_self_build else matrix_bridge_mx_puppet_groupme_container_image_registry_prefix_upstream }}" +matrix_bridge_mx_puppet_groupme_container_image_registry_prefix_upstream: "{{ matrix_bridge_mx_puppet_groupme_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mx_puppet_groupme_container_image_registry_prefix_upstream_default: "registry.gitlab.com/" -matrix_mx_puppet_groupme_base_path: "{{ matrix_base_data_path }}/mx-puppet-groupme" -matrix_mx_puppet_groupme_config_path: "{{ matrix_mx_puppet_groupme_base_path }}/config" -matrix_mx_puppet_groupme_data_path: "{{ matrix_mx_puppet_groupme_base_path }}/data" -matrix_mx_puppet_groupme_container_src_files_path: "{{ matrix_mx_puppet_groupme_base_path }}/docker-src" +matrix_bridge_mx_puppet_groupme_base_path: "{{ matrix_base_data_path }}/mx-puppet-groupme" +matrix_bridge_mx_puppet_groupme_config_path: "{{ matrix_bridge_mx_puppet_groupme_base_path }}/config" +matrix_bridge_mx_puppet_groupme_data_path: "{{ matrix_bridge_mx_puppet_groupme_base_path }}/data" +matrix_bridge_mx_puppet_groupme_container_src_files_path: "{{ matrix_bridge_mx_puppet_groupme_base_path }}/docker-src" -matrix_mx_puppet_groupme_appservice_port: "8437" +matrix_bridge_mx_puppet_groupme_appservice_port: "8437" -matrix_mx_puppet_groupme_homeserver_address: "" -matrix_mx_puppet_groupme_homeserver_domain: '{{ matrix_domain }}' -matrix_mx_puppet_groupme_appservice_address: 'http://matrix-mx-puppet-groupme:{{ matrix_mx_puppet_groupme_appservice_port }}' +matrix_bridge_mx_puppet_groupme_homeserver_address: "" +matrix_bridge_mx_puppet_groupme_homeserver_domain: '{{ matrix_domain }}' +matrix_bridge_mx_puppet_groupme_appservice_address: 'http://matrix-mx-puppet-groupme:{{ matrix_bridge_mx_puppet_groupme_appservice_port }}' # "@alice:example.com" to allow a specific user # "@.*:example.com" to allow users on a specific homeserver # "@.*" to allow anyone -matrix_mx_puppet_groupme_provisioning_whitelist: +matrix_bridge_mx_puppet_groupme_provisioning_whitelist: - "@.*:{{ matrix_domain | regex_escape }}" # Leave empty to disable blacklist # "@bob:example.com" to disallow a specific user # "@.*:example.com" to disallow users on a specific homeserver -matrix_mx_puppet_groupme_provisioning_blacklist: [] +matrix_bridge_mx_puppet_groupme_provisioning_blacklist: [] -matrix_mx_puppet_groupme_container_network: "" +matrix_bridge_mx_puppet_groupme_container_network: "" -matrix_mx_puppet_groupme_container_additional_networks: "{{ matrix_mx_puppet_groupme_container_additional_networks_auto + matrix_mx_puppet_groupme_container_additional_networks_custom }}" -matrix_mx_puppet_groupme_container_additional_networks_auto: [] -matrix_mx_puppet_groupme_container_additional_networks_custom: [] +matrix_bridge_mx_puppet_groupme_container_additional_networks: "{{ matrix_bridge_mx_puppet_groupme_container_additional_networks_auto + matrix_bridge_mx_puppet_groupme_container_additional_networks_custom }}" +matrix_bridge_mx_puppet_groupme_container_additional_networks_auto: [] +matrix_bridge_mx_puppet_groupme_container_additional_networks_custom: [] # A list of extra arguments to pass to the container -matrix_mx_puppet_groupme_container_extra_arguments: [] +matrix_bridge_mx_puppet_groupme_container_extra_arguments: [] # List of systemd services that matrix-puppet-groupme.service depends on. -matrix_mx_puppet_groupme_systemd_required_services_list: "{{ matrix_mx_puppet_groupme_systemd_required_services_list_default + matrix_mx_puppet_groupme_systemd_required_services_list_auto + matrix_mx_puppet_groupme_systemd_required_services_list_custom }}" -matrix_mx_puppet_groupme_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mx_puppet_groupme_systemd_required_services_list_auto: [] -matrix_mx_puppet_groupme_systemd_required_services_list_custom: [] +matrix_bridge_mx_puppet_groupme_systemd_required_services_list: "{{ matrix_bridge_mx_puppet_groupme_systemd_required_services_list_default + matrix_bridge_mx_puppet_groupme_systemd_required_services_list_auto + matrix_bridge_mx_puppet_groupme_systemd_required_services_list_custom }}" +matrix_bridge_mx_puppet_groupme_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mx_puppet_groupme_systemd_required_services_list_auto: [] +matrix_bridge_mx_puppet_groupme_systemd_required_services_list_custom: [] # List of systemd services that matrix-puppet-groupme.service wants -matrix_mx_puppet_groupme_systemd_wanted_services_list: [] +matrix_bridge_mx_puppet_groupme_systemd_wanted_services_list: [] -matrix_mx_puppet_groupme_appservice_token: '' -matrix_mx_puppet_groupme_homeserver_token: '' +matrix_bridge_mx_puppet_groupme_appservice_token: '' +matrix_bridge_mx_puppet_groupme_homeserver_token: '' # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). -matrix_mx_puppet_groupme_login_shared_secret: '' +matrix_bridge_mx_puppet_groupme_login_shared_secret: '' -matrix_mx_puppet_groupme_presence_enabled: true -matrix_mx_puppet_groupme_presence_interval: 5000 +matrix_bridge_mx_puppet_groupme_presence_enabled: true +matrix_bridge_mx_puppet_groupme_presence_interval: 5000 -matrix_mx_puppet_groupme_database_engine: sqlite +matrix_bridge_mx_puppet_groupme_database_engine: sqlite -matrix_mx_puppet_groupme_sqlite_database_path_local: "{{ matrix_mx_puppet_groupme_data_path }}/database.db" -matrix_mx_puppet_groupme_sqlite_database_path_in_container: "/data/database.db" +matrix_bridge_mx_puppet_groupme_sqlite_database_path_local: "{{ matrix_bridge_mx_puppet_groupme_data_path }}/database.db" +matrix_bridge_mx_puppet_groupme_sqlite_database_path_in_container: "/data/database.db" -matrix_mx_puppet_groupme_database_username: matrix_mx_puppet_groupme -matrix_mx_puppet_groupme_database_password: ~ -matrix_mx_puppet_groupme_database_hostname: '' -matrix_mx_puppet_groupme_database_port: 5432 -matrix_mx_puppet_groupme_database_name: matrix_mx_puppet_groupme -matrix_mx_puppet_groupme_database_sslmode: disable +matrix_bridge_mx_puppet_groupme_database_username: matrix_mx_puppet_groupme +matrix_bridge_mx_puppet_groupme_database_password: ~ +matrix_bridge_mx_puppet_groupme_database_hostname: '' +matrix_bridge_mx_puppet_groupme_database_port: 5432 +matrix_bridge_mx_puppet_groupme_database_name: matrix_mx_puppet_groupme +matrix_bridge_mx_puppet_groupme_database_sslmode: disable -matrix_mx_puppet_groupme_database_connection_string: 'postgresql://{{ matrix_mx_puppet_groupme_database_username }}:{{ matrix_mx_puppet_groupme_database_password }}@{{ matrix_mx_puppet_groupme_database_hostname }}:{{ matrix_mx_puppet_groupme_database_port }}/{{ matrix_mx_puppet_groupme_database_name }}?sslmode={{ matrix_mx_puppet_groupme_database_sslmode }}' +matrix_bridge_mx_puppet_groupme_database_connection_string: 'postgresql://{{ matrix_bridge_mx_puppet_groupme_database_username }}:{{ matrix_bridge_mx_puppet_groupme_database_password }}@{{ matrix_bridge_mx_puppet_groupme_database_hostname }}:{{ matrix_bridge_mx_puppet_groupme_database_port }}/{{ matrix_bridge_mx_puppet_groupme_database_name }}?sslmode={{ matrix_bridge_mx_puppet_groupme_database_sslmode }}' # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mx_puppet_groupme_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mx_puppet_groupme_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mx_puppet_groupme_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mx_puppet_groupme_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mx_puppet_groupme_configuration_extension_yaml: | +matrix_bridge_mx_puppet_groupme_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mx_puppet_groupme_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mx_puppet_groupme_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mx_puppet_groupme_configuration_yaml`. + # completely redefining `matrix_bridge_mx_puppet_groupme_configuration_yaml`. -matrix_mx_puppet_groupme_configuration_extension: "{{ matrix_mx_puppet_groupme_configuration_extension_yaml | from_yaml if matrix_mx_puppet_groupme_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mx_puppet_groupme_configuration_extension: "{{ matrix_bridge_mx_puppet_groupme_configuration_extension_yaml | from_yaml if matrix_bridge_mx_puppet_groupme_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mx_puppet_groupme_configuration_yaml`. -matrix_mx_puppet_groupme_configuration: "{{ matrix_mx_puppet_groupme_configuration_yaml | from_yaml | combine(matrix_mx_puppet_groupme_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mx_puppet_groupme_configuration_yaml`. +matrix_bridge_mx_puppet_groupme_configuration: "{{ matrix_bridge_mx_puppet_groupme_configuration_yaml | from_yaml | combine(matrix_bridge_mx_puppet_groupme_configuration_extension, recursive=True) }}" -matrix_mx_puppet_groupme_registration_yaml: | - as_token: "{{ matrix_mx_puppet_groupme_appservice_token }}" - hs_token: "{{ matrix_mx_puppet_groupme_homeserver_token }}" +matrix_bridge_mx_puppet_groupme_registration_yaml: | + as_token: "{{ matrix_bridge_mx_puppet_groupme_appservice_token }}" + hs_token: "{{ matrix_bridge_mx_puppet_groupme_homeserver_token }}" id: groupme-puppet namespaces: users: - exclusive: true - regex: '@_groupmepuppet_.*:{{ matrix_mx_puppet_groupme_homeserver_domain | regex_escape }}' + regex: '@_groupmepuppet_.*:{{ matrix_bridge_mx_puppet_groupme_homeserver_domain | regex_escape }}' rooms: [] aliases: - exclusive: true - regex: '#_groupmepuppet_.*:{{ matrix_mx_puppet_groupme_homeserver_domain | regex_escape }}' + regex: '#_groupmepuppet_.*:{{ matrix_bridge_mx_puppet_groupme_homeserver_domain | regex_escape }}' protocols: [] rate_limited: false sender_localpart: _groupmepuppet_bot - url: {{ matrix_mx_puppet_groupme_appservice_address }} + url: {{ matrix_bridge_mx_puppet_groupme_appservice_address }} de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true -matrix_mx_puppet_groupme_registration: "{{ matrix_mx_puppet_groupme_registration_yaml | from_yaml }}" +matrix_bridge_mx_puppet_groupme_registration: "{{ matrix_bridge_mx_puppet_groupme_registration_yaml | from_yaml }}" -# matrix_mx_puppet_groupme_restart_necessary controls whether the service +# matrix_bridge_mx_puppet_groupme_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -145,4 +144,4 @@ matrix_mx_puppet_groupme_registration: "{{ matrix_mx_puppet_groupme_registration # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mx_puppet_groupme_restart_necessary: false +matrix_bridge_mx_puppet_groupme_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/main.yml b/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/main.yml index 8b6e0be39..f6c629960 100644 --- a/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/main.yml +++ b/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/main.yml @@ -12,15 +12,15 @@ - install-all - install-mx-puppet-groupme block: - - when: matrix_mx_puppet_groupme_enabled | bool + - when: matrix_bridge_mx_puppet_groupme_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mx_puppet_groupme_enabled | bool + - when: matrix_bridge_mx_puppet_groupme_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mx-puppet-groupme block: - - when: not matrix_mx_puppet_groupme_enabled | bool + - when: not matrix_bridge_mx_puppet_groupme_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/setup_install.yml b/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/setup_install.yml index 688ba52e4..43aa99d27 100644 --- a/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/setup_install.yml @@ -18,16 +18,16 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mx_puppet_groupme_base_path }}", when: true} - - {path: "{{ matrix_mx_puppet_groupme_config_path }}", when: true} - - {path: "{{ matrix_mx_puppet_groupme_data_path }}", when: true} - - {path: "{{ matrix_mx_puppet_groupme_container_src_files_path }}", when: "{{ matrix_mx_puppet_groupme_container_image_self_build }}"} - when: matrix_mx_puppet_groupme_enabled | bool and item.when | bool + - {path: "{{ matrix_bridge_mx_puppet_groupme_base_path }}", when: true} + - {path: "{{ matrix_bridge_mx_puppet_groupme_config_path }}", when: true} + - {path: "{{ matrix_bridge_mx_puppet_groupme_data_path }}", when: true} + - {path: "{{ matrix_bridge_mx_puppet_groupme_container_src_files_path }}", when: "{{ matrix_bridge_mx_puppet_groupme_container_image_self_build }}"} + when: matrix_bridge_mx_puppet_groupme_enabled | bool and item.when | bool - name: Check if an old database file already exists ansible.builtin.stat: - path: "{{ matrix_mx_puppet_groupme_base_path }}/database.db" - register: matrix_mx_puppet_groupme_stat_database + path: "{{ matrix_bridge_mx_puppet_groupme_base_path }}/database.db" + register: matrix_bridge_mx_puppet_groupme_stat_database - name: (Data relocation) Ensure matrix-mx-puppet-groupme.service is stopped ansible.builtin.service: @@ -36,99 +36,106 @@ enabled: false daemon_reload: true failed_when: false - when: "matrix_mx_puppet_groupme_stat_database.stat.exists" + when: "matrix_bridge_mx_puppet_groupme_stat_database.stat.exists" - name: (Data relocation) Move mx-puppet-groupme database file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_mx_puppet_groupme_base_path }}/database.db {{ matrix_mx_puppet_groupme_data_path }}/database.db" - creates: "{{ matrix_mx_puppet_groupme_data_path }}/database.db" - removes: "{{ matrix_mx_puppet_groupme_base_path }}/database.db" - when: "matrix_mx_puppet_groupme_stat_database.stat.exists" + cmd: "mv {{ matrix_bridge_mx_puppet_groupme_base_path }}/database.db {{ matrix_bridge_mx_puppet_groupme_data_path }}/database.db" + creates: "{{ matrix_bridge_mx_puppet_groupme_data_path }}/database.db" + removes: "{{ matrix_bridge_mx_puppet_groupme_base_path }}/database.db" + when: "matrix_bridge_mx_puppet_groupme_stat_database.stat.exists" - ansible.builtin.set_fact: - matrix_mx_puppet_groupme_migration_requires_restart: false + matrix_bridge_mx_puppet_groupme_migration_requires_restart: false -- when: "matrix_mx_puppet_groupme_database_engine == 'postgres'" +- when: "matrix_bridge_mx_puppet_groupme_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mx_puppet_groupme_sqlite_database_path_local }}" - register: matrix_mx_puppet_groupme_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mx_puppet_groupme_sqlite_database_path_local }}" + register: matrix_bridge_mx_puppet_groupme_sqlite_database_path_local_stat_result - - when: "matrix_mx_puppet_groupme_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mx_puppet_groupme_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mx_puppet_groupme_sqlite_database_path_local }}" - dst: "{{ matrix_mx_puppet_groupme_database_connection_string }}" + src: "{{ matrix_bridge_mx_puppet_groupme_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mx_puppet_groupme_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mx_puppet_groupme_database_engine' + engine_variable_name: 'matrix_bridge_mx_puppet_groupme_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-mx-puppet-groupme.service'] - ansible.builtin.set_fact: - matrix_mx_puppet_groupme_migration_requires_restart: true + matrix_bridge_mx_puppet_groupme_migration_requires_restart: true - name: Ensure MX Puppet Groupme image is pulled - community.docker.docker_image: - name: "{{ matrix_mx_puppet_groupme_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mx_puppet_groupme_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mx_puppet_groupme_container_image_force_pull }}" - when: matrix_mx_puppet_groupme_enabled | bool and not matrix_mx_puppet_groupme_container_image_self_build - register: matrix_mx_puppet_groupme_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mx_puppet_groupme_container_image }}" + pull: always + when: matrix_bridge_mx_puppet_groupme_enabled | bool and not matrix_bridge_mx_puppet_groupme_container_image_self_build + register: matrix_bridge_mx_puppet_groupme_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mx_puppet_groupme_container_image_pull_result is not failed + until: matrix_bridge_mx_puppet_groupme_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure MX Puppet Groupme repository ownership is correct on self build + ansible.builtin.file: + path: "{{ matrix_bridge_mx_puppet_groupme_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mx_puppet_groupme_enabled | bool and matrix_bridge_mx_puppet_groupme_container_image_self_build" - name: Ensure MX Puppet Groupme repository is present on self build ansible.builtin.git: - repo: "{{ matrix_mx_puppet_groupme_container_image_self_build_repo }}" - version: "{{ matrix_mx_puppet_groupme_container_image_self_build_repo_version }}" - dest: "{{ matrix_mx_puppet_groupme_container_src_files_path }}" + repo: "{{ matrix_bridge_mx_puppet_groupme_container_image_self_build_repo }}" + version: "{{ matrix_bridge_mx_puppet_groupme_container_image_self_build_repo_version }}" + dest: "{{ matrix_bridge_mx_puppet_groupme_container_src_files_path }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mx_puppet_groupme_git_pull_results - when: "matrix_mx_puppet_groupme_enabled | bool and matrix_mx_puppet_groupme_container_image_self_build" + register: matrix_bridge_mx_puppet_groupme_git_pull_results + when: "matrix_bridge_mx_puppet_groupme_enabled | bool and matrix_bridge_mx_puppet_groupme_container_image_self_build" - name: Ensure MX Puppet Groupme Docker image is built - community.docker.docker_image: - name: "{{ matrix_mx_puppet_groupme_container_image }}" - source: build - force_source: "{{ matrix_mx_puppet_groupme_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mx_puppet_groupme_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mx_puppet_groupme_container_src_files_path }}" - pull: true - when: "matrix_mx_puppet_groupme_enabled | bool and matrix_mx_puppet_groupme_container_image_self_build" + community.docker.docker_image_build: + name: "{{ matrix_bridge_mx_puppet_groupme_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mx_puppet_groupme_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mx_puppet_groupme_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mx_puppet_groupme_enabled | bool and matrix_bridge_mx_puppet_groupme_container_image_self_build" + register: matrix_bridge_mx_puppet_groupme_container_image_build_result - name: Ensure mx-puppet-groupme config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mx_puppet_groupme_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mx_puppet_groupme_config_path }}/config.yaml" + content: "{{ matrix_bridge_mx_puppet_groupme_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mx_puppet_groupme_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mx_puppet_groupme_config_result + register: matrix_bridge_mx_puppet_groupme_config_result - name: Ensure mx-puppet-groupme groupme-registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mx_puppet_groupme_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mx_puppet_groupme_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mx_puppet_groupme_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mx_puppet_groupme_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mx_puppet_groupme_registration_result + register: matrix_bridge_mx_puppet_groupme_registration_result - name: Ensure mx-puppet-groupme container network is created + when: matrix_bridge_mx_puppet_groupme_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mx_puppet_groupme_container_network }}" + name: "{{ matrix_bridge_mx_puppet_groupme_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -137,17 +144,18 @@ src: "{{ role_path }}/templates/systemd/matrix-mx-puppet-groupme.service.j2" dest: "/etc/systemd/system/matrix-mx-puppet-groupme.service" mode: '0644' - register: matrix_mx_puppet_groupme_systemd_service_result + register: matrix_bridge_mx_puppet_groupme_systemd_service_result - name: Determine whether matrix-mx-puppet-groupme needs a restart ansible.builtin.set_fact: - matrix_mx_puppet_groupme_restart_necessary: >- + matrix_bridge_mx_puppet_groupme_restart_necessary: >- {{ - matrix_mx_puppet_groupme_migration_requires_restart | default(false) - or matrix_mx_puppet_groupme_config_result.changed | default(false) - or matrix_mx_puppet_groupme_registration_result.changed | default(false) - or matrix_mx_puppet_groupme_systemd_service_result.changed | default(false) - or matrix_mx_puppet_groupme_container_image_pull_result.changed | default(false) + matrix_bridge_mx_puppet_groupme_migration_requires_restart | default(false) + or matrix_bridge_mx_puppet_groupme_config_result.changed | default(false) + or matrix_bridge_mx_puppet_groupme_registration_result.changed | default(false) + or matrix_bridge_mx_puppet_groupme_systemd_service_result.changed | default(false) + or matrix_bridge_mx_puppet_groupme_container_image_pull_result.changed | default(false) + or matrix_bridge_mx_puppet_groupme_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mx-puppet-groupme.service restarted, if necessary @@ -155,4 +163,4 @@ name: "matrix-mx-puppet-groupme.service" state: restarted daemon_reload: true - when: "matrix_mx_puppet_groupme_migration_requires_restart | bool" + when: "matrix_bridge_mx_puppet_groupme_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/setup_uninstall.yml index 6f698ca62..31ee4da0c 100644 --- a/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/setup_uninstall.yml @@ -9,9 +9,9 @@ - name: Check existence of matrix-mx-puppet-groupme service ansible.builtin.stat: path: "/etc/systemd/system/matrix-mx-puppet-groupme.service" - register: matrix_mx_puppet_groupme_service_stat + register: matrix_bridge_mx_puppet_groupme_service_stat -- when: matrix_mx_puppet_groupme_service_stat.stat.exists | bool +- when: matrix_bridge_mx_puppet_groupme_service_stat.stat.exists | bool block: - name: Ensure matrix-mx-puppet-groupme is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/validate_config.yml b/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/validate_config.yml index a710f5581..93654ab27 100644 --- a/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mx-puppet-groupme/tasks/validate_config.yml @@ -11,13 +11,14 @@ The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mx_puppet_groupme_docker_image_name_prefix', 'new': 'matrix_mx_puppet_groupme_container_image_registry_prefix'} - - {'old': 'matrix_mx_puppet_groupme_docker_image', 'new': 'matrix_mx_puppet_groupme_container_image'} - - {'old': 'matrix_mx_puppet_groupme_docker_image_force_pull', 'new': 'matrix_mx_puppet_groupme_container_image_force_pull'} - - {'old': 'matrix_mx_puppet_groupme_docker_image_registry_prefix', 'new': 'matrix_mx_puppet_groupme_container_image_registry_prefix'} - - {'old': 'matrix_mx_puppet_groupme_docker_image_registry_prefix_upstream', 'new': 'matrix_mx_puppet_groupme_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mx_puppet_groupme_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mx_puppet_groupme_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mx_puppet_groupme_docker_src_files_path', 'new': 'matrix_mx_puppet_groupme_container_src_files_path'} + - {'old': 'matrix_bridge_mx_puppet_groupme_docker_image_name_prefix', 'new': 'matrix_bridge_mx_puppet_groupme_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mx_puppet_groupme_docker_image', 'new': 'matrix_bridge_mx_puppet_groupme_container_image'} + - {'old': 'matrix_bridge_mx_puppet_groupme_docker_image_force_pull', 'new': 'matrix_bridge_mx_puppet_groupme_container_image_force_pull'} + - {'old': 'matrix_bridge_mx_puppet_groupme_docker_image_registry_prefix', 'new': 'matrix_bridge_mx_puppet_groupme_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mx_puppet_groupme_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mx_puppet_groupme_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mx_puppet_groupme_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mx_puppet_groupme_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mx_puppet_groupme_docker_src_files_path', 'new': 'matrix_bridge_mx_puppet_groupme_container_src_files_path'} + - {'old': 'matrix_bridge_mx_puppet_groupme_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required mx-puppet-groupme settings not defined ansible.builtin.fail: @@ -25,8 +26,8 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mx_puppet_groupme_appservice_token', when: true} - - {'name': 'matrix_mx_puppet_groupme_homeserver_address', when: true} - - {'name': 'matrix_mx_puppet_groupme_homeserver_token', when: true} - - {'name': 'matrix_mx_puppet_groupme_database_hostname', when: "{{ matrix_mx_puppet_groupme_database_engine == 'postgres' }}"} - - {'name': 'matrix_mx_puppet_groupme_container_network', when: true} + - {'name': 'matrix_bridge_mx_puppet_groupme_appservice_token', when: true} + - {'name': 'matrix_bridge_mx_puppet_groupme_homeserver_address', when: true} + - {'name': 'matrix_bridge_mx_puppet_groupme_homeserver_token', when: true} + - {'name': 'matrix_bridge_mx_puppet_groupme_database_hostname', when: "{{ matrix_bridge_mx_puppet_groupme_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mx_puppet_groupme_container_network', when: true} diff --git a/roles/custom/matrix-bridge-mx-puppet-groupme/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mx-puppet-groupme/templates/config.yaml.j2 index eddc714e3..b839fdc13 100644 --- a/roles/custom/matrix-bridge-mx-puppet-groupme/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mx-puppet-groupme/templates/config.yaml.j2 @@ -2,16 +2,16 @@ bridge: # Port to host the bridge on # Used for communication between the homeserver and the bridge - port: {{ matrix_mx_puppet_groupme_appservice_port }} + port: {{ matrix_bridge_mx_puppet_groupme_appservice_port }} # The host connections to the bridge's webserver are allowed from bindAddress: 0.0.0.0 # Public domain of the homeserver - domain: {{ matrix_mx_puppet_groupme_homeserver_domain }} + domain: {{ matrix_bridge_mx_puppet_groupme_homeserver_domain }} # Reachable URL of the Matrix homeserver - homeserverUrl: {{ matrix_mx_puppet_groupme_homeserver_address }} - {% if matrix_mx_puppet_groupme_login_shared_secret != '' %} + homeserverUrl: {{ matrix_bridge_mx_puppet_groupme_homeserver_address }} + {% if matrix_bridge_mx_puppet_groupme_login_shared_secret != '' %} loginSharedSecretMap: - {{ matrix_domain }}: {{ matrix_mx_puppet_groupme_login_shared_secret }} + {{ matrix_domain }}: {{ matrix_bridge_mx_puppet_groupme_login_shared_secret }} {% endif %} # Display name of the bridge bot displayname: GroupMe Puppet Bridge @@ -23,13 +23,13 @@ bridge: presence: # Bridge GroupMe online/offline status - enabled: {{ matrix_mx_puppet_groupme_presence_enabled | to_json }} + enabled: {{ matrix_bridge_mx_puppet_groupme_presence_enabled | to_json }} # How often to send status to the homeserver in milliseconds - interval: {{ matrix_mx_puppet_groupme_presence_enabled | to_json }} + interval: {{ matrix_bridge_mx_puppet_groupme_presence_enabled | to_json }} provisioning: # Regex of Matrix IDs allowed to use the puppet bridge - whitelist: {{ matrix_mx_puppet_groupme_provisioning_whitelist|to_json }} + whitelist: {{ matrix_bridge_mx_puppet_groupme_provisioning_whitelist|to_json }} # Allow a specific user #- "@alice:example\\.com" # Allow users on a specific homeserver @@ -42,7 +42,7 @@ provisioning: #- "@bob:example\\.com" # Disallow users on a specific homeserver #- "@.*:example\\.com" - blacklist: {{ matrix_mx_puppet_groupme_provisioning_blacklist|to_json }} + blacklist: {{ matrix_bridge_mx_puppet_groupme_provisioning_blacklist|to_json }} relay: # Regex of Matrix IDs who are allowed to use the bridge in relay mode. @@ -50,28 +50,28 @@ relay: # multiple Matrix users # # Same format as in provisioning - whitelist: {{ matrix_mx_puppet_groupme_provisioning_whitelist|to_json }} - blacklist: {{ matrix_mx_puppet_groupme_provisioning_blacklist|to_json }} + whitelist: {{ matrix_bridge_mx_puppet_groupme_provisioning_whitelist|to_json }} + blacklist: {{ matrix_bridge_mx_puppet_groupme_provisioning_blacklist|to_json }} selfService: # Regex of Matrix IDs who are allowed to use bridge self-servicing (plumbed rooms) # # Same format as in provisioning - whitelist: {{ matrix_mx_puppet_groupme_provisioning_whitelist|to_json }} - blacklist: {{ matrix_mx_puppet_groupme_provisioning_blacklist|to_json }} + whitelist: {{ matrix_bridge_mx_puppet_groupme_provisioning_whitelist|to_json }} + blacklist: {{ matrix_bridge_mx_puppet_groupme_provisioning_blacklist|to_json }} database: -{% if matrix_mx_puppet_groupme_database_engine == 'postgres' %} +{% if matrix_bridge_mx_puppet_groupme_database_engine == 'postgres' %} # Use Postgres as a database backend # If set, will be used instead of SQLite3 # Connection string to connect to the Postgres instance # with username "user", password "pass", host "localhost" and database name "dbname". # Modify each value as necessary - connString: {{ matrix_mx_puppet_groupme_database_connection_string|to_json }} + connString: {{ matrix_bridge_mx_puppet_groupme_database_connection_string|to_json }} {% else %} # Use SQLite3 as a database backend # The name of the database file - filename: {{ matrix_mx_puppet_groupme_sqlite_database_path_in_container|to_json }} + filename: {{ matrix_bridge_mx_puppet_groupme_sqlite_database_path_in_container|to_json }} {% endif %} logging: diff --git a/roles/custom/matrix-bridge-mx-puppet-groupme/templates/systemd/matrix-mx-puppet-groupme.service.j2 b/roles/custom/matrix-bridge-mx-puppet-groupme/templates/systemd/matrix-mx-puppet-groupme.service.j2 index bc57467b8..46e3cf93f 100644 --- a/roles/custom/matrix-bridge-mx-puppet-groupme/templates/systemd/matrix-mx-puppet-groupme.service.j2 +++ b/roles/custom/matrix-bridge-mx-puppet-groupme/templates/systemd/matrix-mx-puppet-groupme.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mx Puppet Groupme bridge -{% for service in matrix_mx_puppet_groupme_systemd_required_services_list %} +{% for service in matrix_bridge_mx_puppet_groupme_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mx_puppet_groupme_systemd_wanted_services_list %} +{% for service in matrix_bridge_mx_puppet_groupme_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,19 +22,21 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mx_puppet_groupme_container_network }} \ + --network={{ matrix_bridge_mx_puppet_groupme_container_network }} \ -e CONFIG_PATH=/config/config.yaml \ -e REGISTRATION_PATH=/config/registration.yaml \ - --mount type=bind,src={{ matrix_mx_puppet_groupme_config_path }},dst=/config \ - --mount type=bind,src={{ matrix_mx_puppet_groupme_data_path }},dst=/data \ - {% for arg in matrix_mx_puppet_groupme_container_extra_arguments %} + --mount type=bind,src={{ matrix_bridge_mx_puppet_groupme_config_path }},dst=/config \ + --mount type=bind,src={{ matrix_bridge_mx_puppet_groupme_data_path }},dst=/data \ + {% for arg in matrix_bridge_mx_puppet_groupme_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mx_puppet_groupme_container_image }} + {{ matrix_bridge_mx_puppet_groupme_container_image }} -{% for network in matrix_mx_puppet_groupme_container_additional_networks %} +{% if matrix_bridge_mx_puppet_groupme_container_network != 'host' %} +{% for network in matrix_bridge_mx_puppet_groupme_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mx-puppet-groupme {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mx-puppet-groupme diff --git a/roles/custom/matrix-bridge-mx-puppet-steam/defaults/main.yml b/roles/custom/matrix-bridge-mx-puppet-steam/defaults/main.yml index abd3c8fdb..c02060a33 100644 --- a/roles/custom/matrix-bridge-mx-puppet-steam/defaults/main.yml +++ b/roles/custom/matrix-bridge-mx-puppet-steam/defaults/main.yml @@ -13,132 +13,131 @@ # Mx Puppet Steam is a Matrix <-> Steam bridge # Project source code URL: https://github.com/icewind1991/mx-puppet-steam -matrix_mx_puppet_steam_enabled: true +matrix_bridge_mx_puppet_steam_enabled: true -matrix_mx_puppet_steam_container_image_self_build: false -matrix_mx_puppet_steam_container_image_self_build_repo: "https://github.com/icewind1991/mx-puppet-steam.git" -matrix_mx_puppet_steam_container_image_self_build_repo_version: "{{ 'master' if matrix_mx_puppet_steam_version == 'latest' else matrix_mx_puppet_steam_version }}" +matrix_bridge_mx_puppet_steam_container_image_self_build: false +matrix_bridge_mx_puppet_steam_container_image_self_build_repo: "https://github.com/icewind1991/mx-puppet-steam.git" +matrix_bridge_mx_puppet_steam_container_image_self_build_repo_version: "{{ 'master' if matrix_bridge_mx_puppet_steam_version == 'latest' else matrix_bridge_mx_puppet_steam_version }}" # Controls whether the mx-puppet-steam container exposes its HTTP port (tcp/8432 in the container). # # Takes an ":" or "" value (e.g. "127.0.0.1:8432"), or empty string to not expose. -matrix_mx_puppet_steam_container_http_host_bind_port: '' +matrix_bridge_mx_puppet_steam_container_http_host_bind_port: '' # renovate: datasource=docker depName=icewind1991/mx-puppet-steam -matrix_mx_puppet_steam_version: latest -matrix_mx_puppet_steam_container_image: "{{ matrix_mx_puppet_steam_container_image_registry_prefix }}icewind1991/mx-puppet-steam:{{ matrix_mx_puppet_steam_version }}" -matrix_mx_puppet_steam_container_image_registry_prefix: "{{ 'localhost/' if matrix_mx_puppet_steam_container_image_self_build else matrix_mx_puppet_steam_container_image_registry_prefix_upstream }}" -matrix_mx_puppet_steam_container_image_registry_prefix_upstream: "{{ matrix_mx_puppet_steam_container_image_registry_prefix_upstream_default }}" -matrix_mx_puppet_steam_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_mx_puppet_steam_container_image_force_pull: "{{ matrix_mx_puppet_steam_container_image.endswith(':latest') }}" +matrix_bridge_mx_puppet_steam_version: latest +matrix_bridge_mx_puppet_steam_container_image: "{{ matrix_bridge_mx_puppet_steam_container_image_registry_prefix }}icewind1991/mx-puppet-steam:{{ matrix_bridge_mx_puppet_steam_version }}" +matrix_bridge_mx_puppet_steam_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_mx_puppet_steam_container_image_self_build else matrix_bridge_mx_puppet_steam_container_image_registry_prefix_upstream }}" +matrix_bridge_mx_puppet_steam_container_image_registry_prefix_upstream: "{{ matrix_bridge_mx_puppet_steam_container_image_registry_prefix_upstream_default }}" +matrix_bridge_mx_puppet_steam_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_mx_puppet_steam_base_path: "{{ matrix_base_data_path }}/mx-puppet-steam" -matrix_mx_puppet_steam_config_path: "{{ matrix_mx_puppet_steam_base_path }}/config" -matrix_mx_puppet_steam_data_path: "{{ matrix_mx_puppet_steam_base_path }}/data" -matrix_mx_puppet_steam_container_src_files_path: "{{ matrix_mx_puppet_steam_base_path }}/docker-src" +matrix_bridge_mx_puppet_steam_base_path: "{{ matrix_base_data_path }}/mx-puppet-steam" +matrix_bridge_mx_puppet_steam_config_path: "{{ matrix_bridge_mx_puppet_steam_base_path }}/config" +matrix_bridge_mx_puppet_steam_data_path: "{{ matrix_bridge_mx_puppet_steam_base_path }}/data" +matrix_bridge_mx_puppet_steam_container_src_files_path: "{{ matrix_bridge_mx_puppet_steam_base_path }}/docker-src" -matrix_mx_puppet_steam_appservice_port: "8432" +matrix_bridge_mx_puppet_steam_appservice_port: "8432" -matrix_mx_puppet_steam_homeserver_address: "" -matrix_mx_puppet_steam_homeserver_domain: '{{ matrix_domain }}' -matrix_mx_puppet_steam_appservice_address: 'http://matrix-mx-puppet-steam:{{ matrix_mx_puppet_steam_appservice_port }}' +matrix_bridge_mx_puppet_steam_homeserver_address: "" +matrix_bridge_mx_puppet_steam_homeserver_domain: '{{ matrix_domain }}' +matrix_bridge_mx_puppet_steam_appservice_address: 'http://matrix-mx-puppet-steam:{{ matrix_bridge_mx_puppet_steam_appservice_port }}' # "@alice:example.com" to allow a specific user # "@.*:example.com" to allow users on a specific homeserver # "@.*" to allow anyone -matrix_mx_puppet_steam_provisioning_whitelist: +matrix_bridge_mx_puppet_steam_provisioning_whitelist: - "@.*:{{ matrix_domain | regex_escape }}" # Leave empty to disable blacklist # "@bob:example.com" to disallow a specific user # "@.*:example.com" to disallow users on a specific homeserver -matrix_mx_puppet_steam_provisioning_blacklist: [] +matrix_bridge_mx_puppet_steam_provisioning_blacklist: [] -matrix_mx_puppet_steam_container_network: "" +matrix_bridge_mx_puppet_steam_container_network: "" -matrix_mx_puppet_steam_container_additional_networks: "{{ matrix_mx_puppet_steam_container_additional_networks_auto + matrix_mx_puppet_steam_container_additional_networks_custom }}" -matrix_mx_puppet_steam_container_additional_networks_auto: [] -matrix_mx_puppet_steam_container_additional_networks_custom: [] +matrix_bridge_mx_puppet_steam_container_additional_networks: "{{ matrix_bridge_mx_puppet_steam_container_additional_networks_auto + matrix_bridge_mx_puppet_steam_container_additional_networks_custom }}" +matrix_bridge_mx_puppet_steam_container_additional_networks_auto: [] +matrix_bridge_mx_puppet_steam_container_additional_networks_custom: [] # A list of extra arguments to pass to the container -matrix_mx_puppet_steam_container_extra_arguments: [] +matrix_bridge_mx_puppet_steam_container_extra_arguments: [] # List of systemd services that matrix-puppet-steam.service depends on. -matrix_mx_puppet_steam_systemd_required_services_list: "{{ matrix_mx_puppet_steam_systemd_required_services_list_default + matrix_mx_puppet_steam_systemd_required_services_list_auto + matrix_mx_puppet_steam_systemd_required_services_list_custom }}" -matrix_mx_puppet_steam_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_mx_puppet_steam_systemd_required_services_list_auto: [] -matrix_mx_puppet_steam_systemd_required_services_list_custom: [] +matrix_bridge_mx_puppet_steam_systemd_required_services_list: "{{ matrix_bridge_mx_puppet_steam_systemd_required_services_list_default + matrix_bridge_mx_puppet_steam_systemd_required_services_list_auto + matrix_bridge_mx_puppet_steam_systemd_required_services_list_custom }}" +matrix_bridge_mx_puppet_steam_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_mx_puppet_steam_systemd_required_services_list_auto: [] +matrix_bridge_mx_puppet_steam_systemd_required_services_list_custom: [] # List of systemd services that matrix-puppet-steam.service wants -matrix_mx_puppet_steam_systemd_wanted_services_list: [] +matrix_bridge_mx_puppet_steam_systemd_wanted_services_list: [] -matrix_mx_puppet_steam_appservice_token: '' -matrix_mx_puppet_steam_homeserver_token: '' +matrix_bridge_mx_puppet_steam_appservice_token: '' +matrix_bridge_mx_puppet_steam_homeserver_token: '' # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). -matrix_mx_puppet_steam_login_shared_secret: '' +matrix_bridge_mx_puppet_steam_login_shared_secret: '' -matrix_mx_puppet_steam_presence_enabled: true -matrix_mx_puppet_steam_presence_interval: 5000 +matrix_bridge_mx_puppet_steam_presence_enabled: true +matrix_bridge_mx_puppet_steam_presence_interval: 5000 -matrix_mx_puppet_steam_database_engine: sqlite +matrix_bridge_mx_puppet_steam_database_engine: sqlite -matrix_mx_puppet_steam_sqlite_database_path_local: "{{ matrix_mx_puppet_steam_data_path }}/database.db" -matrix_mx_puppet_steam_sqlite_database_path_in_container: "/data/database.db" +matrix_bridge_mx_puppet_steam_sqlite_database_path_local: "{{ matrix_bridge_mx_puppet_steam_data_path }}/database.db" +matrix_bridge_mx_puppet_steam_sqlite_database_path_in_container: "/data/database.db" -matrix_mx_puppet_steam_database_username: matrix_mx_puppet_steam -matrix_mx_puppet_steam_database_password: ~ -matrix_mx_puppet_steam_database_hostname: '' -matrix_mx_puppet_steam_database_port: 5432 -matrix_mx_puppet_steam_database_name: matrix_mx_puppet_steam -matrix_mx_puppet_steam_database_sslmode: disable +matrix_bridge_mx_puppet_steam_database_username: matrix_mx_puppet_steam +matrix_bridge_mx_puppet_steam_database_password: ~ +matrix_bridge_mx_puppet_steam_database_hostname: '' +matrix_bridge_mx_puppet_steam_database_port: 5432 +matrix_bridge_mx_puppet_steam_database_name: matrix_mx_puppet_steam +matrix_bridge_mx_puppet_steam_database_sslmode: disable -matrix_mx_puppet_steam_database_connection_string: 'postgresql://{{ matrix_mx_puppet_steam_database_username }}:{{ matrix_mx_puppet_steam_database_password }}@{{ matrix_mx_puppet_steam_database_hostname }}:{{ matrix_mx_puppet_steam_database_port }}/{{ matrix_mx_puppet_steam_database_name }}?sslmode={{ matrix_mx_puppet_steam_database_sslmode }}' +matrix_bridge_mx_puppet_steam_database_connection_string: 'postgresql://{{ matrix_bridge_mx_puppet_steam_database_username }}:{{ matrix_bridge_mx_puppet_steam_database_password }}@{{ matrix_bridge_mx_puppet_steam_database_hostname }}:{{ matrix_bridge_mx_puppet_steam_database_port }}/{{ matrix_bridge_mx_puppet_steam_database_name }}?sslmode={{ matrix_bridge_mx_puppet_steam_database_sslmode }}' # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_mx_puppet_steam_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_mx_puppet_steam_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_mx_puppet_steam_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_mx_puppet_steam_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_mx_puppet_steam_configuration_extension_yaml: | +matrix_bridge_mx_puppet_steam_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_mx_puppet_steam_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_mx_puppet_steam_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_mx_puppet_steam_configuration_yaml`. + # completely redefining `matrix_bridge_mx_puppet_steam_configuration_yaml`. -matrix_mx_puppet_steam_configuration_extension: "{{ matrix_mx_puppet_steam_configuration_extension_yaml | from_yaml if matrix_mx_puppet_steam_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_mx_puppet_steam_configuration_extension: "{{ matrix_bridge_mx_puppet_steam_configuration_extension_yaml | from_yaml if matrix_bridge_mx_puppet_steam_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_mx_puppet_steam_configuration_yaml`. -matrix_mx_puppet_steam_configuration: "{{ matrix_mx_puppet_steam_configuration_yaml | from_yaml | combine(matrix_mx_puppet_steam_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_mx_puppet_steam_configuration_yaml`. +matrix_bridge_mx_puppet_steam_configuration: "{{ matrix_bridge_mx_puppet_steam_configuration_yaml | from_yaml | combine(matrix_bridge_mx_puppet_steam_configuration_extension, recursive=True) }}" -matrix_mx_puppet_steam_registration_yaml: | - as_token: "{{ matrix_mx_puppet_steam_appservice_token }}" - hs_token: "{{ matrix_mx_puppet_steam_homeserver_token }}" +matrix_bridge_mx_puppet_steam_registration_yaml: | + as_token: "{{ matrix_bridge_mx_puppet_steam_appservice_token }}" + hs_token: "{{ matrix_bridge_mx_puppet_steam_homeserver_token }}" id: steam-puppet namespaces: users: - exclusive: true - regex: '@_steampuppet_.*:{{ matrix_mx_puppet_steam_homeserver_domain | regex_escape }}' + regex: '@_steampuppet_.*:{{ matrix_bridge_mx_puppet_steam_homeserver_domain | regex_escape }}' rooms: [] aliases: - exclusive: true - regex: '#_steampuppet_.*:{{ matrix_mx_puppet_steam_homeserver_domain | regex_escape }}' + regex: '#_steampuppet_.*:{{ matrix_bridge_mx_puppet_steam_homeserver_domain | regex_escape }}' protocols: [] rate_limited: false sender_localpart: _steampuppet_bot - url: {{ matrix_mx_puppet_steam_appservice_address }} + url: {{ matrix_bridge_mx_puppet_steam_appservice_address }} de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true -matrix_mx_puppet_steam_registration: "{{ matrix_mx_puppet_steam_registration_yaml | from_yaml }}" +matrix_bridge_mx_puppet_steam_registration: "{{ matrix_bridge_mx_puppet_steam_registration_yaml | from_yaml }}" -# matrix_mx_puppet_steam_restart_necessary controls whether the service +# matrix_bridge_mx_puppet_steam_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -146,4 +145,4 @@ matrix_mx_puppet_steam_registration: "{{ matrix_mx_puppet_steam_registration_yam # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_mx_puppet_steam_restart_necessary: false +matrix_bridge_mx_puppet_steam_restart_necessary: false diff --git a/roles/custom/matrix-bridge-mx-puppet-steam/tasks/main.yml b/roles/custom/matrix-bridge-mx-puppet-steam/tasks/main.yml index a7619e431..dd2a20d9c 100644 --- a/roles/custom/matrix-bridge-mx-puppet-steam/tasks/main.yml +++ b/roles/custom/matrix-bridge-mx-puppet-steam/tasks/main.yml @@ -12,15 +12,15 @@ - install-all - install-mx-puppet-steam block: - - when: matrix_mx_puppet_steam_enabled | bool + - when: matrix_bridge_mx_puppet_steam_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_mx_puppet_steam_enabled | bool + - when: matrix_bridge_mx_puppet_steam_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-mx-puppet-steam block: - - when: not matrix_mx_puppet_steam_enabled | bool + - when: not matrix_bridge_mx_puppet_steam_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-mx-puppet-steam/tasks/setup_install.yml b/roles/custom/matrix-bridge-mx-puppet-steam/tasks/setup_install.yml index d1c324cb7..cf89a245a 100644 --- a/roles/custom/matrix-bridge-mx-puppet-steam/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mx-puppet-steam/tasks/setup_install.yml @@ -20,16 +20,16 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_mx_puppet_steam_base_path }}", when: true} - - {path: "{{ matrix_mx_puppet_steam_config_path }}", when: true} - - {path: "{{ matrix_mx_puppet_steam_data_path }}", when: true} - - {path: "{{ matrix_mx_puppet_steam_container_src_files_path }}", when: "{{ matrix_mx_puppet_steam_container_image_self_build }}"} - when: matrix_mx_puppet_steam_enabled | bool and item.when | bool + - {path: "{{ matrix_bridge_mx_puppet_steam_base_path }}", when: true} + - {path: "{{ matrix_bridge_mx_puppet_steam_config_path }}", when: true} + - {path: "{{ matrix_bridge_mx_puppet_steam_data_path }}", when: true} + - {path: "{{ matrix_bridge_mx_puppet_steam_container_src_files_path }}", when: "{{ matrix_bridge_mx_puppet_steam_container_image_self_build }}"} + when: matrix_bridge_mx_puppet_steam_enabled | bool and item.when | bool - name: Check if an old database file already exists ansible.builtin.stat: - path: "{{ matrix_mx_puppet_steam_base_path }}/database.db" - register: matrix_mx_puppet_steam_stat_database + path: "{{ matrix_bridge_mx_puppet_steam_base_path }}/database.db" + register: matrix_bridge_mx_puppet_steam_stat_database - name: (Data relocation) Ensure matrix-mx-puppet-steam.service is stopped ansible.builtin.service: @@ -38,99 +38,106 @@ enabled: false daemon_reload: true failed_when: false - when: "matrix_mx_puppet_steam_stat_database.stat.exists" + when: "matrix_bridge_mx_puppet_steam_stat_database.stat.exists" - name: (Data relocation) Move mx-puppet-steam database file to ./data directory ansible.builtin.command: - cmd: "mv {{ matrix_mx_puppet_steam_base_path }}/database.db {{ matrix_mx_puppet_steam_data_path }}/database.db" - creates: "{{ matrix_mx_puppet_steam_data_path }}/database.db" - removes: "{{ matrix_mx_puppet_steam_base_path }}/database.db" - when: "matrix_mx_puppet_steam_stat_database.stat.exists" + cmd: "mv {{ matrix_bridge_mx_puppet_steam_base_path }}/database.db {{ matrix_bridge_mx_puppet_steam_data_path }}/database.db" + creates: "{{ matrix_bridge_mx_puppet_steam_data_path }}/database.db" + removes: "{{ matrix_bridge_mx_puppet_steam_base_path }}/database.db" + when: "matrix_bridge_mx_puppet_steam_stat_database.stat.exists" - ansible.builtin.set_fact: - matrix_mx_puppet_steam_migration_requires_restart: false + matrix_bridge_mx_puppet_steam_migration_requires_restart: false -- when: "matrix_mx_puppet_steam_database_engine == 'postgres'" +- when: "matrix_bridge_mx_puppet_steam_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_mx_puppet_steam_sqlite_database_path_local }}" - register: matrix_mx_puppet_steam_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_mx_puppet_steam_sqlite_database_path_local }}" + register: matrix_bridge_mx_puppet_steam_sqlite_database_path_local_stat_result - - when: "matrix_mx_puppet_steam_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_mx_puppet_steam_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_mx_puppet_steam_sqlite_database_path_local }}" - dst: "{{ matrix_mx_puppet_steam_database_connection_string }}" + src: "{{ matrix_bridge_mx_puppet_steam_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_mx_puppet_steam_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_mx_puppet_steam_database_engine' + engine_variable_name: 'matrix_bridge_mx_puppet_steam_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-mx-puppet-steam.service'] - ansible.builtin.set_fact: - matrix_mx_puppet_steam_migration_requires_restart: true + matrix_bridge_mx_puppet_steam_migration_requires_restart: true - name: Ensure MX Puppet Steam image is pulled - community.docker.docker_image: - name: "{{ matrix_mx_puppet_steam_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_mx_puppet_steam_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mx_puppet_steam_container_image_force_pull }}" - when: matrix_mx_puppet_steam_enabled | bool and not matrix_mx_puppet_steam_container_image_self_build - register: matrix_mx_puppet_steam_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_mx_puppet_steam_container_image }}" + pull: always + when: matrix_bridge_mx_puppet_steam_enabled | bool and not matrix_bridge_mx_puppet_steam_container_image_self_build + register: matrix_bridge_mx_puppet_steam_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_mx_puppet_steam_container_image_pull_result is not failed + until: matrix_bridge_mx_puppet_steam_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure MX Puppet Steam repository ownership is correct on self build + ansible.builtin.file: + path: "{{ matrix_bridge_mx_puppet_steam_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_mx_puppet_steam_enabled | bool and matrix_bridge_mx_puppet_steam_container_image_self_build" - name: Ensure MX Puppet Steam repository is present on self build ansible.builtin.git: - repo: "{{ matrix_mx_puppet_steam_container_image_self_build_repo }}" - version: "{{ matrix_mx_puppet_steam_container_image_self_build_repo_version }}" - dest: "{{ matrix_mx_puppet_steam_container_src_files_path }}" + repo: "{{ matrix_bridge_mx_puppet_steam_container_image_self_build_repo }}" + version: "{{ matrix_bridge_mx_puppet_steam_container_image_self_build_repo_version }}" + dest: "{{ matrix_bridge_mx_puppet_steam_container_src_files_path }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_mx_puppet_steam_git_pull_results - when: "matrix_mx_puppet_steam_enabled | bool and matrix_mx_puppet_steam_container_image_self_build" + register: matrix_bridge_mx_puppet_steam_git_pull_results + when: "matrix_bridge_mx_puppet_steam_enabled | bool and matrix_bridge_mx_puppet_steam_container_image_self_build" - name: Ensure MX Puppet Steam Docker image is built - community.docker.docker_image: - name: "{{ matrix_mx_puppet_steam_container_image }}" - source: build - force_source: "{{ matrix_mx_puppet_steam_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_mx_puppet_steam_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_mx_puppet_steam_container_src_files_path }}" - pull: true - when: "matrix_mx_puppet_steam_enabled | bool and matrix_mx_puppet_steam_container_image_self_build" + community.docker.docker_image_build: + name: "{{ matrix_bridge_mx_puppet_steam_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_mx_puppet_steam_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_mx_puppet_steam_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_mx_puppet_steam_enabled | bool and matrix_bridge_mx_puppet_steam_container_image_self_build" + register: matrix_bridge_mx_puppet_steam_container_image_build_result - name: Ensure mx-puppet-steam config.yaml installed ansible.builtin.copy: - content: "{{ matrix_mx_puppet_steam_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mx_puppet_steam_config_path }}/config.yaml" + content: "{{ matrix_bridge_mx_puppet_steam_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mx_puppet_steam_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mx_puppet_steam_config_result + register: matrix_bridge_mx_puppet_steam_config_result - name: Ensure mx-puppet-steam steam-registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_mx_puppet_steam_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_mx_puppet_steam_config_path }}/registration.yaml" + content: "{{ matrix_bridge_mx_puppet_steam_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_mx_puppet_steam_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_mx_puppet_steam_registration_result + register: matrix_bridge_mx_puppet_steam_registration_result - name: Ensure mx-puppet-steam container network is created + when: matrix_bridge_mx_puppet_steam_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_mx_puppet_steam_container_network }}" + name: "{{ matrix_bridge_mx_puppet_steam_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -139,17 +146,18 @@ src: "{{ role_path }}/templates/systemd/matrix-mx-puppet-steam.service.j2" dest: "/etc/systemd/system/matrix-mx-puppet-steam.service" mode: '0644' - register: matrix_mx_puppet_steam_systemd_service_result + register: matrix_bridge_mx_puppet_steam_systemd_service_result - name: Determine whether matrix-mx-puppet-steam needs a restart ansible.builtin.set_fact: - matrix_mx_puppet_steam_restart_necessary: >- + matrix_bridge_mx_puppet_steam_restart_necessary: >- {{ - matrix_mx_puppet_steam_migration_requires_restart | default(false) - or matrix_mx_puppet_steam_config_result.changed | default(false) - or matrix_mx_puppet_steam_registration_result.changed | default(false) - or matrix_mx_puppet_steam_systemd_service_result.changed | default(false) - or matrix_mx_puppet_steam_container_image_pull_result.changed | default(false) + matrix_bridge_mx_puppet_steam_migration_requires_restart | default(false) + or matrix_bridge_mx_puppet_steam_config_result.changed | default(false) + or matrix_bridge_mx_puppet_steam_registration_result.changed | default(false) + or matrix_bridge_mx_puppet_steam_systemd_service_result.changed | default(false) + or matrix_bridge_mx_puppet_steam_container_image_pull_result.changed | default(false) + or matrix_bridge_mx_puppet_steam_container_image_build_result.changed | default(false) }} - name: Ensure matrix-mx-puppet-steam.service restarted, if necessary @@ -157,4 +165,4 @@ name: "matrix-mx-puppet-steam.service" state: restarted daemon_reload: true - when: "matrix_mx_puppet_steam_migration_requires_restart | bool" + when: "matrix_bridge_mx_puppet_steam_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-mx-puppet-steam/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-mx-puppet-steam/tasks/setup_uninstall.yml index 1281ee4f8..5ded9fb4d 100644 --- a/roles/custom/matrix-bridge-mx-puppet-steam/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-mx-puppet-steam/tasks/setup_uninstall.yml @@ -9,9 +9,9 @@ - name: Check existence of matrix-mx-puppet-steam service ansible.builtin.stat: path: "/etc/systemd/system/matrix-mx-puppet-steam.service" - register: matrix_mx_puppet_steam_service_stat + register: matrix_bridge_mx_puppet_steam_service_stat -- when: matrix_mx_puppet_steam_service_stat.stat.exists | bool +- when: matrix_bridge_mx_puppet_steam_service_stat.stat.exists | bool block: - name: Ensure matrix-mx-puppet-steam is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-mx-puppet-steam/tasks/validate_config.yml b/roles/custom/matrix-bridge-mx-puppet-steam/tasks/validate_config.yml index e19593bf6..cd2bc2659 100644 --- a/roles/custom/matrix-bridge-mx-puppet-steam/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mx-puppet-steam/tasks/validate_config.yml @@ -11,13 +11,14 @@ The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_mx_puppet_steam_docker_image_name_prefix', 'new': 'matrix_mx_puppet_steam_container_image_registry_prefix'} - - {'old': 'matrix_mx_puppet_steam_docker_image', 'new': 'matrix_mx_puppet_steam_container_image'} - - {'old': 'matrix_mx_puppet_steam_docker_image_force_pull', 'new': 'matrix_mx_puppet_steam_container_image_force_pull'} - - {'old': 'matrix_mx_puppet_steam_docker_image_registry_prefix', 'new': 'matrix_mx_puppet_steam_container_image_registry_prefix'} - - {'old': 'matrix_mx_puppet_steam_docker_image_registry_prefix_upstream', 'new': 'matrix_mx_puppet_steam_container_image_registry_prefix_upstream'} - - {'old': 'matrix_mx_puppet_steam_docker_image_registry_prefix_upstream_default', 'new': 'matrix_mx_puppet_steam_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_mx_puppet_steam_docker_src_files_path', 'new': 'matrix_mx_puppet_steam_container_src_files_path'} + - {'old': 'matrix_bridge_mx_puppet_steam_docker_image_name_prefix', 'new': 'matrix_bridge_mx_puppet_steam_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mx_puppet_steam_docker_image', 'new': 'matrix_bridge_mx_puppet_steam_container_image'} + - {'old': 'matrix_bridge_mx_puppet_steam_docker_image_force_pull', 'new': 'matrix_bridge_mx_puppet_steam_container_image_force_pull'} + - {'old': 'matrix_bridge_mx_puppet_steam_docker_image_registry_prefix', 'new': 'matrix_bridge_mx_puppet_steam_container_image_registry_prefix'} + - {'old': 'matrix_bridge_mx_puppet_steam_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_mx_puppet_steam_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_mx_puppet_steam_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_mx_puppet_steam_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_mx_puppet_steam_docker_src_files_path', 'new': 'matrix_bridge_mx_puppet_steam_container_src_files_path'} + - {'old': 'matrix_bridge_mx_puppet_steam_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required mx-puppet-steam settings not defined ansible.builtin.fail: @@ -25,8 +26,8 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_mx_puppet_steam_appservice_token', when: true} - - {'name': 'matrix_mx_puppet_steam_homeserver_address', when: true} - - {'name': 'matrix_mx_puppet_steam_homeserver_token', when: true} - - {'name': 'matrix_mx_puppet_steam_database_hostname', when: "{{ matrix_mx_puppet_steam_database_engine == 'postgres' }}"} - - {'name': 'matrix_mx_puppet_steam_container_network', when: true} + - {'name': 'matrix_bridge_mx_puppet_steam_appservice_token', when: true} + - {'name': 'matrix_bridge_mx_puppet_steam_homeserver_address', when: true} + - {'name': 'matrix_bridge_mx_puppet_steam_homeserver_token', when: true} + - {'name': 'matrix_bridge_mx_puppet_steam_database_hostname', when: "{{ matrix_bridge_mx_puppet_steam_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_mx_puppet_steam_container_network', when: true} diff --git a/roles/custom/matrix-bridge-mx-puppet-steam/templates/config.yaml.j2 b/roles/custom/matrix-bridge-mx-puppet-steam/templates/config.yaml.j2 index 3819698ca..995e04c97 100644 --- a/roles/custom/matrix-bridge-mx-puppet-steam/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-mx-puppet-steam/templates/config.yaml.j2 @@ -2,16 +2,16 @@ bridge: # Port to host the bridge on # Used for communication between the homeserver and the bridge - port: {{ matrix_mx_puppet_steam_appservice_port }} + port: {{ matrix_bridge_mx_puppet_steam_appservice_port }} # The host connections to the bridge's webserver are allowed from bindAddress: 0.0.0.0 # Public domain of the homeserver - domain: {{ matrix_mx_puppet_steam_homeserver_domain }} + domain: {{ matrix_bridge_mx_puppet_steam_homeserver_domain }} # Reachable URL of the Matrix homeserver - homeserverUrl: {{ matrix_mx_puppet_steam_homeserver_address }} - {% if matrix_mx_puppet_steam_login_shared_secret != '' %} + homeserverUrl: {{ matrix_bridge_mx_puppet_steam_homeserver_address }} + {% if matrix_bridge_mx_puppet_steam_login_shared_secret != '' %} loginSharedSecretMap: - {{ matrix_domain }}: {{ matrix_mx_puppet_steam_login_shared_secret }} + {{ matrix_domain }}: {{ matrix_bridge_mx_puppet_steam_login_shared_secret }} {% endif %} # Display name of the bridge bot displayname: Steam Puppet Bridge @@ -23,13 +23,13 @@ bridge: presence: # Bridge Steam online/offline status - enabled: {{ matrix_mx_puppet_steam_presence_enabled | to_json }} + enabled: {{ matrix_bridge_mx_puppet_steam_presence_enabled | to_json }} # How often to send status to the homeserver in milliseconds - interval: {{ matrix_mx_puppet_steam_presence_interval | to_json }} + interval: {{ matrix_bridge_mx_puppet_steam_presence_interval | to_json }} provisioning: # Regex of Matrix IDs allowed to use the puppet bridge - whitelist: {{ matrix_mx_puppet_steam_provisioning_whitelist|to_json }} + whitelist: {{ matrix_bridge_mx_puppet_steam_provisioning_whitelist|to_json }} # Allow a specific user #- "@alice:example\\.com" # Allow users on a specific homeserver @@ -42,7 +42,7 @@ provisioning: #- "@bob:example\\.com" # Disallow users on a specific homeserver #- "@.*:example\\.com" - blacklist: {{ matrix_mx_puppet_steam_provisioning_blacklist|to_json }} + blacklist: {{ matrix_bridge_mx_puppet_steam_provisioning_blacklist|to_json }} relay: # Regex of Matrix IDs who are allowed to use the bridge in relay mode. @@ -50,28 +50,28 @@ relay: # multiple Matrix users # # Same format as in provisioning - whitelist: {{ matrix_mx_puppet_steam_provisioning_whitelist|to_json }} - blacklist: {{ matrix_mx_puppet_steam_provisioning_blacklist|to_json }} + whitelist: {{ matrix_bridge_mx_puppet_steam_provisioning_whitelist|to_json }} + blacklist: {{ matrix_bridge_mx_puppet_steam_provisioning_blacklist|to_json }} selfService: # Regex of Matrix IDs who are allowed to use bridge self-servicing (plumbed rooms) # # Same format as in provisioning - whitelist: {{ matrix_mx_puppet_steam_provisioning_whitelist|to_json }} - blacklist: {{ matrix_mx_puppet_steam_provisioning_blacklist|to_json }} + whitelist: {{ matrix_bridge_mx_puppet_steam_provisioning_whitelist|to_json }} + blacklist: {{ matrix_bridge_mx_puppet_steam_provisioning_blacklist|to_json }} database: -{% if matrix_mx_puppet_steam_database_engine == 'postgres' %} +{% if matrix_bridge_mx_puppet_steam_database_engine == 'postgres' %} # Use Postgres as a database backend # If set, will be used instead of SQLite3 # Connection string to connect to the Postgres instance # with username "user", password "pass", host "localhost" and database name "dbname". # Modify each value as necessary - connString: {{ matrix_mx_puppet_steam_database_connection_string|to_json }} + connString: {{ matrix_bridge_mx_puppet_steam_database_connection_string|to_json }} {% else %} # Use SQLite3 as a database backend # The name of the database file - filename: {{ matrix_mx_puppet_steam_sqlite_database_path_in_container|to_json }} + filename: {{ matrix_bridge_mx_puppet_steam_sqlite_database_path_in_container|to_json }} {% endif %} logging: diff --git a/roles/custom/matrix-bridge-mx-puppet-steam/templates/systemd/matrix-mx-puppet-steam.service.j2 b/roles/custom/matrix-bridge-mx-puppet-steam/templates/systemd/matrix-mx-puppet-steam.service.j2 index ade6c21db..6913829da 100644 --- a/roles/custom/matrix-bridge-mx-puppet-steam/templates/systemd/matrix-mx-puppet-steam.service.j2 +++ b/roles/custom/matrix-bridge-mx-puppet-steam/templates/systemd/matrix-mx-puppet-steam.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Mx Puppet Steam bridge -{% for service in matrix_mx_puppet_steam_systemd_required_services_list %} +{% for service in matrix_bridge_mx_puppet_steam_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_mx_puppet_steam_systemd_wanted_services_list %} +{% for service in matrix_bridge_mx_puppet_steam_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,19 +22,21 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_mx_puppet_steam_container_network }} \ + --network={{ matrix_bridge_mx_puppet_steam_container_network }} \ -e CONFIG_PATH=/config/config.yaml \ -e REGISTRATION_PATH=/config/registration.yaml \ - --mount type=bind,src={{ matrix_mx_puppet_steam_config_path }},dst=/config \ - --mount type=bind,src={{ matrix_mx_puppet_steam_data_path }},dst=/data \ - {% for arg in matrix_mx_puppet_steam_container_extra_arguments %} + --mount type=bind,src={{ matrix_bridge_mx_puppet_steam_config_path }},dst=/config \ + --mount type=bind,src={{ matrix_bridge_mx_puppet_steam_data_path }},dst=/data \ + {% for arg in matrix_bridge_mx_puppet_steam_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_mx_puppet_steam_container_image }} + {{ matrix_bridge_mx_puppet_steam_container_image }} -{% for network in matrix_mx_puppet_steam_container_additional_networks %} +{% if matrix_bridge_mx_puppet_steam_container_network != 'host' %} +{% for network in matrix_bridge_mx_puppet_steam_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-mx-puppet-steam {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-mx-puppet-steam diff --git a/roles/custom/matrix-bridge-postmoogle/defaults/main.yml b/roles/custom/matrix-bridge-postmoogle/defaults/main.yml index b0fec65e6..7a2f588c6 100644 --- a/roles/custom/matrix-bridge-postmoogle/defaults/main.yml +++ b/roles/custom/matrix-bridge-postmoogle/defaults/main.yml @@ -10,185 +10,180 @@ # postmoogle is an email to Matrix bridge using its bot user # Project source code URL: https://github.com/etkecc/postmoogle -matrix_postmoogle_enabled: true +matrix_bridge_postmoogle_enabled: true -matrix_postmoogle_container_image_self_build: false -matrix_postmoogle_container_repo: "https://github.com/etkecc/postmoogle.git" -matrix_postmoogle_container_repo_version: "{{ 'main' if matrix_postmoogle_version == 'latest' else matrix_postmoogle_version }}" -matrix_postmoogle_container_src_files_path: "{{ matrix_base_data_path }}/postmoogle/docker-src" +matrix_bridge_postmoogle_container_image_self_build: false +matrix_bridge_postmoogle_container_repo: "https://github.com/etkecc/postmoogle.git" +matrix_bridge_postmoogle_container_repo_version: "{{ 'main' if matrix_bridge_postmoogle_version == 'latest' else matrix_bridge_postmoogle_version }}" +matrix_bridge_postmoogle_container_src_files_path: "{{ matrix_base_data_path }}/postmoogle/docker-src" # renovate: datasource=docker depName=ghcr.io/etkecc/postmoogle -matrix_postmoogle_version: v0.9.29 -matrix_postmoogle_container_image: "{{ matrix_postmoogle_container_image_registry_prefix }}etkecc/postmoogle:{{ matrix_postmoogle_version }}" -matrix_postmoogle_container_image_registry_prefix: "{{ 'localhost/' if matrix_postmoogle_container_image_self_build else matrix_postmoogle_container_image_registry_prefix_upstream }}" -matrix_postmoogle_container_image_registry_prefix_upstream: "{{ matrix_postmoogle_container_image_registry_prefix_upstream_default }}" -matrix_postmoogle_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_postmoogle_container_image_force_pull: "{{ matrix_postmoogle_container_image.endswith(':latest') }}" +matrix_bridge_postmoogle_version: v0.9.31 +matrix_bridge_postmoogle_container_image: "{{ matrix_bridge_postmoogle_container_image_registry_prefix }}etkecc/postmoogle:{{ matrix_bridge_postmoogle_version }}" +matrix_bridge_postmoogle_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_postmoogle_container_image_self_build else matrix_bridge_postmoogle_container_image_registry_prefix_upstream }}" +matrix_bridge_postmoogle_container_image_registry_prefix_upstream: "{{ matrix_bridge_postmoogle_container_image_registry_prefix_upstream_default }}" +matrix_bridge_postmoogle_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_postmoogle_base_path: "{{ matrix_base_data_path }}/postmoogle" -matrix_postmoogle_config_path: "{{ matrix_postmoogle_base_path }}/config" -matrix_postmoogle_data_path: "{{ matrix_postmoogle_base_path }}/data" +matrix_bridge_postmoogle_base_path: "{{ matrix_base_data_path }}/postmoogle" +matrix_bridge_postmoogle_config_path: "{{ matrix_bridge_postmoogle_base_path }}/config" +matrix_bridge_postmoogle_data_path: "{{ matrix_bridge_postmoogle_base_path }}/data" -matrix_postmoogle_container_network: "" +matrix_bridge_postmoogle_container_network: "" -matrix_postmoogle_container_additional_networks: "{{ matrix_postmoogle_container_additional_networks_auto + matrix_postmoogle_container_additional_networks_custom }}" -matrix_postmoogle_container_additional_networks_auto: [] -matrix_postmoogle_container_additional_networks_custom: [] +matrix_bridge_postmoogle_container_additional_networks: "{{ matrix_bridge_postmoogle_container_additional_networks_auto + matrix_bridge_postmoogle_container_additional_networks_custom }}" +matrix_bridge_postmoogle_container_additional_networks_auto: [] +matrix_bridge_postmoogle_container_additional_networks_custom: [] # A list of extra arguments to pass to the container -matrix_postmoogle_container_extra_arguments: [] +matrix_bridge_postmoogle_container_extra_arguments: [] # List of systemd services that matrix-postmoogle.service depends on -matrix_postmoogle_systemd_required_services_list: "{{ matrix_postmoogle_systemd_required_services_list_default + matrix_postmoogle_systemd_required_services_list_auto + matrix_postmoogle_systemd_required_services_list_custom }}" -matrix_postmoogle_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_postmoogle_systemd_required_services_list_auto: [] -matrix_postmoogle_systemd_required_services_list_custom: [] +matrix_bridge_postmoogle_systemd_required_services_list: "{{ matrix_bridge_postmoogle_systemd_required_services_list_default + matrix_bridge_postmoogle_systemd_required_services_list_auto + matrix_bridge_postmoogle_systemd_required_services_list_custom }}" +matrix_bridge_postmoogle_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_postmoogle_systemd_required_services_list_auto: [] +matrix_bridge_postmoogle_systemd_required_services_list_custom: [] # List of systemd services that matrix-postmoogle.service wants -matrix_postmoogle_systemd_wanted_services_list: [] +matrix_bridge_postmoogle_systemd_wanted_services_list: [] # Database-related configuration fields. # # To use SQLite, stick to these defaults. # # To use Postgres: -# - change the engine (`matrix_postmoogle_database_engine: 'postgres'`) -# - adjust your database credentials via the `matrix_postmoogle_database_*` variables -matrix_postmoogle_database_engine: 'sqlite' - -matrix_postmoogle_sqlite_database_path_local: "{{ matrix_postmoogle_data_path }}/bot.db" -matrix_postmoogle_sqlite_database_path_in_container: "/data/bot.db" - -matrix_postmoogle_database_username: 'postmoogle' -matrix_postmoogle_database_password: 'some-password' -matrix_postmoogle_database_hostname: '' -matrix_postmoogle_database_port: 5432 -matrix_postmoogle_database_name: 'postmoogle' -matrix_postmoogle_database_sslmode: disable - -matrix_postmoogle_database_connection_string: 'postgres://{{ matrix_postmoogle_database_username }}:{{ matrix_postmoogle_database_password }}@{{ matrix_postmoogle_database_hostname }}:{{ matrix_postmoogle_database_port }}/{{ matrix_postmoogle_database_name }}?sslmode={{ matrix_postmoogle_database_sslmode }}' - -matrix_postmoogle_storage_database: "{{ - { - 'sqlite': matrix_postmoogle_sqlite_database_path_in_container, - 'postgres': matrix_postmoogle_database_connection_string, - }[matrix_postmoogle_database_engine] -}}" - -matrix_postmoogle_database_dialect: "{{ - { +# - change the engine (`matrix_bridge_postmoogle_database_engine: 'postgres'`) +# - adjust your database credentials via the `matrix_bridge_postmoogle_database_*` variables +matrix_bridge_postmoogle_database_engine: 'sqlite' + +matrix_bridge_postmoogle_sqlite_database_path_local: "{{ matrix_bridge_postmoogle_data_path }}/bot.db" +matrix_bridge_postmoogle_sqlite_database_path_in_container: "/data/bot.db" + +matrix_bridge_postmoogle_database_username: 'postmoogle' +matrix_bridge_postmoogle_database_password: 'some-password' +matrix_bridge_postmoogle_database_hostname: '' +matrix_bridge_postmoogle_database_port: 5432 +matrix_bridge_postmoogle_database_name: 'postmoogle' +matrix_bridge_postmoogle_database_sslmode: disable + +matrix_bridge_postmoogle_database_connection_string: 'postgres://{{ matrix_bridge_postmoogle_database_username }}:{{ matrix_bridge_postmoogle_database_password }}@{{ matrix_bridge_postmoogle_database_hostname }}:{{ matrix_bridge_postmoogle_database_port }}/{{ matrix_bridge_postmoogle_database_name }}?sslmode={{ matrix_bridge_postmoogle_database_sslmode }}' + +matrix_bridge_postmoogle_storage_database: "{{ { + 'sqlite': matrix_bridge_postmoogle_sqlite_database_path_in_container, + 'postgres': matrix_bridge_postmoogle_database_connection_string, +}[matrix_bridge_postmoogle_database_engine] }}" + +matrix_bridge_postmoogle_database_dialect: "{{ { 'sqlite': 'sqlite3', 'postgres': 'postgres', - }[matrix_postmoogle_database_engine] -}}" +}[matrix_bridge_postmoogle_database_engine] }}" # The bot's username. This user needs to be created manually beforehand. -# Also see `matrix_postmoogle_password` or `matrix_postmoogle_sharedsecret` -matrix_postmoogle_login: "postmoogle" +# Also see `matrix_bridge_postmoogle_password` or `matrix_bridge_postmoogle_sharedsecret` +matrix_bridge_postmoogle_login: "postmoogle" # The password that the bot uses to authenticate. -matrix_postmoogle_password: '' +matrix_bridge_postmoogle_password: '' -# Alternative to password - shared secret requires matrix_postmoogle_login to be MXID -matrix_postmoogle_sharedsecret: '' +# Alternative to password - shared secret requires matrix_bridge_postmoogle_login to be MXID +matrix_bridge_postmoogle_sharedsecret: '' -matrix_postmoogle_homeserver: "" +matrix_bridge_postmoogle_homeserver: "" # Command prefix -matrix_postmoogle_prefix: '!pm' +matrix_bridge_postmoogle_prefix: '!pm' # Max email size in megabytes, including attachments -matrix_postmoogle_maxsize: '1024' +matrix_bridge_postmoogle_maxsize: '1024' # Optional SMTP relay mode -matrix_postmoogle_relay_host: '' -matrix_postmoogle_relay_port: '' -matrix_postmoogle_relay_username: '' -matrix_postmoogle_relay_password: '' +matrix_bridge_postmoogle_relay_host: '' +matrix_bridge_postmoogle_relay_port: '' +matrix_bridge_postmoogle_relay_username: '' +matrix_bridge_postmoogle_relay_password: '' # A list of admins # Example set of rules: -# matrix_postmoogle_admins: +# matrix_bridge_postmoogle_admins: # - '@alice:example.com' # - '@bob:example.com' # - '@bot.*:example.com' # - '@*:example.net' -matrix_postmoogle_admins: "{{ [matrix_admin] if matrix_admin else [] }}" +matrix_bridge_postmoogle_admins: "{{ [matrix_admin] if matrix_admin else [] }}" -# Sentry DSN. Deprecated, use matrix_postmoogle_monitoring_sentry_dsn -matrix_postmoogle_sentry: '' +# Sentry DSN. Deprecated, use matrix_bridge_postmoogle_monitoring_sentry_dsn +matrix_bridge_postmoogle_sentry: '' # Sentry integration -matrix_postmoogle_monitoring_sentry_dsn: "{{ matrix_postmoogle_sentry }}" -matrix_postmoogle_monitoring_sentry_rate: 20 +matrix_bridge_postmoogle_monitoring_sentry_dsn: "{{ matrix_bridge_postmoogle_sentry }}" +matrix_bridge_postmoogle_monitoring_sentry_rate: 20 # healthchecks.io integration -matrix_postmoogle_monitoring_healthchecks_uuid: '' -matrix_postmoogle_monitoring_healthchecks_duration: 60 +matrix_bridge_postmoogle_monitoring_healthchecks_uuid: '' +matrix_bridge_postmoogle_monitoring_healthchecks_duration: 60 # Log level -matrix_postmoogle_loglevel: 'INFO' +matrix_bridge_postmoogle_loglevel: 'INFO' -# deprecated, use matrix_postmoogle_domains -matrix_postmoogle_domain: "{{ matrix_server_fqn_matrix }}" +# deprecated, use matrix_bridge_postmoogle_domains +matrix_bridge_postmoogle_domain: "{{ matrix_server_fqn_matrix }}" -matrix_postmoogle_domains: - - "{{ matrix_postmoogle_domain }}" # backward compatibility +matrix_bridge_postmoogle_domains: + - "{{ matrix_bridge_postmoogle_domain }}" # backward compatibility # Password (passphrase) to encrypt account data -matrix_postmoogle_data_secret: "" +matrix_bridge_postmoogle_data_secret: "" # in-container ports -matrix_postmoogle_port: '2525' -matrix_postmoogle_tls_port: '25587' +matrix_bridge_postmoogle_port: '2525' +matrix_bridge_postmoogle_tls_port: '25587' # on-host ports -matrix_postmoogle_smtp_host_bind_port: '25' -matrix_postmoogle_submission_host_bind_port: '587' +matrix_bridge_postmoogle_smtp_host_bind_port: '25' +matrix_bridge_postmoogle_submission_host_bind_port: '587' ### SSL ## on-host SSL dir -matrix_postmoogle_ssl_path: "" +matrix_bridge_postmoogle_ssl_path: "" ## in-container SSL paths -# matrix_postmoogle_tls_cert is the SSL certificates' certificates. +# matrix_bridge_postmoogle_tls_cert is the SSL certificates' certificates. # This var is likely set via group_vars/matrix_servers, so you don't need to set certs manually. # If you do need to set it manually, note that this is an in-container path. -# To mount a certificates volumes into the container, use matrix_postmoogle_ssl_path -# Example value: /ssl/live/{{ matrix_postmoogle_domain }}/fullchain.pem -matrix_postmoogle_tls_cert: "" +# To mount a certificates volumes into the container, use matrix_bridge_postmoogle_ssl_path +# Example value: /ssl/live/{{ matrix_bridge_postmoogle_domain }}/fullchain.pem +matrix_bridge_postmoogle_tls_cert: "" -# matrix_postmoogle_tls_key is the SSL certificates' keys. +# matrix_bridge_postmoogle_tls_key is the SSL certificates' keys. # This var is likely set via group_vars/matrix_servers, so you don't need to set keys manually. # If you do need to set it manually, note that this is an in-container path. -# To mount a certificates volumes into the container, use matrix_postmoogle_ssl_path -# Example value: /ssl/live/{{ matrix_postmoogle_domain }}/privkey.pem -matrix_postmoogle_tls_key: "" +# To mount a certificates volumes into the container, use matrix_bridge_postmoogle_ssl_path +# Example value: /ssl/live/{{ matrix_bridge_postmoogle_domain }}/privkey.pem +matrix_bridge_postmoogle_tls_key: "" # Mandatory TLS, even on plain SMTP port -matrix_postmoogle_tls_required: false +matrix_bridge_postmoogle_tls_required: false # trusted proxies -matrix_postmoogle_proxies: [] +matrix_bridge_postmoogle_proxies: [] # known forwarders -matrix_postmoogle_mailboxes_forwarded: [] +matrix_bridge_postmoogle_mailboxes_forwarded: [] # reserved mailboxes -matrix_postmoogle_mailboxes_reserved: [] +matrix_bridge_postmoogle_mailboxes_reserved: [] # mailbox activation flow -matrix_postmoogle_mailboxes_activation: none +matrix_bridge_postmoogle_mailboxes_activation: none # Additional environment variables to pass to the postmoogle container # # Example: -# matrix_postmoogle_environment_variables_extension: | +# matrix_bridge_postmoogle_environment_variables_extension: | # postmoogle_TEXT_DONE=Done -matrix_postmoogle_environment_variables_extension: '' +matrix_bridge_postmoogle_environment_variables_extension: '' -# matrix_postmoogle_restart_necessary controls whether the service +# matrix_bridge_postmoogle_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -196,4 +191,4 @@ matrix_postmoogle_environment_variables_extension: '' # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_postmoogle_restart_necessary: false +matrix_bridge_postmoogle_restart_necessary: false diff --git a/roles/custom/matrix-bridge-postmoogle/molecule/default/converge.yml b/roles/custom/matrix-bridge-postmoogle/molecule/default/converge.yml new file mode 100644 index 000000000..5b2c85369 --- /dev/null +++ b/roles/custom/matrix-bridge-postmoogle/molecule/default/converge.yml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for Postmoogle Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for Postmoogle Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +# The role installs the unit but does not start it; systemd_service_manager does that in the +# full playbook. +- name: Ensure Postmoogle is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the Postmoogle systemd service is started + ansible.builtin.systemd_service: + name: matrix-postmoogle.service + state: started diff --git a/roles/custom/matrix-bridge-postmoogle/molecule/default/molecule.yml b/roles/custom/matrix-bridge-postmoogle/molecule/default/molecule.yml new file mode 100644 index 000000000..24c5e0ef7 --- /dev/null +++ b/roles/custom/matrix-bridge-postmoogle/molecule/default/molecule.yml @@ -0,0 +1,93 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: postmoogle-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_postmoogle_container_network: postmoogle-molecule + + # The shared stub prepare.yml stands up. It accepts the password login and returns + # the full MXID corresponding to this deliberately non-default localpart. + matrix_bridge_postmoogle_homeserver: http://matrix.molecule.local:8008 + matrix_bridge_postmoogle_login: molecule-postmoogle + matrix_bridge_postmoogle_password: molecule_matrix_password_d8a314 + + # Postgres is what group_vars/matrix_servers selects whenever the playbook-managed + # Postgres is enabled. The name, user and password differ from the role's defaults, + # so a migrated schema proves that the role composed and the process used this DSN. + matrix_bridge_postmoogle_database_engine: postgres + matrix_bridge_postmoogle_database_hostname: matrix-postgres-molecule + matrix_bridge_postmoogle_database_name: molecule_postmoogle + matrix_bridge_postmoogle_database_username: molecule_postmoogle + matrix_bridge_postmoogle_database_password: molecule_pg_password_7e9c42 + + # These differ from the role's defaults and are asserted against the parsed env file. + matrix_bridge_postmoogle_domains: + - mail.molecule.local + - inbound.molecule.local + matrix_bridge_postmoogle_prefix: "!molecule-mail" + matrix_bridge_postmoogle_maxsize: "73" + matrix_bridge_postmoogle_loglevel: DEBUG + matrix_bridge_postmoogle_admins: + - "@molecule-admin:molecule.local" + - "@mail-.*:molecule.local" + # A valid 32-byte AES key, deliberately not empty like the role default. + matrix_bridge_postmoogle_data_secret: 0123456789abcdef0123456789abcdef + matrix_bridge_postmoogle_proxies: + - 192.0.2.44 + matrix_bridge_postmoogle_mailboxes_forwarded: + - forwarded + matrix_bridge_postmoogle_mailboxes_reserved: + - reserved + + # Port 25 is inappropriate for a test and can already be occupied. Both the + # in-container port and the high host port are non-default, so an SMTP exchange on + # the former plus Docker's accepted binding for the latter proves the wiring. + matrix_bridge_postmoogle_port: "2626" + matrix_bridge_postmoogle_smtp_host_bind_port: "25252" + + # verify.yml is a separate play, where the role's defaults are out of scope. + matrix_bridge_postmoogle_base_path: /matrix/postmoogle + matrix_bridge_postmoogle_config_path: /matrix/postmoogle/config + matrix_bridge_postmoogle_data_path: /matrix/postmoogle/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-postmoogle/molecule/default/prepare.yml b/roles/custom/matrix-bridge-postmoogle/molecule/default/prepare.yml new file mode 100644 index 000000000..99ee16d63 --- /dev/null +++ b/roles/custom/matrix-bridge-postmoogle/molecule/default/prepare.yml @@ -0,0 +1,88 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare Postmoogle Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_postmoogle_container_network }}" + register: matrix_bridge_postmoogle_molecule_network + changed_when: matrix_bridge_postmoogle_molecule_network.rc == 0 + failed_when: + - matrix_bridge_postmoogle_molecule_network.rc != 0 + - "'already exists' not in matrix_bridge_postmoogle_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_postmoogle_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_postmoogle_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_postmoogle_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_postmoogle_database_password }}" + + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_postmoogle_container_network }}" + molecule_shared_stub_server_name: molecule.local + molecule_shared_stub_user_id: "@{{ matrix_bridge_postmoogle_login }}:molecule.local" + # Its request log is useful here because Postmoogle has no Matrix-facing HTTP + # endpoint of its own. It proves that startup crossed the Matrix login boundary. + molecule_shared_stub_verbose: "1" diff --git a/roles/custom/matrix-bridge-postmoogle/molecule/default/requirements.yml b/roles/custom/matrix-bridge-postmoogle/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-postmoogle/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-postmoogle/molecule/default/verify.yml b/roles/custom/matrix-bridge-postmoogle/molecule/default/verify.yml new file mode 100644 index 000000000..9c2ec2d35 --- /dev/null +++ b/roles/custom/matrix-bridge-postmoogle/molecule/default/verify.yml @@ -0,0 +1,265 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves Postmoogle logs in as the bot the role configured, migrates the Postgres database +# the role pointed it at, and serves SMTP on the non-default port the role rendered. The SMTP +# probe stops after EHLO: this scenario deliberately never bridges real mail. +- name: Verify Postmoogle + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + + vars: + matrix_bridge_postmoogle_molecule_user_id: "@{{ matrix_bridge_postmoogle_login }}:molecule.local" + matrix_bridge_postmoogle_molecule_database_dsn: >- + postgres://{{ matrix_bridge_postmoogle_database_username }}:{{ matrix_bridge_postmoogle_database_password }}@{{ matrix_bridge_postmoogle_database_hostname }}:5432/{{ matrix_bridge_postmoogle_database_name }}?sslmode=disable + matrix_bridge_postmoogle_container: "{{ (matrix_bridge_postmoogle_container_inspect.stdout | from_json) | first }}" + + tasks: + # From the role's defaults rather than pinned in molecule.yml, so the image assertion + # compares the running image against what the role ships, not the scenario itself. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_bridge_postmoogle_role_defaults + + - name: Wait for the Postmoogle service to become active + ansible.builtin.systemd_service: + name: matrix-postmoogle.service + register: matrix_bridge_postmoogle_service + until: matrix_bridge_postmoogle_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes a crash-looping container appear active. The counter is therefore + # part of the same assertion, and `is defined` prevents a missing counter becoming 0. + - name: Assert the service is active and has not been restarting + ansible.builtin.assert: + that: + - matrix_bridge_postmoogle_service.status.ActiveState == 'active' + - matrix_bridge_postmoogle_service.status.NRestarts is defined + - matrix_bridge_postmoogle_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-postmoogle.service is + {{ matrix_bridge_postmoogle_service.status.ActiveState | default('unknown') }} + after {{ matrix_bridge_postmoogle_service.status.NRestarts | default('?') }} + automatic restart(s) + success_msg: "matrix-postmoogle.service is active and has not restarted" + + # The unit attaches the container output to journald. Strip its ANSI colours and filter + # the whole journal: the login line is among the oldest and would disappear from a tail. + - name: Wait for Postmoogle to report Matrix login and SMTP startup + ansible.builtin.shell: + cmd: >- + set -o pipefail; + journalctl --unit=matrix-postmoogle.service --no-pager --output=cat --lines=all + | sed -r 's/\x1B\[[0-9;]*[mK]//g' + | grep -E 'Stored credentials after login|Starting SMTP server|cannot initialize matrix bot' + | head -n 30 || true + executable: /bin/bash + register: matrix_bridge_postmoogle_journal + changed_when: false + until: + - "'Stored credentials after login' in matrix_bridge_postmoogle_journal.stdout" + - "'Starting SMTP server' in matrix_bridge_postmoogle_journal.stdout" + retries: 24 + delay: 5 + failed_when: false + + # "Stored credentials after login" is emitted after the Matrix /login response has been + # accepted. Requiring the returned MXID proves the URL, localpart and password were good + # enough for a login round-trip, rather than only appearing in a file on disk. + - name: Assert Postmoogle logged in as the configured bot + ansible.builtin.assert: + that: + - "'Stored credentials after login' in matrix_bridge_postmoogle_journal.stdout" + - "'user_id=' ~ matrix_bridge_postmoogle_molecule_user_id in matrix_bridge_postmoogle_journal.stdout" + - "'cannot initialize matrix bot' not in matrix_bridge_postmoogle_journal.stdout" + fail_msg: >- + Postmoogle did not log in as {{ matrix_bridge_postmoogle_molecule_user_id }} + success_msg: "Postmoogle completed Matrix login as the configured bot" + + - name: Assert Postmoogle opened its configured SMTP port + ansible.builtin.assert: + that: + - "'Starting SMTP server port=' ~ matrix_bridge_postmoogle_port in matrix_bridge_postmoogle_journal.stdout" + fail_msg: "Postmoogle did not start SMTP on port {{ matrix_bridge_postmoogle_port }}" + success_msg: "Postmoogle started its configured SMTP listener" + + # This is an actual SMTP readiness exchange over the container network, not only a TCP + # connect. It sends EHLO and stops there, without supplying an envelope or message body. + - name: Exchange an SMTP banner and EHLO with Postmoogle + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_postmoogle_container_network }} + - "{{ molecule_shared_image_python }}" + - python3 + - -c + - >- + import socket; + s=socket.create_connection(("matrix-postmoogle", {{ matrix_bridge_postmoogle_port | int }}), 5); + s.settimeout(5); + banner=s.recv(4096).decode(); + s.sendall(b"EHLO molecule.local\r\n"); + reply=s.recv(4096).decode(); + print("BANNER=" + repr(banner)); + print("EHLO=" + repr(reply)); + s.close() + register: matrix_bridge_postmoogle_smtp + changed_when: false + retries: 24 + delay: 5 + until: matrix_bridge_postmoogle_smtp.rc == 0 + failed_when: false + + - name: Assert Postmoogle completed the SMTP readiness exchange + ansible.builtin.assert: + that: + - matrix_bridge_postmoogle_smtp.rc == 0 + - "\"BANNER='220\" in matrix_bridge_postmoogle_smtp.stdout" + - "\"EHLO='250\" in matrix_bridge_postmoogle_smtp.stdout" + fail_msg: >- + Postmoogle did not return a 220 banner and 250 EHLO response on port + {{ matrix_bridge_postmoogle_port }} + ({{ matrix_bridge_postmoogle_smtp.stdout | default('no output') }}) + success_msg: "Postmoogle completes an SMTP banner and EHLO exchange" + + - name: Read the environment file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_postmoogle_config_path }}/env" + register: matrix_bridge_postmoogle_env_file + + - name: Read the environment file's ownership and mode + ansible.builtin.stat: + path: "{{ matrix_bridge_postmoogle_config_path }}/env" + register: matrix_bridge_postmoogle_env_stat + + # Parse the key=value document instead of substring-matching it, including the DSN's own + # equals sign by splitting each line only once. + - name: Parse the rendered Postmoogle environment + ansible.builtin.set_fact: + matrix_bridge_postmoogle_env: >- + {{ matrix_bridge_postmoogle_env | default({}) | combine(dict([item.split('=', 1)])) }} + loop: "{{ (matrix_bridge_postmoogle_env_file.content | b64decode).splitlines() }}" + when: item is search('=') + no_log: true + + - name: Assert the parsed environment carries this scenario's configuration + ansible.builtin.assert: + that: + - matrix_bridge_postmoogle_actual_env == matrix_bridge_postmoogle_expected_env + fail_msg: "The rendered environment does not carry the scenario's values" + success_msg: "The parsed environment carries the scenario's values" + vars: + matrix_bridge_postmoogle_expected_env: + POSTMOOGLE_LOGIN: "{{ matrix_bridge_postmoogle_login }}" + POSTMOOGLE_PASSWORD: "{{ matrix_bridge_postmoogle_password }}" + POSTMOOGLE_HOMESERVER: "{{ matrix_bridge_postmoogle_homeserver }}" + POSTMOOGLE_DOMAINS: "{{ matrix_bridge_postmoogle_domains | join(' ') }}" + POSTMOOGLE_PORT: "{{ matrix_bridge_postmoogle_port }}" + POSTMOOGLE_DB_DSN: "{{ matrix_bridge_postmoogle_molecule_database_dsn | trim }}" + POSTMOOGLE_DB_DIALECT: postgres + POSTMOOGLE_PREFIX: "{{ matrix_bridge_postmoogle_prefix }}" + POSTMOOGLE_MAXSIZE: "{{ matrix_bridge_postmoogle_maxsize }}" + POSTMOOGLE_LOGLEVEL: "{{ matrix_bridge_postmoogle_loglevel }}" + POSTMOOGLE_ADMINS: "{{ matrix_bridge_postmoogle_admins | join(' ') }}" + POSTMOOGLE_DATA_SECRET: "{{ matrix_bridge_postmoogle_data_secret }}" + POSTMOOGLE_PROXIES: "{{ matrix_bridge_postmoogle_proxies | join(' ') }}" + POSTMOOGLE_MAILBOXES_FORWARDED: "{{ matrix_bridge_postmoogle_mailboxes_forwarded | join(' ') }}" + POSTMOOGLE_MAILBOXES_RESERVED: "{{ matrix_bridge_postmoogle_mailboxes_reserved | join(' ') }}" + matrix_bridge_postmoogle_actual_env: >- + {{ matrix_bridge_postmoogle_env | dict2items + | selectattr('key', 'in', matrix_bridge_postmoogle_expected_env.keys()) + | items2dict }} + + - name: Assert the environment file has the playbook-supplied identity and private mode + ansible.builtin.assert: + that: + - matrix_bridge_postmoogle_env_stat.stat.uid | int == matrix_user_uid | int + - matrix_bridge_postmoogle_env_stat.stat.gid | int == matrix_user_gid | int + - matrix_bridge_postmoogle_env_stat.stat.mode == '0640' + fail_msg: "The environment file does not have the expected identity or mode" + success_msg: "The environment file has the playbook-supplied identity and private mode" + + # These tables can only exist after Postmoogle has resolved the non-default hostname, + # authenticated with the non-default credentials and run its Matrix/crypto migrations. + - name: List the tables Postmoogle created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_postmoogle_database_username }} + - --dbname={{ matrix_bridge_postmoogle_database_name }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: matrix_bridge_postmoogle_tables + changed_when: false + + - name: Assert Postmoogle migrated its schema into the configured database + ansible.builtin.assert: + that: + - matrix_bridge_postmoogle_tables.rc == 0 + - "'mx_version' in matrix_bridge_postmoogle_table_names" + - "'crypto_version' in matrix_bridge_postmoogle_table_names" + - matrix_bridge_postmoogle_table_names | length > 10 + fail_msg: >- + Postmoogle did not create its Matrix and crypto schema in + {{ matrix_bridge_postmoogle_database_name }} + success_msg: "Postmoogle migrated its schema into the configured Postgres database" + vars: + matrix_bridge_postmoogle_table_names: "{{ matrix_bridge_postmoogle_tables.stdout_lines | select | list }}" + + - name: Inspect the running Postmoogle container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-postmoogle + register: matrix_bridge_postmoogle_container_inspect + changed_when: false + + - name: Assert the running container uses the exact pinned image + ansible.builtin.assert: + that: + - matrix_bridge_postmoogle_container.Config.Image == 'ghcr.io/etkecc/postmoogle:' ~ matrix_bridge_postmoogle_role_defaults.matrix_bridge_postmoogle_version + fail_msg: "The running container does not use the exact image the role pins" + success_msg: "The running container uses the exact image the role pins" + + - name: Assert the running container uses the playbook identity and a read-only root filesystem + ansible.builtin.assert: + that: + - matrix_bridge_postmoogle_container.Config.User == matrix_user_uid ~ ':' ~ matrix_user_gid + - matrix_bridge_postmoogle_container.HostConfig.ReadonlyRootfs + fail_msg: "The running container does not use the expected identity or read-only root filesystem" + success_msg: "The running container uses the playbook identity and a read-only root filesystem" + + - name: Assert the running container is attached to the configured network + ansible.builtin.assert: + that: + - matrix_bridge_postmoogle_container_network in matrix_bridge_postmoogle_container.NetworkSettings.Networks + fail_msg: "The running container is not attached to {{ matrix_bridge_postmoogle_container_network }}" + success_msg: "The running container is attached to the configured network" + + # The high host binding is read back from Docker rather than merely from the unit file. + # Docker could not have started the container if that binding were invalid. + - name: Assert Docker published only the configured SMTP port + ansible.builtin.assert: + that: + - matrix_bridge_postmoogle_port ~ '/tcp' in matrix_bridge_postmoogle_container.HostConfig.PortBindings + - matrix_bridge_postmoogle_container.HostConfig.PortBindings[matrix_bridge_postmoogle_port ~ '/tcp'][0].HostPort == matrix_bridge_postmoogle_smtp_host_bind_port + - "'25/tcp' not in matrix_bridge_postmoogle_container.HostConfig.PortBindings" + fail_msg: "Docker does not carry the configured high SMTP binding, or also publishes port 25" + success_msg: "Docker published only the configured high SMTP binding" diff --git a/roles/custom/matrix-bridge-postmoogle/tasks/main.yml b/roles/custom/matrix-bridge-postmoogle/tasks/main.yml index ecbbff69a..61b9fd6aa 100644 --- a/roles/custom/matrix-bridge-postmoogle/tasks/main.yml +++ b/roles/custom/matrix-bridge-postmoogle/tasks/main.yml @@ -12,15 +12,15 @@ - install-all - install-postmoogle block: - - when: matrix_postmoogle_enabled | bool + - when: matrix_bridge_postmoogle_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_postmoogle_enabled | bool + - when: matrix_bridge_postmoogle_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-postmoogle block: - - when: not matrix_postmoogle_enabled | bool + - when: not matrix_bridge_postmoogle_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-postmoogle/tasks/setup_install.yml b/roles/custom/matrix-bridge-postmoogle/tasks/setup_install.yml index 84be8e04c..8b2c703da 100644 --- a/roles/custom/matrix-bridge-postmoogle/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-postmoogle/tasks/setup_install.yml @@ -32,29 +32,29 @@ path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-postmoogle.service" state: absent -- when: "matrix_postmoogle_database_engine == 'postgres'" +- when: "matrix_bridge_postmoogle_database_engine == 'postgres'" block: - name: Check if an SQLite database already exists ansible.builtin.stat: - path: "{{ matrix_postmoogle_sqlite_database_path_local }}" - register: matrix_postmoogle_sqlite_database_path_local_stat_result + path: "{{ matrix_bridge_postmoogle_sqlite_database_path_local }}" + register: matrix_bridge_postmoogle_sqlite_database_path_local_stat_result - - when: "matrix_postmoogle_sqlite_database_path_local_stat_result.stat.exists | bool" + - when: "matrix_bridge_postmoogle_sqlite_database_path_local_stat_result.stat.exists | bool" block: - ansible.builtin.include_role: name: galaxy/postgres tasks_from: migrate_db_to_postgres vars: postgres_db_migration_request: - src: "{{ matrix_postmoogle_sqlite_database_path_local }}" - dst: "{{ matrix_postmoogle_database_connection_string }}" + src: "{{ matrix_bridge_postmoogle_sqlite_database_path_local }}" + dst: "{{ matrix_bridge_postmoogle_database_connection_string }}" caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_postmoogle_database_engine' + engine_variable_name: 'matrix_bridge_postmoogle_database_engine' engine_old: 'sqlite' systemd_services_to_stop: ['matrix-postmoogle.service'] - ansible.builtin.set_fact: - matrix_postmoogle_migration_requires_restart: true + matrix_bridge_postmoogle_migration_requires_restart: true - name: Ensure postmoogle paths exist ansible.builtin.file: @@ -64,59 +64,66 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_postmoogle_config_path }}", when: true} - - {path: "{{ matrix_postmoogle_data_path }}", when: true} - - {path: "{{ matrix_postmoogle_container_src_files_path }}", when: "{{ matrix_postmoogle_container_image_self_build }}"} + - {path: "{{ matrix_bridge_postmoogle_config_path }}", when: true} + - {path: "{{ matrix_bridge_postmoogle_data_path }}", when: true} + - {path: "{{ matrix_bridge_postmoogle_container_src_files_path }}", when: "{{ matrix_bridge_postmoogle_container_image_self_build }}"} when: "item.when | bool" - name: Ensure postmoogle environment variables file created ansible.builtin.template: src: "{{ role_path }}/templates/env.j2" - dest: "{{ matrix_postmoogle_config_path }}/env" + dest: "{{ matrix_bridge_postmoogle_config_path }}/env" owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" mode: '0640' - register: matrix_postmoogle_env_result + register: matrix_bridge_postmoogle_env_result - name: Ensure postmoogle image is pulled - community.docker.docker_image: - name: "{{ matrix_postmoogle_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_postmoogle_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_postmoogle_container_image_force_pull }}" - when: "not matrix_postmoogle_container_image_self_build | bool" - register: matrix_postmoogle_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_postmoogle_container_image }}" + pull: always + when: "not matrix_bridge_postmoogle_container_image_self_build | bool" + register: matrix_bridge_postmoogle_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_postmoogle_container_image_pull_result is not failed + until: matrix_bridge_postmoogle_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure postmoogle repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_postmoogle_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_postmoogle_container_image_self_build | bool" - name: Ensure postmoogle repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_postmoogle_container_repo }}" - version: "{{ matrix_postmoogle_container_repo_version }}" - dest: "{{ matrix_postmoogle_container_src_files_path }}" + repo: "{{ matrix_bridge_postmoogle_container_repo }}" + version: "{{ matrix_bridge_postmoogle_container_repo_version }}" + dest: "{{ matrix_bridge_postmoogle_container_src_files_path }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_postmoogle_git_pull_results - when: "matrix_postmoogle_container_image_self_build | bool" + register: matrix_bridge_postmoogle_git_pull_results + when: "matrix_bridge_postmoogle_container_image_self_build | bool" - name: Ensure postmoogle image is built - community.docker.docker_image: - name: "{{ matrix_postmoogle_container_image }}" - source: build - force_source: "{{ matrix_postmoogle_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_postmoogle_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_postmoogle_container_src_files_path }}" - pull: true - when: "matrix_postmoogle_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_postmoogle_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_postmoogle_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_postmoogle_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_postmoogle_container_image_self_build | bool" + register: matrix_bridge_postmoogle_container_image_build_result - name: Ensure postmoogle container network is created + when: matrix_bridge_postmoogle_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_postmoogle_container_network }}" + name: "{{ matrix_bridge_postmoogle_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -125,14 +132,15 @@ src: "{{ role_path }}/templates/systemd/matrix-postmoogle.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-postmoogle.service" mode: '0644' - register: matrix_postmoogle_systemd_service_result + register: matrix_bridge_postmoogle_systemd_service_result - name: Determine whether matrix-postmoogle needs a restart ansible.builtin.set_fact: - matrix_postmoogle_restart_necessary: >- + matrix_bridge_postmoogle_restart_necessary: >- {{ - matrix_postmoogle_migration_requires_restart | default(false) - or matrix_postmoogle_env_result.changed | default(false) - or matrix_postmoogle_systemd_service_result.changed | default(false) - or matrix_postmoogle_container_image_pull_result.changed | default(false) + matrix_bridge_postmoogle_migration_requires_restart | default(false) + or matrix_bridge_postmoogle_env_result.changed | default(false) + or matrix_bridge_postmoogle_systemd_service_result.changed | default(false) + or matrix_bridge_postmoogle_container_image_pull_result.changed | default(false) + or matrix_bridge_postmoogle_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-bridge-postmoogle/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-postmoogle/tasks/setup_uninstall.yml index 9db50fc5c..5ea461ebc 100644 --- a/roles/custom/matrix-bridge-postmoogle/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-postmoogle/tasks/setup_uninstall.yml @@ -10,9 +10,9 @@ - name: Check existence of matrix-postmoogle service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-postmoogle.service" - register: matrix_postmoogle_service_stat + register: matrix_bridge_postmoogle_service_stat -- when: matrix_postmoogle_service_stat.stat.exists | bool +- when: matrix_bridge_postmoogle_service_stat.stat.exists | bool block: - name: Ensure matrix-postmoogle is stopped ansible.builtin.service: @@ -28,5 +28,5 @@ - name: Ensure Matrix postmoogle paths don't exist ansible.builtin.file: - path: "{{ matrix_postmoogle_base_path }}" + path: "{{ matrix_bridge_postmoogle_base_path }}" state: absent diff --git a/roles/custom/matrix-bridge-postmoogle/tasks/validate_config.yml b/roles/custom/matrix-bridge-postmoogle/tasks/validate_config.yml index 6306650e0..d16747441 100644 --- a/roles/custom/matrix-bridge-postmoogle/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-postmoogle/tasks/validate_config.yml @@ -12,15 +12,16 @@ The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_postmoogle_docker_image_name_prefix', 'new': 'matrix_postmoogle_container_image_registry_prefix'} - - {'old': 'matrix_postmoogle_docker_image', 'new': 'matrix_postmoogle_container_image'} - - {'old': 'matrix_postmoogle_docker_image_force_pull', 'new': 'matrix_postmoogle_container_image_force_pull'} - - {'old': 'matrix_postmoogle_docker_image_registry_prefix', 'new': 'matrix_postmoogle_container_image_registry_prefix'} - - {'old': 'matrix_postmoogle_docker_image_registry_prefix_upstream', 'new': 'matrix_postmoogle_container_image_registry_prefix_upstream'} - - {'old': 'matrix_postmoogle_docker_image_registry_prefix_upstream_default', 'new': 'matrix_postmoogle_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_postmoogle_docker_repo', 'new': 'matrix_postmoogle_container_repo'} - - {'old': 'matrix_postmoogle_docker_repo_version', 'new': 'matrix_postmoogle_container_repo_version'} - - {'old': 'matrix_postmoogle_docker_src_files_path', 'new': 'matrix_postmoogle_container_src_files_path'} + - {'old': 'matrix_bridge_postmoogle_docker_image_name_prefix', 'new': 'matrix_bridge_postmoogle_container_image_registry_prefix'} + - {'old': 'matrix_bridge_postmoogle_docker_image', 'new': 'matrix_bridge_postmoogle_container_image'} + - {'old': 'matrix_bridge_postmoogle_docker_image_force_pull', 'new': 'matrix_bridge_postmoogle_container_image_force_pull'} + - {'old': 'matrix_bridge_postmoogle_docker_image_registry_prefix', 'new': 'matrix_bridge_postmoogle_container_image_registry_prefix'} + - {'old': 'matrix_bridge_postmoogle_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_postmoogle_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_postmoogle_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_postmoogle_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_postmoogle_docker_repo', 'new': 'matrix_bridge_postmoogle_container_repo'} + - {'old': 'matrix_bridge_postmoogle_docker_repo_version', 'new': 'matrix_bridge_postmoogle_container_repo_version'} + - {'old': 'matrix_bridge_postmoogle_docker_src_files_path', 'new': 'matrix_bridge_postmoogle_container_src_files_path'} + - {'old': 'matrix_bridge_postmoogle_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required Postmoogle settings not defined ansible.builtin.fail: @@ -28,7 +29,7 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_postmoogle_password', when: true} - - {'name': 'matrix_postmoogle_container_network', when: true} - - {'name': 'matrix_postmoogle_homeserver', when: true} - - {'name': 'matrix_postmoogle_database_hostname', when: "{{ matrix_postmoogle_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_postmoogle_password', when: true} + - {'name': 'matrix_bridge_postmoogle_container_network', when: true} + - {'name': 'matrix_bridge_postmoogle_homeserver', when: true} + - {'name': 'matrix_bridge_postmoogle_database_hostname', when: "{{ matrix_bridge_postmoogle_database_engine == 'postgres' }}"} diff --git a/roles/custom/matrix-bridge-postmoogle/templates/env.j2 b/roles/custom/matrix-bridge-postmoogle/templates/env.j2 index a2a8348bf..1d9c038f5 100644 --- a/roles/custom/matrix-bridge-postmoogle/templates/env.j2 +++ b/roles/custom/matrix-bridge-postmoogle/templates/env.j2 @@ -6,34 +6,34 @@ SPDX-FileCopyrightText: 2024 Suguru Hirahara SPDX-License-Identifier: AGPL-3.0-or-later #} -POSTMOOGLE_LOGIN={{ matrix_postmoogle_login }} -POSTMOOGLE_PASSWORD={{ matrix_postmoogle_password }} -POSTMOOGLE_SHAREDSECRET={{ matrix_postmoogle_sharedsecret }} -POSTMOOGLE_HOMESERVER={{ matrix_postmoogle_homeserver }} -POSTMOOGLE_DOMAINS={{ matrix_postmoogle_domains | join(' ') }} -POSTMOOGLE_PORT={{ matrix_postmoogle_port }} -POSTMOOGLE_DB_DSN={{ matrix_postmoogle_database_connection_string }} -POSTMOOGLE_DB_DIALECT={{ matrix_postmoogle_database_dialect }} -POSTMOOGLE_PREFIX={{ matrix_postmoogle_prefix }} -POSTMOOGLE_MAXSIZE={{ matrix_postmoogle_maxsize }} -POSTMOOGLE_LOGLEVEL={{ matrix_postmoogle_loglevel }} -POSTMOOGLE_ADMINS={{ matrix_postmoogle_admins | join(' ') }} -POSTMOOGLE_TLS_PORT={{ matrix_postmoogle_tls_port }} -POSTMOOGLE_TLS_CERT={{ matrix_postmoogle_tls_cert }} -POSTMOOGLE_TLS_KEY={{ matrix_postmoogle_tls_key }} -POSTMOOGLE_TLS_REQUIRED={{ matrix_postmoogle_tls_required }} -POSTMOOGLE_DATA_SECRET={{ matrix_postmoogle_data_secret }} -POSTMOOGLE_PROXIES={{ matrix_postmoogle_proxies | join(' ') }} -POSTMOOGLE_RELAY_HOST={{ matrix_postmoogle_relay_host }} -POSTMOOGLE_RELAY_PORT={{ matrix_postmoogle_relay_port }} -POSTMOOGLE_RELAY_USERNAME={{ matrix_postmoogle_relay_username }} -POSTMOOGLE_RELAY_PASSWORD={{ matrix_postmoogle_relay_password }} -POSTMOOGLE_MONITORING_SENTRY_DSN={{ matrix_postmoogle_monitoring_sentry_dsn }} -POSTMOOGLE_MONITORING_SENTRY_RATE={{ matrix_postmoogle_monitoring_sentry_rate }} -POSTMOOGLE_MONITORING_HEALTHCHECKS_UUID={{ matrix_postmoogle_monitoring_healthchecks_uuid }} -POSTMOOGLE_MONITORING_HEALTHCHECKS_DURATION={{ matrix_postmoogle_monitoring_healthchecks_duration }} -POSTMOOGLE_MAILBOXES_FORWARDED={{ matrix_postmoogle_mailboxes_forwarded | join(' ') }} -POSTMOOGLE_MAILBOXES_RESERVED={{ matrix_postmoogle_mailboxes_reserved | join(' ') }} -POSTMOOGLE_MAILBOXES_ACTIVATION={{ matrix_postmoogle_mailboxes_activation }} +POSTMOOGLE_LOGIN={{ matrix_bridge_postmoogle_login }} +POSTMOOGLE_PASSWORD={{ matrix_bridge_postmoogle_password }} +POSTMOOGLE_SHAREDSECRET={{ matrix_bridge_postmoogle_sharedsecret }} +POSTMOOGLE_HOMESERVER={{ matrix_bridge_postmoogle_homeserver }} +POSTMOOGLE_DOMAINS={{ matrix_bridge_postmoogle_domains | join(' ') }} +POSTMOOGLE_PORT={{ matrix_bridge_postmoogle_port }} +POSTMOOGLE_DB_DSN={{ matrix_bridge_postmoogle_database_connection_string }} +POSTMOOGLE_DB_DIALECT={{ matrix_bridge_postmoogle_database_dialect }} +POSTMOOGLE_PREFIX={{ matrix_bridge_postmoogle_prefix }} +POSTMOOGLE_MAXSIZE={{ matrix_bridge_postmoogle_maxsize }} +POSTMOOGLE_LOGLEVEL={{ matrix_bridge_postmoogle_loglevel }} +POSTMOOGLE_ADMINS={{ matrix_bridge_postmoogle_admins | join(' ') }} +POSTMOOGLE_TLS_PORT={{ matrix_bridge_postmoogle_tls_port }} +POSTMOOGLE_TLS_CERT={{ matrix_bridge_postmoogle_tls_cert }} +POSTMOOGLE_TLS_KEY={{ matrix_bridge_postmoogle_tls_key }} +POSTMOOGLE_TLS_REQUIRED={{ matrix_bridge_postmoogle_tls_required }} +POSTMOOGLE_DATA_SECRET={{ matrix_bridge_postmoogle_data_secret }} +POSTMOOGLE_PROXIES={{ matrix_bridge_postmoogle_proxies | join(' ') }} +POSTMOOGLE_RELAY_HOST={{ matrix_bridge_postmoogle_relay_host }} +POSTMOOGLE_RELAY_PORT={{ matrix_bridge_postmoogle_relay_port }} +POSTMOOGLE_RELAY_USERNAME={{ matrix_bridge_postmoogle_relay_username }} +POSTMOOGLE_RELAY_PASSWORD={{ matrix_bridge_postmoogle_relay_password }} +POSTMOOGLE_MONITORING_SENTRY_DSN={{ matrix_bridge_postmoogle_monitoring_sentry_dsn }} +POSTMOOGLE_MONITORING_SENTRY_RATE={{ matrix_bridge_postmoogle_monitoring_sentry_rate }} +POSTMOOGLE_MONITORING_HEALTHCHECKS_UUID={{ matrix_bridge_postmoogle_monitoring_healthchecks_uuid }} +POSTMOOGLE_MONITORING_HEALTHCHECKS_DURATION={{ matrix_bridge_postmoogle_monitoring_healthchecks_duration }} +POSTMOOGLE_MAILBOXES_FORWARDED={{ matrix_bridge_postmoogle_mailboxes_forwarded | join(' ') }} +POSTMOOGLE_MAILBOXES_RESERVED={{ matrix_bridge_postmoogle_mailboxes_reserved | join(' ') }} +POSTMOOGLE_MAILBOXES_ACTIVATION={{ matrix_bridge_postmoogle_mailboxes_activation }} -{{ matrix_postmoogle_environment_variables_extension }} +{{ matrix_bridge_postmoogle_environment_variables_extension }} diff --git a/roles/custom/matrix-bridge-postmoogle/templates/systemd/matrix-postmoogle.service.j2 b/roles/custom/matrix-bridge-postmoogle/templates/systemd/matrix-postmoogle.service.j2 index 9415382d1..15d1e086f 100644 --- a/roles/custom/matrix-bridge-postmoogle/templates/systemd/matrix-postmoogle.service.j2 +++ b/roles/custom/matrix-bridge-postmoogle/templates/systemd/matrix-postmoogle.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Postmoogle bridge -{% for service in matrix_postmoogle_systemd_required_services_list %} +{% for service in matrix_bridge_postmoogle_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_postmoogle_systemd_wanted_services_list %} +{% for service in matrix_bridge_postmoogle_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -23,24 +23,26 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ --read-only \ - --network={{ matrix_postmoogle_container_network }} \ - --env-file={{ matrix_postmoogle_config_path }}/env \ - -p {{ matrix_postmoogle_smtp_host_bind_port }}:{{ matrix_postmoogle_port }} \ - {% if matrix_postmoogle_ssl_path %} - -p {{ matrix_postmoogle_submission_host_bind_port }}:{{ matrix_postmoogle_tls_port }} \ + --network={{ matrix_bridge_postmoogle_container_network }} \ + --env-file={{ matrix_bridge_postmoogle_config_path }}/env \ + -p {{ matrix_bridge_postmoogle_smtp_host_bind_port }}:{{ matrix_bridge_postmoogle_port }} \ + {% if matrix_bridge_postmoogle_ssl_path %} + -p {{ matrix_bridge_postmoogle_submission_host_bind_port }}:{{ matrix_bridge_postmoogle_tls_port }} \ {% endif %} - --mount type=bind,src={{ matrix_postmoogle_data_path }},dst=/data \ - {% if matrix_postmoogle_ssl_path %} - --mount type=bind,src={{ matrix_postmoogle_ssl_path }},dst=/ssl \ + --mount type=bind,src={{ matrix_bridge_postmoogle_data_path }},dst=/data \ + {% if matrix_bridge_postmoogle_ssl_path %} + --mount type=bind,src={{ matrix_bridge_postmoogle_ssl_path }},dst=/ssl \ {% endif %} - {% for arg in matrix_postmoogle_container_extra_arguments %} + {% for arg in matrix_bridge_postmoogle_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_postmoogle_container_image }} + {{ matrix_bridge_postmoogle_container_image }} -{% for network in matrix_postmoogle_container_additional_networks %} +{% if matrix_bridge_postmoogle_container_network != 'host' %} +{% for network in matrix_bridge_postmoogle_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-postmoogle {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-postmoogle diff --git a/roles/custom/matrix-bridge-rustpush/defaults/main.yml b/roles/custom/matrix-bridge-rustpush/defaults/main.yml new file mode 100644 index 000000000..47fcbc1ec --- /dev/null +++ b/roles/custom/matrix-bridge-rustpush/defaults/main.yml @@ -0,0 +1,248 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Jason LaGuidice +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# matrix-bridge-rustpush is a Matrix <-> iMessage bridge using RustPush +# Project source code URL: https://github.com/jasonlaguidice/imessage + +matrix_bridge_rustpush_enabled: false + +matrix_bridge_rustpush_container_image_self_build: false +matrix_bridge_rustpush_container_image_self_build_repo: "https://github.com/jasonlaguidice/imessage.git" +matrix_bridge_rustpush_container_image_self_build_repo_version: "{{ 'master' if matrix_bridge_rustpush_version == 'latest' else matrix_bridge_rustpush_version }}" + +# renovate: datasource=docker depName=ghcr.io/jasonlaguidice/imessage +matrix_bridge_rustpush_version: v0.0.3 +matrix_bridge_rustpush_container_image: "{{ matrix_bridge_rustpush_container_image_registry_prefix }}jasonlaguidice/imessage:{{ matrix_bridge_rustpush_version }}" +matrix_bridge_rustpush_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_rustpush_container_image_self_build else matrix_bridge_rustpush_container_image_registry_prefix_upstream }}" +matrix_bridge_rustpush_container_image_registry_prefix_upstream: "{{ matrix_bridge_rustpush_container_image_registry_prefix_upstream_default }}" +matrix_bridge_rustpush_container_image_registry_prefix_upstream_default: "ghcr.io/" + +matrix_bridge_rustpush_base_path: "{{ matrix_base_data_path }}/matrix-rustpush-bridge" +matrix_bridge_rustpush_config_path: "{{ matrix_bridge_rustpush_base_path }}/config" +matrix_bridge_rustpush_data_path: "{{ matrix_bridge_rustpush_base_path }}/data" +matrix_bridge_rustpush_container_src_files_path: "{{ matrix_bridge_rustpush_base_path }}/docker-src" + +matrix_bridge_rustpush_homeserver_address: "" +# Whether asynchronous uploads via MSC2246 should be enabled for media. +matrix_bridge_rustpush_homeserver_async_media: false +matrix_bridge_rustpush_homeserver_domain: '{{ matrix_domain }}' +matrix_bridge_rustpush_appservice_address: 'http://matrix-rustpush-bridge:8081' + +matrix_bridge_rustpush_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_rustpush_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" + +# A public address that external services can use to reach this appservice. +matrix_bridge_rustpush_appservice_public_address: '' + +# Displayname template for iMessage contacts. +# Available variables: {{.FirstName}}, {{.LastName}}, {{.Nickname}}, +# {{.Phone}}, {{.Email}}, {{.ID}} +matrix_bridge_rustpush_network_displayname_template: "{% raw %}{{if .FirstName}}{{.FirstName}}{{if .LastName}} {{.LastName}}{{end}}{{else if .Nickname}}{{.Nickname}}{{else if .Phone}}{{.Phone}}{{else if .Email}}{{.Email}}{{else}}{{.ID}}{{end}} (iMessage){% endraw %}" + +matrix_bridge_rustpush_cloudkit_backfill: true +matrix_bridge_rustpush_video_transcoding: true +matrix_bridge_rustpush_heic_conversion: true +matrix_bridge_rustpush_disable_facetime: false +matrix_bridge_rustpush_statuskit_notifications: false +matrix_bridge_rustpush_statuskit_share_on_startup: true +# Only takes effect when `matrix_bridge_rustpush_statuskit_notifications` is true. +# - topic: sets the contact's DM room topic to their Focus/DND state (e.g. "🔕 Do Not Disturb"), clearing it when available. +# - notice: posts a silent m.notice instead (legacy behavior). +# Group chats always use `notice`, regardless of this setting. +matrix_bridge_rustpush_statuskit_notification_style: topic + +matrix_bridge_rustpush_bridge_command_prefix: "!im" + +matrix_bridge_rustpush_bridge_permissions: | + {{ + {matrix_bridge_rustpush_homeserver_domain: 'user'} + | combine({matrix_admin: 'admin'} if matrix_admin else {}) + }} + +matrix_bridge_rustpush_container_network: "" + +matrix_bridge_rustpush_container_additional_networks: "{{ matrix_bridge_rustpush_container_additional_networks_auto + matrix_bridge_rustpush_container_additional_networks_custom }}" +matrix_bridge_rustpush_container_additional_networks_auto: [] +matrix_bridge_rustpush_container_additional_networks_custom: [] + +# matrix_bridge_rustpush_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# See `../templates/labels.j2` for details. +# +# To inject your own other container labels, see `matrix_bridge_rustpush_container_labels_additional_labels`. +matrix_bridge_rustpush_container_labels_traefik_enabled: true +matrix_bridge_rustpush_container_labels_traefik_docker_network: "{{ matrix_bridge_rustpush_container_network }}" +matrix_bridge_rustpush_container_labels_traefik_entrypoints: web-secure +matrix_bridge_rustpush_container_labels_traefik_tls: "{{ matrix_bridge_rustpush_container_labels_traefik_entrypoints != 'web' }}" +matrix_bridge_rustpush_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Whether this bridge's HTTP API (including the provisioning API) is exposed at a +# public path via Traefik. Disabled by default. When enabled, requests to +# https:///... +# are forwarded to the bridge with that path prefix stripped. +matrix_bridge_rustpush_exposure_enabled: false +matrix_bridge_rustpush_exposure_hostname: '' +matrix_bridge_rustpush_exposure_path_prefix: '' + +matrix_bridge_rustpush_container_labels_exposure_enabled: "{{ matrix_bridge_rustpush_exposure_enabled }}" +matrix_bridge_rustpush_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_rustpush_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_rustpush_exposure_path_prefix }}`)" +matrix_bridge_rustpush_container_labels_exposure_traefik_priority: 0 +matrix_bridge_rustpush_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_rustpush_container_labels_traefik_entrypoints }}" +matrix_bridge_rustpush_container_labels_exposure_traefik_tls: "{{ matrix_bridge_rustpush_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_rustpush_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_rustpush_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_rustpush_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# See `../templates/labels.j2` for details. +# +# Example: +# matrix_bridge_rustpush_container_labels_additional_labels: | +# my.label=1 +# another.label="here" +matrix_bridge_rustpush_container_labels_additional_labels: '' + +# A list of extra arguments to pass to the container +matrix_bridge_rustpush_container_extra_arguments: [] + +# Override the Rust log filter passed to the bridge container via RUST_LOG. +# Leave empty to use the bridge's built-in default +# ("warn,rustpush=warn,rustpushgo=info,open_absinthe=info"). +# +# Useful values: +# "warn,rustpushgo=info,open_absinthe=debug" # NAC emulator diagnostics (_enc field sizes, etc.) +# "warn,rustpushgo=info,open_absinthe=debug,rustpush=info" # + upstream rustpush internals +# "debug" # everything (very chatty) +# +# The open_absinthe crate logs NAC hardware-key diagnostics at INFO and emulator +# state at DEBUG. These are suppressed by default to reduce log noise. +matrix_bridge_rustpush_rust_log: "" + +# List of systemd services that matrix-rustpush-bridge.service depends on. +matrix_bridge_rustpush_systemd_required_services_list: "{{ matrix_bridge_rustpush_systemd_required_services_list_default + matrix_bridge_rustpush_systemd_required_services_list_auto + matrix_bridge_rustpush_systemd_required_services_list_custom }}" +matrix_bridge_rustpush_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_rustpush_systemd_required_services_list_auto: [] +matrix_bridge_rustpush_systemd_required_services_list_custom: [] + +# List of systemd services that matrix-rustpush-bridge.service wants +matrix_bridge_rustpush_systemd_wanted_services_list: [] + +matrix_bridge_rustpush_appservice_token: '' +matrix_bridge_rustpush_homeserver_token: '' + +# Whether or not created rooms should have federation enabled. +# If false, created portal rooms will never be federated. +matrix_bridge_rustpush_matrix_federate_rooms: false + +# Database-related configuration fields. +# +# To use Postgres: +# - adjust your database credentials via the `matrix_bridge_rustpush_postgres_*` variables +matrix_bridge_rustpush_database_engine: 'postgres' + +matrix_bridge_rustpush_database_username: 'matrix_rustpush_bridge' +matrix_bridge_rustpush_database_password: 'some-password' +matrix_bridge_rustpush_database_hostname: '' +matrix_bridge_rustpush_database_port: 5432 +matrix_bridge_rustpush_database_name: 'matrix_rustpush_bridge' +matrix_bridge_rustpush_database_sslmode: disable + +matrix_bridge_rustpush_database_connection_string: 'postgres://{{ matrix_bridge_rustpush_database_username }}:{{ matrix_bridge_rustpush_database_password }}@{{ matrix_bridge_rustpush_database_hostname }}:{{ matrix_bridge_rustpush_database_port }}/{{ matrix_bridge_rustpush_database_name }}?sslmode={{ matrix_bridge_rustpush_database_sslmode }}' + +matrix_bridge_rustpush_database_uri: "{{ + { + 'postgres': matrix_bridge_rustpush_database_connection_string, + }[matrix_bridge_rustpush_database_engine] +}}" + +matrix_bridge_rustpush_double_puppet_secrets: "{{ matrix_bridge_rustpush_double_puppet_secrets_auto | combine(matrix_bridge_rustpush_double_puppet_secrets_custom) }}" +matrix_bridge_rustpush_double_puppet_secrets_auto: {} +matrix_bridge_rustpush_double_puppet_secrets_custom: {} + +matrix_bridge_rustpush_appservice_bot_username: rustpushbot +matrix_bridge_rustpush_appservice_bot_displayname: RustPush bridge bot +matrix_bridge_rustpush_appservice_bot_avatar: '' + +# Localpart template for MXIDs of remote (iMessage) users. +# The `{{.}}` placeholder expands to the iMessage handle (phone/email). +matrix_bridge_rustpush_appservice_username_template: "{% raw %}rustpush_{{.}}{% endraw %}" + +# Backfill is disabled by default because Linux Docker cannot access chat.db. +# On macOS with Full Disk Access, this can be set to true. +matrix_bridge_rustpush_backfill_enabled: false +# Maximum number of messages to backfill in empty rooms +matrix_bridge_rustpush_backfill_max_initial_messages: 50 + +# Maximum number of missed messages to backfill after bridge restarts +matrix_bridge_rustpush_backfill_max_catchup_messages: 500 + +# How many days back to look for chats during initial sync. +# Default in upstream is 365 (1 year). Set to 0 to disable. +matrix_bridge_rustpush_initial_sync_days: 365 + +# Shared secret for authentication of provisioning API requests. +# If set to "disable", the provisioning API will be disabled. +matrix_bridge_rustpush_provisioning_shared_secret: disable + +# Minimum severity of journal log messages. +# Valid values: fatal, error, warn, info, debug, trace +matrix_bridge_rustpush_logging_level: 'warn' + +# Default configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_bridge_rustpush_configuration_extension_yaml`) +# or completely replace this variable with your own template. +matrix_bridge_rustpush_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" + +matrix_bridge_rustpush_configuration_extension_yaml: | + # Your custom YAML configuration goes here. + # This configuration extends the default starting configuration (`matrix_bridge_rustpush_configuration_yaml`). + # + # You can override individual variables from the default configuration, or introduce new ones. + # + # If you need something more special, you can take full control by + # completely redefining `matrix_bridge_rustpush_configuration_yaml`. + +matrix_bridge_rustpush_configuration_extension: "{{ matrix_bridge_rustpush_configuration_extension_yaml | from_yaml if matrix_bridge_rustpush_configuration_extension_yaml | from_yaml is mapping else {} }}" + +# Holds the final configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_rustpush_configuration_yaml`. +matrix_bridge_rustpush_configuration: "{{ matrix_bridge_rustpush_configuration_yaml | from_yaml | combine(matrix_bridge_rustpush_configuration_extension, recursive=True) }}" + +matrix_bridge_rustpush_registration_yaml: | + id: rustpush-bridge + as_token: "{{ matrix_bridge_rustpush_appservice_token }}" + hs_token: "{{ matrix_bridge_rustpush_homeserver_token }}" + namespaces: + users: + - exclusive: true + regex: '^@rustpush_.+:{{ matrix_bridge_rustpush_homeserver_domain | regex_escape }}$' + - exclusive: true + regex: '^@{{ matrix_bridge_rustpush_appservice_bot_username | regex_escape }}:{{ matrix_bridge_rustpush_homeserver_domain | regex_escape }}$' + url: {{ matrix_bridge_rustpush_appservice_address }} + sender_localpart: _bot_{{ matrix_bridge_rustpush_appservice_bot_username }} + rate_limited: false + de.sorunome.msc2409.push_ephemeral: true + receive_ephemeral: true + io.element.msc4190: {{ matrix_bridge_rustpush_msc4190_enabled | to_json }} + +matrix_bridge_rustpush_registration: "{{ matrix_bridge_rustpush_registration_yaml | from_yaml }}" + +# Enable End-to-bridge encryption +matrix_bridge_rustpush_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_rustpush_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_rustpush_bridge_encryption_require: false +matrix_bridge_rustpush_bridge_encryption_appservice: false +matrix_bridge_rustpush_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_rustpush_bridge_encryption_allow }}" +matrix_bridge_rustpush_bridge_encryption_pickle_key: mautrix.bridge.e2ee + +# matrix_bridge_rustpush_restart_necessary controls whether the service +# will be restarted (when true) or merely started (when false) by the +# systemd service manager role (when conditional restart is enabled). +# +# This value is automatically computed during installation based on whether +# any configuration files, the systemd service file, or the container image changed. +# The default of `false` means "no restart needed" — appropriate when the role's +# installation tasks haven't run (e.g., due to --tags skipping them). +matrix_bridge_rustpush_restart_necessary: false diff --git a/roles/custom/matrix-bridge-rustpush/tasks/main.yml b/roles/custom/matrix-bridge-rustpush/tasks/main.yml new file mode 100644 index 000000000..46886a3cb --- /dev/null +++ b/roles/custom/matrix-bridge-rustpush/tasks/main.yml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Jason LaGuidice +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- tags: + - setup-all + - setup-rustpush-bridge + - install-all + - install-rustpush-bridge + block: + - when: matrix_bridge_rustpush_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" + + - when: matrix_bridge_rustpush_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" + +- tags: + - setup-all + - setup-rustpush-bridge + block: + - when: not matrix_bridge_rustpush_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-rustpush/tasks/setup_install.yml b/roles/custom/matrix-bridge-rustpush/tasks/setup_install.yml new file mode 100644 index 000000000..21e3302b4 --- /dev/null +++ b/roles/custom/matrix-bridge-rustpush/tasks/setup_install.yml @@ -0,0 +1,120 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Jason LaGuidice +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Ensure RustPush paths exist + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + mode: "0750" + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - {path: "{{ matrix_bridge_rustpush_base_path }}", when: true} + - {path: "{{ matrix_bridge_rustpush_config_path }}", when: true} + - {path: "{{ matrix_bridge_rustpush_data_path }}", when: true} + - {path: "{{ matrix_bridge_rustpush_container_src_files_path }}", when: "{{ matrix_bridge_rustpush_container_image_self_build }}"} + when: item.when | bool + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure RustPush repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_rustpush_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_rustpush_enabled | bool and matrix_bridge_rustpush_container_image_self_build" + +- name: Ensure RustPush repository is present on self-build + ansible.builtin.git: + repo: "{{ matrix_bridge_rustpush_container_image_self_build_repo }}" + version: "{{ matrix_bridge_rustpush_container_image_self_build_repo_version }}" + dest: "{{ matrix_bridge_rustpush_container_src_files_path }}" + force: "yes" + become: true + become_user: "{{ matrix_user_name }}" + register: matrix_bridge_rustpush_git_pull_results + when: "matrix_bridge_rustpush_enabled | bool and matrix_bridge_rustpush_container_image_self_build" + +- name: Ensure RustPush Docker image is built + community.docker.docker_image_build: + name: "{{ matrix_bridge_rustpush_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_rustpush_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_rustpush_git_pull_results.changed | bool else 'never' }}" + build_args: + BUILD_VERSION: "{{ matrix_bridge_rustpush_container_image_self_build_repo_version }}" + BUILD_COMMIT: "{{ matrix_bridge_rustpush_git_pull_results.after[:8] if matrix_bridge_rustpush_git_pull_results is defined and matrix_bridge_rustpush_git_pull_results.after is defined else 'unknown' }}" + register: matrix_bridge_rustpush_container_image_build_result + when: "matrix_bridge_rustpush_enabled | bool and matrix_bridge_rustpush_container_image_self_build | bool" + +- name: Ensure RustPush container image is pulled + community.docker.docker_image_pull: + name: "{{ matrix_bridge_rustpush_container_image }}" + pull: always + register: matrix_bridge_rustpush_container_image_pull_result + when: "matrix_bridge_rustpush_enabled | bool and not matrix_bridge_rustpush_container_image_self_build | bool" + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: matrix_bridge_rustpush_container_image_pull_result is not failed + ignore_errors: "{{ ansible_check_mode }}" + +- name: Ensure rustpush-bridge config.yaml installed + ansible.builtin.copy: + content: "{{ matrix_bridge_rustpush_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_rustpush_config_path }}/config.yaml" + mode: "0644" + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bridge_rustpush_config_result + +- name: Ensure rustpush-bridge registration.yaml installed + ansible.builtin.copy: + content: "{{ matrix_bridge_rustpush_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_rustpush_config_path }}/registration.yaml" + mode: "0644" + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_bridge_rustpush_registration_result + +- name: Ensure rustpush-bridge support files installed + ansible.builtin.template: + src: "{{ role_path }}/templates/{{ item }}.j2" + dest: "{{ matrix_bridge_rustpush_base_path }}/{{ item }}" + mode: "0640" + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - labels + register: matrix_bridge_rustpush_support_files_result + +- name: Ensure matrix-rustpush-bridge container network is created + community.general.docker_network: + enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" + name: "{{ matrix_bridge_rustpush_container_network }}" + driver: bridge + driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" + +- name: Ensure matrix-rustpush-bridge.service installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-rustpush-bridge.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-rustpush-bridge.service" + mode: "0644" + register: matrix_bridge_rustpush_systemd_service_result + +- name: Determine whether matrix-rustpush-bridge needs a restart + ansible.builtin.set_fact: + matrix_bridge_rustpush_restart_necessary: >- + {{ + matrix_bridge_rustpush_config_result.changed | default(false) + or matrix_bridge_rustpush_registration_result.changed | default(false) + or matrix_bridge_rustpush_support_files_result.changed | default(false) + or matrix_bridge_rustpush_systemd_service_result.changed | default(false) + or matrix_bridge_rustpush_container_image_pull_result.changed | default(false) + or matrix_bridge_rustpush_container_image_build_result.changed | default(false) + }} diff --git a/roles/custom/matrix-bridge-rustpush/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-rustpush/tasks/setup_uninstall.yml new file mode 100644 index 000000000..7b648950b --- /dev/null +++ b/roles/custom/matrix-bridge-rustpush/tasks/setup_uninstall.yml @@ -0,0 +1,24 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Jason LaGuidice +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Check existence of matrix-rustpush-bridge service + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-rustpush-bridge.service" + register: matrix_bridge_rustpush_service_stat + +- when: matrix_bridge_rustpush_service_stat.stat.exists | bool + block: + - name: Ensure matrix-rustpush-bridge is stopped + ansible.builtin.service: + name: matrix-rustpush-bridge + state: stopped + daemon_reload: true + + - name: Ensure matrix-rustpush-bridge.service doesn't exist + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-rustpush-bridge.service" + state: absent diff --git a/roles/custom/matrix-bridge-rustpush/tasks/validate_config.yml b/roles/custom/matrix-bridge-rustpush/tasks/validate_config.yml new file mode 100644 index 000000000..c74bc5884 --- /dev/null +++ b/roles/custom/matrix-bridge-rustpush/tasks/validate_config.yml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Jason LaGuidice +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: (Deprecation) Catch and report renamed settings + ansible.builtin.fail: + msg: >- + Your configuration contains a variable, which now has a different name. + Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_bridge_rustpush_metrics_enabled', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_metrics_proxying_enabled', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_metrics_proxying_hostname', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_metrics_proxying_path_prefix', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_container_labels_metrics_enabled', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_container_labels_metrics_traefik_rule', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_container_labels_metrics_traefik_priority', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_container_labels_metrics_traefik_entrypoints', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_container_labels_metrics_traefik_tls', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_container_labels_metrics_traefik_tls_certResolver', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (the rustpush bridge does not support metrics)'} + - {'old': 'matrix_bridge_rustpush_container_labels_metrics_middleware_basic_auth_users', 'new': ' (the rustpush bridge does not support metrics)'} + +- name: Fail if required RustPush settings not defined + ansible.builtin.fail: + msg: >- + You need to define a required configuration setting (`{{ item.name }}`). + when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" + with_items: + - {'name': 'matrix_bridge_rustpush_appservice_token', when: true} + - {'name': 'matrix_bridge_rustpush_homeserver_address', when: true} + - {'name': 'matrix_bridge_rustpush_homeserver_token', when: true} + - {'name': 'matrix_bridge_rustpush_database_hostname', when: "{{ matrix_bridge_rustpush_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_rustpush_container_network', when: true} diff --git a/roles/custom/matrix-bridge-rustpush/templates/config.yaml.j2 b/roles/custom/matrix-bridge-rustpush/templates/config.yaml.j2 new file mode 100644 index 000000000..45a7dc1e4 --- /dev/null +++ b/roles/custom/matrix-bridge-rustpush/templates/config.yaml.j2 @@ -0,0 +1,213 @@ +#jinja2: lstrip_blocks: True +# Network-specific config options (iMessage via RustPush) +network: + # Displayname template for iMessage contacts. + # Available variables: + # .FirstName, .LastName, .Nickname + # .Phone, .Email, .ID + displayname_template: {{ matrix_bridge_rustpush_network_displayname_template | to_json }} + + # How many days back to look for chats during initial sync. + # Default is 365 (1 year). Set to 0 to use the default. + initial_sync_days: {{ matrix_bridge_rustpush_initial_sync_days | to_json }} + + # Set to false to disable CloudKit backfill globally + cloudkit_backfill: {{ matrix_bridge_rustpush_cloudkit_backfill | to_json }} + backfill_source: cloudkit + + # Enable or disable video transcoding + video_transcoding: {{ matrix_bridge_rustpush_video_transcoding | to_json }} + + # Enable or disable HEIC conversion + heic_conversion: {{ matrix_bridge_rustpush_heic_conversion | to_json }} + heic_jpeg_quality: 95 + + # Set to true to disable Facetime support globally + disable_facetime: {{ matrix_bridge_rustpush_disable_facetime | to_json }} + + # Set to false to disable Statuskit support globally + statuskit_notifications: {{ matrix_bridge_rustpush_statuskit_notifications | to_json }} + statuskit_share_on_startup: {{ matrix_bridge_rustpush_statuskit_share_on_startup | to_json }} + # How to surface a contact's Focus/DND status. Only takes effect when statuskit_notifications is true. + # - topic: set the DM room topic to the contact's Focus/DND state, clearing it when available. + # - notice: post a silent m.notice instead (legacy behavior). Group chats always use notice. + statuskit_notification_style: {{ matrix_bridge_rustpush_statuskit_notification_style | to_json }} + +# Config options that affect the central bridge module. +bridge: + # The prefix for commands. Only required in non-management rooms. + command_prefix: {{ matrix_bridge_rustpush_bridge_command_prefix | to_json }} + # Should the bridge create a space for each login containing the rooms that account is in? + personal_filtering_spaces: true + # Whether the bridge should set names and avatars explicitly for DM portals. + private_chat_portal_meta: true + # Should events be handled asynchronously within portal rooms? + async_events: false + # Should every user have their own portals rather than sharing them? + split_portals: false + # Should the bridge resend `m.bridge` events to all portals on startup? + resend_bridge_info: false + + # Should leaving Matrix rooms be bridged as leaving groups on the remote network? + bridge_matrix_leave: false + # Should room tags only be synced when creating the portal? + tag_only_on_create: true + # List of tags to allow bridging. + only_bridge_tags: [m.favourite, m.lowpriority] + # Should room mute status only be synced when creating the portal? + mute_only_on_create: true + + # What should be done to portal rooms when a user logs out or is logged out? + cleanup_on_logout: + enabled: false + manual: + private: nothing + relayed: nothing + shared_no_users: nothing + shared_has_users: nothing + bad_credentials: + private: nothing + relayed: nothing + shared_no_users: nothing + shared_has_users: nothing + + # Settings for relay mode + relay: + enabled: false + admin_only: true + default_relays: [] + message_formats: + m.text: "{% raw %}{{ .Sender.DisambiguatedName }}: {{ .Message }}{% endraw %}" + m.notice: "{% raw %}{{ .Sender.DisambiguatedName }}: {{ .Message }}{% endraw %}" + m.emote: "{% raw %}* {{ .Sender.DisambiguatedName }} {{ .Message }}{% endraw %}" + m.file: "{% raw %}{{ .Sender.DisambiguatedName }} sent a file{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.image: "{% raw %}{{ .Sender.DisambiguatedName }} sent an image{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.audio: "{% raw %}{{ .Sender.DisambiguatedName }} sent an audio file{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.video: "{% raw %}{{ .Sender.DisambiguatedName }} sent a video{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + m.location: "{% raw %}{{ .Sender.DisambiguatedName }} sent a location{{ if .Caption }}: {{ .Caption }}{{ end }}{% endraw %}" + displayname_format: "{% raw %}{{ .DisambiguatedName }}{% endraw %}" + + # Permissions for using the bridge. + permissions: {{ matrix_bridge_rustpush_bridge_permissions | to_json }} + +# Config for the bridge's database. +database: + type: postgres + uri: {{ matrix_bridge_rustpush_database_uri | to_json }} + max_open_conns: 5 + max_idle_conns: 1 + max_conn_idle_time: null + max_conn_lifetime: null + +# Homeserver details. +homeserver: + address: {{ matrix_bridge_rustpush_homeserver_address | to_json }} + domain: {{ matrix_bridge_rustpush_homeserver_domain | to_json }} + software: standard + status_endpoint: + message_send_checkpoint_endpoint: + async_media: {{ matrix_bridge_rustpush_homeserver_async_media | to_json }} + websocket: false + ping_interval_seconds: 0 + +# Application service host/registration related details. +appservice: + address: {{ matrix_bridge_rustpush_appservice_address | to_json }} + public_address: {{ matrix_bridge_rustpush_appservice_public_address | to_json }} + + hostname: 0.0.0.0 + port: 8081 + + id: rustpush-bridge + bot: + username: {{ matrix_bridge_rustpush_appservice_bot_username | to_json }} + displayname: {{ matrix_bridge_rustpush_appservice_bot_displayname | to_json(ensure_ascii=False) }} + avatar: {{ matrix_bridge_rustpush_appservice_bot_avatar | to_json }} + + ephemeral_events: true + async_transactions: false + + as_token: {{ matrix_bridge_rustpush_appservice_token | to_json }} + hs_token: {{ matrix_bridge_rustpush_homeserver_token | to_json }} + + # Localpart template of MXIDs for remote users. + username_template: {{ matrix_bridge_rustpush_appservice_username_template | to_json }} + +# Config options that affect the Matrix connector of the bridge. +matrix: + message_status_events: false + delivery_receipts: false + message_error_notices: true + sync_direct_chat_list: true + federate_rooms: {{ matrix_bridge_rustpush_matrix_federate_rooms | to_json }} + upload_file_threshold: 5242880 + +# Segment-compatible analytics endpoint for tracking some events. +analytics: + token: null + url: https://api.segment.io/v1/track + user_id: null + +# Settings for provisioning API +provisioning: + prefix: /_matrix/provision + shared_secret: {{ matrix_bridge_rustpush_provisioning_shared_secret | to_json }} + allow_matrix_auth: true + debug_endpoints: false + +# Settings for backfilling messages. +backfill: + enabled: {{ matrix_bridge_rustpush_backfill_enabled | to_json }} + max_initial_messages: {{ matrix_bridge_rustpush_backfill_max_initial_messages | to_json }} + max_catchup_messages: {{ matrix_bridge_rustpush_backfill_max_catchup_messages | to_json }} + unread_hours_threshold: 720 + threads: + max_initial_messages: 50 + queue: + enabled: false + batch_size: 100 + batch_delay: 20 + max_batches: -1 + max_batches_override: {} + +# Settings for enabling double puppeting +double_puppet: + servers: {} + allow_discovery: false + secrets: {{ matrix_bridge_rustpush_double_puppet_secrets | to_json }} + +# End-to-bridge encryption support options. +encryption: + allow: {{ matrix_bridge_rustpush_bridge_encryption_allow | to_json }} + default: {{ matrix_bridge_rustpush_bridge_encryption_default | to_json }} + require: {{ matrix_bridge_rustpush_bridge_encryption_require | to_json }} + appservice: {{ matrix_bridge_rustpush_bridge_encryption_appservice | to_json }} + msc4190: {{ matrix_bridge_rustpush_msc4190_enabled | to_json }} + self_sign: {{ matrix_bridge_rustpush_self_sign_enabled | to_json }} + allow_key_sharing: {{ matrix_bridge_rustpush_bridge_encryption_key_sharing_allow | to_json }} + pickle_key: {{ matrix_bridge_rustpush_bridge_encryption_pickle_key | to_json }} + delete_keys: + delete_outbound_on_ack: false + dont_store_outbound: false + ratchet_on_decrypt: false + delete_fully_used_on_decrypt: false + delete_prev_on_new_session: false + delete_on_device_delete: false + periodically_delete_expired: false + delete_outdated_inbound: false + verification_levels: + receive: unverified + send: unverified + share: cross-signed-tofu + rotation: + enable_custom: false + milliseconds: 604800000 + messages: 100 + disable_device_change_key_rotation: false + +# Logging config. +logging: + min_level: {{ matrix_bridge_rustpush_logging_level | to_json }} + writers: + - type: stdout + format: pretty-colored diff --git a/roles/custom/matrix-bridge-rustpush/templates/config.yaml.j2.license b/roles/custom/matrix-bridge-rustpush/templates/config.yaml.j2.license new file mode 100644 index 000000000..ff5b39cd7 --- /dev/null +++ b/roles/custom/matrix-bridge-rustpush/templates/config.yaml.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Jason LaGuidice + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-rustpush/templates/labels.j2 b/roles/custom/matrix-bridge-rustpush/templates/labels.j2 new file mode 100644 index 000000000..aea18358f --- /dev/null +++ b/roles/custom/matrix-bridge-rustpush/templates/labels.j2 @@ -0,0 +1,51 @@ +{# +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Jason LaGuidice + +SPDX-License-Identifier: AGPL-3.0-or-later +#} + +{% if matrix_bridge_rustpush_container_labels_traefik_enabled %} +traefik.enable=true + +{% if matrix_bridge_rustpush_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_rustpush_container_labels_traefik_docker_network }} +{% endif %} + +traefik.http.services.matrix-rustpush-bridge.loadbalancer.server.port=8081 + +{% if matrix_bridge_rustpush_container_labels_exposure_enabled %} +############################################################ +# # +# Bridge API exposure # +# # +############################################################ + +traefik.http.middlewares.matrix-rustpush-bridge-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_rustpush_exposure_path_prefix }} +traefik.http.routers.matrix-rustpush-bridge-exposure.middlewares=matrix-rustpush-bridge-exposure-strip-prefix + +traefik.http.routers.matrix-rustpush-bridge-exposure.rule={{ matrix_bridge_rustpush_container_labels_exposure_traefik_rule }} + +{% if matrix_bridge_rustpush_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-rustpush-bridge-exposure.priority={{ matrix_bridge_rustpush_container_labels_exposure_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-rustpush-bridge-exposure.service=matrix-rustpush-bridge +traefik.http.routers.matrix-rustpush-bridge-exposure.entrypoints={{ matrix_bridge_rustpush_container_labels_exposure_traefik_entrypoints }} + +traefik.http.routers.matrix-rustpush-bridge-exposure.tls={{ matrix_bridge_rustpush_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_rustpush_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-rustpush-bridge-exposure.tls.certResolver={{ matrix_bridge_rustpush_container_labels_exposure_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Bridge API exposure # +# # +############################################################ +{% endif %} + + +{% endif %} + +{{ matrix_bridge_rustpush_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-rustpush/templates/labels.j2.license b/roles/custom/matrix-bridge-rustpush/templates/labels.j2.license new file mode 100644 index 000000000..ff5b39cd7 --- /dev/null +++ b/roles/custom/matrix-bridge-rustpush/templates/labels.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Jason LaGuidice + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bot-go-neb/templates/systemd/matrix-bot-go-neb.service.j2 b/roles/custom/matrix-bridge-rustpush/templates/systemd/matrix-rustpush-bridge.service.j2 similarity index 51% rename from roles/custom/matrix-bot-go-neb/templates/systemd/matrix-bot-go-neb.service.j2 rename to roles/custom/matrix-bridge-rustpush/templates/systemd/matrix-rustpush-bridge.service.j2 index d27909e4b..00593b665 100644 --- a/roles/custom/matrix-bot-go-neb/templates/systemd/matrix-bot-go-neb.service.j2 +++ b/roles/custom/matrix-bridge-rustpush/templates/systemd/matrix-rustpush-bridge.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] -Description=Matrix Go-NEB bot -{% for service in matrix_bot_go_neb_systemd_required_services_list %} +Description=Matrix RustPush bridge +{% for service in matrix_bridge_rustpush_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_bot_go_neb_systemd_wanted_services_list %} +{% for service in matrix_bridge_rustpush_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -13,43 +13,39 @@ DefaultDependencies=no [Service] Type=simple Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-bot-go-neb 2>/dev/null || true' -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-bot-go-neb 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-rustpush-bridge 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-rustpush-bridge 2>/dev/null || true' ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --rm \ - --name=matrix-bot-go-neb \ + --name=matrix-rustpush-bridge \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --read-only \ - --network={{ matrix_bot_go_neb_container_network }} \ - {% if matrix_bot_go_neb_container_http_host_bind_port %} - -p {{ matrix_bot_go_neb_container_http_host_bind_port }}:4050 \ - {% endif %} - --env-file={{ matrix_bot_go_neb_base_path }}/env \ - --label-file={{ matrix_bot_go_neb_base_path }}/labels \ - --mount type=bind,src={{ matrix_bot_go_neb_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_bot_go_neb_data_path }},dst=/data \ - --entrypoint=/bin/sh \ - {% for arg in matrix_bot_go_neb_container_extra_arguments %} + --network={{ matrix_bridge_rustpush_container_network }} \ + --env HOME=/data \ +{% if matrix_bridge_rustpush_rust_log %} --env RUST_LOG={{ matrix_bridge_rustpush_rust_log }} \ +{% endif %} --mount type=bind,src={{ matrix_bridge_rustpush_config_path }},dst=/config \ + --mount type=bind,src={{ matrix_bridge_rustpush_data_path }},dst=/data \ + --label-file={{ matrix_bridge_rustpush_base_path }}/labels \ + --entrypoint /usr/local/bin/matrix-rustpush \ + {% for arg in matrix_bridge_rustpush_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_bot_go_neb_container_image }} \ - -c "go-neb /config/config.yaml" + {{ matrix_bridge_rustpush_container_image }} \ + -c /config/config.yaml -r /config/registration.yaml -{% for network in matrix_bot_go_neb_container_additional_networks %} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-go-neb +{% for network in matrix_bridge_rustpush_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-rustpush-bridge {% endfor %} -ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-go-neb - -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-bot-go-neb 2>/dev/null || true' -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-bot-go-neb 2>/dev/null || true' +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-rustpush-bridge +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-rustpush-bridge 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-rustpush-bridge 2>/dev/null || true' Restart=always RestartSec=30 -SyslogIdentifier=matrix-bot-go-neb +SyslogIdentifier=matrix-rustpush-bridge [Install] WantedBy=multi-user.target diff --git a/roles/custom/matrix-bridge-rustpush/templates/systemd/matrix-rustpush-bridge.service.j2.license b/roles/custom/matrix-bridge-rustpush/templates/systemd/matrix-rustpush-bridge.service.j2.license new file mode 100644 index 000000000..ff5b39cd7 --- /dev/null +++ b/roles/custom/matrix-bridge-rustpush/templates/systemd/matrix-rustpush-bridge.service.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2026 MDAD project contributors +SPDX-FileCopyrightText: 2026 Jason LaGuidice + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-bridge-sms/defaults/main.yml b/roles/custom/matrix-bridge-sms/defaults/main.yml index de160e78a..d2f6127c9 100644 --- a/roles/custom/matrix-bridge-sms/defaults/main.yml +++ b/roles/custom/matrix-bridge-sms/defaults/main.yml @@ -12,61 +12,61 @@ # matrix-sms-bridge is a Matrix <-> SMS bridge # Project source code URL: https://github.com/benkuly/matrix-sms-bridge -matrix_sms_bridge_enabled: true +matrix_bridge_sms_enabled: true # renovate: datasource=docker depName=folivonet/matrix-sms-bridge -matrix_sms_bridge_version: 0.5.13 -matrix_sms_bridge_container_image: "{{ matrix_sms_bridge_container_image_registry_prefix }}folivonet/matrix-sms-bridge:{{ matrix_sms_bridge_container_image_tag }}" -matrix_sms_bridge_container_image_registry_prefix: "{{ matrix_sms_bridge_container_image_registry_prefix_upstream }}" -matrix_sms_bridge_container_image_registry_prefix_upstream: "{{ matrix_sms_bridge_container_image_registry_prefix_upstream_default }}" -matrix_sms_bridge_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_sms_bridge_container_image_tag: "{{ matrix_sms_bridge_version }}" +matrix_bridge_sms_version: 0.5.13 +matrix_bridge_sms_container_image: "{{ matrix_bridge_sms_container_image_registry_prefix }}folivonet/matrix-sms-bridge:{{ matrix_bridge_sms_container_image_tag }}" +matrix_bridge_sms_container_image_registry_prefix: "{{ matrix_bridge_sms_container_image_registry_prefix_upstream }}" +matrix_bridge_sms_container_image_registry_prefix_upstream: "{{ matrix_bridge_sms_container_image_registry_prefix_upstream_default }}" +matrix_bridge_sms_container_image_registry_prefix_upstream_default: "docker.io/" +matrix_bridge_sms_container_image_tag: "{{ matrix_bridge_sms_version }}" -matrix_sms_bridge_base_path: "{{ matrix_base_data_path }}/matrix-sms-bridge" -matrix_sms_bridge_config_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/config" -matrix_sms_bridge_data_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/data" +matrix_bridge_sms_base_path: "{{ matrix_base_data_path }}/matrix-sms-bridge" +matrix_bridge_sms_config_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/config" +matrix_bridge_sms_data_path: "{{ matrix_base_data_path }}/matrix-sms-bridge/data" -matrix_sms_bridge_appservice_token: '' -matrix_sms_bridge_homeserver_token: '' +matrix_bridge_sms_appservice_token: '' +matrix_bridge_sms_homeserver_token: '' -matrix_sms_bridge_container_http_host_bind_port: '' +matrix_bridge_sms_container_http_host_bind_port: '' -matrix_sms_bridge_container_network: "" +matrix_bridge_sms_container_network: "" -matrix_sms_bridge_container_additional_networks: "{{ matrix_sms_bridge_container_additional_networks_auto + matrix_sms_bridge_container_additional_networks_custom }}" -matrix_sms_bridge_container_additional_networks_auto: [] -matrix_sms_bridge_container_additional_networks_custom: [] +matrix_bridge_sms_container_additional_networks: "{{ matrix_bridge_sms_container_additional_networks_auto + matrix_bridge_sms_container_additional_networks_custom }}" +matrix_bridge_sms_container_additional_networks_auto: [] +matrix_bridge_sms_container_additional_networks_custom: [] # A list of extra arguments to pass to the container -matrix_sms_bridge_container_extra_arguments: [] +matrix_bridge_sms_container_extra_arguments: [] # List of systemd services that service depends on. -matrix_sms_bridge_systemd_required_services_list: "{{ matrix_sms_bridge_systemd_required_services_list_default + matrix_sms_bridge_systemd_required_services_list_auto + matrix_sms_bridge_systemd_required_services_list_custom }}" -matrix_sms_bridge_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_sms_bridge_systemd_required_services_list_auto: [] -matrix_sms_bridge_systemd_required_services_list_custom: [] +matrix_bridge_sms_systemd_required_services_list: "{{ matrix_bridge_sms_systemd_required_services_list_default + matrix_bridge_sms_systemd_required_services_list_auto + matrix_bridge_sms_systemd_required_services_list_custom }}" +matrix_bridge_sms_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_sms_systemd_required_services_list_auto: [] +matrix_bridge_sms_systemd_required_services_list_custom: [] # List of systemd services that service wants -matrix_sms_bridge_systemd_wanted_services_list: [] +matrix_bridge_sms_systemd_wanted_services_list: [] -matrix_sms_bridge_appservice_url: 'http://matrix-sms-bridge:8080' -matrix_sms_bridge_homeserver_hostname: '' -matrix_sms_bridge_homeserver_port: "" +matrix_bridge_sms_appservice_url: 'http://matrix-sms-bridge:8080' +matrix_bridge_sms_homeserver_hostname: '' +matrix_bridge_sms_homeserver_port: "" -matrix_sms_bridge_homserver_domain: "{{ matrix_domain }}" -matrix_sms_bridge_default_room: '' -matrix_sms_bridge_default_region: '' -matrix_sms_bridge_default_timezone: '' -matrix_sms_bridge_single_mode_enabled: false +matrix_bridge_sms_homserver_domain: "{{ matrix_domain }}" +matrix_bridge_sms_default_room: '' +matrix_bridge_sms_default_region: '' +matrix_bridge_sms_default_timezone: '' +matrix_bridge_sms_single_mode_enabled: false -matrix_sms_bridge_provider_android_baseurl: '' -matrix_sms_bridge_provider_android_username: '' -matrix_sms_bridge_provider_android_password: '' -matrix_sms_bridge_provider_android_truststore_local_path: '' -matrix_sms_bridge_provider_android_truststore_password: '' +matrix_bridge_sms_provider_android_baseurl: '' +matrix_bridge_sms_provider_android_username: '' +matrix_bridge_sms_provider_android_password: '' +matrix_bridge_sms_provider_android_truststore_local_path: '' +matrix_bridge_sms_provider_android_truststore_password: '' -matrix_sms_bridge_configuration_yaml: | +matrix_bridge_sms_configuration_yaml: | #jinja2: lstrip_blocks: True # Database connection @@ -75,30 +75,30 @@ matrix_sms_bridge_configuration_yaml: | sms: # (optional) SMS messages without a valid token a routed to this room. # Note that you must invite @smsbot:yourHomeServer to this room. - defaultRoomId: "{{ matrix_sms_bridge_default_room }}" - defaultRegion: "{{ matrix_sms_bridge_default_region }}" - defaultTimeZone: "{{ matrix_sms_bridge_default_timezone }}" - singleModeEnabled: "{{ matrix_sms_bridge_single_mode_enabled }}" + defaultRoomId: "{{ matrix_bridge_sms_default_room }}" + defaultRegion: "{{ matrix_bridge_sms_default_region }}" + defaultTimeZone: "{{ matrix_bridge_sms_default_timezone }}" + singleModeEnabled: "{{ matrix_bridge_sms_single_mode_enabled }}" provider: android: # (optional) default is disabled enabled: true # The url to the android-sms-gateway-server - baseUrl: {{ matrix_sms_bridge_provider_android_baseurl }} + baseUrl: {{ matrix_bridge_sms_provider_android_baseurl }} # The username of the gateway - username: {{ matrix_sms_bridge_provider_android_username }} + username: {{ matrix_bridge_sms_provider_android_username }} # The password of the gateway - password: {{ matrix_sms_bridge_provider_android_password }} + password: {{ matrix_bridge_sms_provider_android_password }} # (optional) if you use a self signed certificate, you can add the public key here - {% if matrix_sms_bridge_provider_android_truststore_local_path %} + {% if matrix_bridge_sms_provider_android_truststore_local_path %} trustStore: path: /config/matrix-sms-gateway-server.p12 - password: {{ matrix_sms_bridge_provider_android_truststore_password }} + password: {{ matrix_bridge_sms_provider_android_truststore_password }} type: PKCS12 {% endif %} bot: # The domain-part of matrix-ids. E. g. example.org when your userIds look like @unicorn:example.org - serverName: {{ matrix_sms_bridge_homserver_domain }} + serverName: {{ matrix_bridge_sms_homserver_domain }} migration: url: "jdbc:h2:file:/data/database/db" username: sa @@ -108,48 +108,48 @@ matrix_sms_bridge_configuration_yaml: | client: homeServer: # The hostname of your Homeserver. - hostname: {{ matrix_sms_bridge_homeserver_hostname }} + hostname: {{ matrix_bridge_sms_homeserver_hostname }} # (optional) The port of your Homeserver. Default is 443. - port: {{ matrix_sms_bridge_homeserver_port }} + port: {{ matrix_bridge_sms_homeserver_port }} # (optional) Use http or https. Default is true (so uses https). secure: false # The token to authenticate against the Homeserver. - token: {{ matrix_sms_bridge_appservice_token }} + token: {{ matrix_bridge_sms_appservice_token }} appservice: # A unique token for Homeservers to use to authenticate requests to this application service. - hsToken: {{ matrix_sms_bridge_homeserver_token }} + hsToken: {{ matrix_bridge_sms_homeserver_token }} -matrix_sms_bridge_configuration_extension_yaml: | +matrix_bridge_sms_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_sms_bridge_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_sms_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_sms_bridge_configuration_yaml`. + # completely redefining `matrix_bridge_sms_configuration_yaml`. -matrix_sms_bridge_configuration_extension: "{{ matrix_sms_bridge_configuration_extension_yaml | from_yaml if matrix_sms_bridge_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_sms_configuration_extension: "{{ matrix_bridge_sms_configuration_extension_yaml | from_yaml if matrix_bridge_sms_configuration_extension_yaml | from_yaml is mapping else {} }}" -matrix_sms_bridge_configuration: "{{ matrix_sms_bridge_configuration_yaml | from_yaml | combine(matrix_sms_bridge_configuration_extension, recursive=True) }}" +matrix_bridge_sms_configuration: "{{ matrix_bridge_sms_configuration_yaml | from_yaml | combine(matrix_bridge_sms_configuration_extension, recursive=True) }}" -matrix_sms_bridge_registration_yaml: | +matrix_bridge_sms_registration_yaml: | id: sms - as_token: "{{ matrix_sms_bridge_appservice_token }}" - hs_token: "{{ matrix_sms_bridge_homeserver_token }}" + as_token: "{{ matrix_bridge_sms_appservice_token }}" + hs_token: "{{ matrix_bridge_sms_homeserver_token }}" namespaces: users: - exclusive: true - regex: '^@sms_.+:{{ matrix_sms_bridge_homserver_domain | regex_escape }}$' + regex: '^@sms_.+:{{ matrix_bridge_sms_homserver_domain | regex_escape }}$' aliases: - exclusive: true - regex: '^#sms_.+:{{ matrix_sms_bridge_homserver_domain | regex_escape }}$' - url: {{ matrix_sms_bridge_appservice_url }} + regex: '^#sms_.+:{{ matrix_bridge_sms_homserver_domain | regex_escape }}$' + url: {{ matrix_bridge_sms_appservice_url }} sender_localpart: smsbot rate_limited: false -matrix_sms_bridge_registration: "{{ matrix_sms_bridge_registration_yaml | from_yaml }}" +matrix_bridge_sms_registration: "{{ matrix_bridge_sms_registration_yaml | from_yaml }}" -# matrix_sms_bridge_restart_necessary controls whether the service +# matrix_bridge_sms_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -157,4 +157,4 @@ matrix_sms_bridge_registration: "{{ matrix_sms_bridge_registration_yaml | from_y # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_sms_bridge_restart_necessary: false +matrix_bridge_sms_restart_necessary: false diff --git a/roles/custom/matrix-bridge-sms/tasks/main.yml b/roles/custom/matrix-bridge-sms/tasks/main.yml index 574dba74b..3bb04af7e 100644 --- a/roles/custom/matrix-bridge-sms/tasks/main.yml +++ b/roles/custom/matrix-bridge-sms/tasks/main.yml @@ -12,15 +12,15 @@ - install-all - install-matrix-sms-bridge block: - - when: matrix_sms_bridge_enabled | bool + - when: matrix_bridge_sms_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_sms_bridge_enabled | bool + - when: matrix_bridge_sms_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-matrix-sms-bridge block: - - when: not matrix_sms_bridge_enabled | bool + - when: not matrix_bridge_sms_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-sms/tasks/setup_install.yml b/roles/custom/matrix-bridge-sms/tasks/setup_install.yml index 022bc22d9..ee5b6af28 100644 --- a/roles/custom/matrix-bridge-sms/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-sms/tasks/setup_install.yml @@ -11,13 +11,13 @@ --- - name: Ensure matrix-sms-bridge image is pulled - community.docker.docker_image: - name: "{{ matrix_sms_bridge_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - register: matrix_sms_bridge_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_sms_container_image }}" + pull: always + register: matrix_bridge_sms_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_sms_bridge_container_image_pull_result is not failed + until: matrix_bridge_sms_container_image_pull_result is not failed - name: Ensure matrix-sms-bridge paths exist ansible.builtin.file: @@ -27,42 +27,43 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - "{{ matrix_sms_bridge_base_path }}" - - "{{ matrix_sms_bridge_config_path }}" - - "{{ matrix_sms_bridge_data_path }}" + - "{{ matrix_bridge_sms_base_path }}" + - "{{ matrix_bridge_sms_config_path }}" + - "{{ matrix_bridge_sms_data_path }}" - name: Ensure matrix-sms-bridge application.yml installed ansible.builtin.copy: - content: "{{ matrix_sms_bridge_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_sms_bridge_config_path }}/application.yml" + content: "{{ matrix_bridge_sms_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_sms_config_path }}/application.yml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_sms_bridge_config_result + register: matrix_bridge_sms_config_result - name: Ensure matrix-sms-bridge registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_sms_bridge_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_sms_bridge_config_path }}/registration.yaml" + content: "{{ matrix_bridge_sms_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_sms_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_sms_bridge_registration_result + register: matrix_bridge_sms_registration_result - name: Ensure android-sms-gateway-server cert installed ansible.builtin.copy: - src: "{{ matrix_sms_bridge_provider_android_truststore_local_path }}" - dest: "{{ matrix_sms_bridge_config_path }}/matrix-sms-gateway-server.p12" + src: "{{ matrix_bridge_sms_provider_android_truststore_local_path }}" + dest: "{{ matrix_bridge_sms_config_path }}/matrix-sms-gateway-server.p12" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - when: matrix_sms_bridge_provider_android_truststore_local_path != "" - register: matrix_sms_bridge_cert_result + when: matrix_bridge_sms_provider_android_truststore_local_path != "" + register: matrix_bridge_sms_cert_result - name: Ensure matrix-sms-bridge container network is created + when: matrix_bridge_sms_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_sms_bridge_container_network }}" + name: "{{ matrix_bridge_sms_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -71,15 +72,15 @@ src: "{{ role_path }}/templates/systemd/matrix-sms-bridge.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-sms-bridge.service" mode: '0644' - register: matrix_sms_bridge_systemd_service_result + register: matrix_bridge_sms_systemd_service_result - name: Determine whether matrix-sms-bridge needs a restart ansible.builtin.set_fact: - matrix_sms_bridge_restart_necessary: >- + matrix_bridge_sms_restart_necessary: >- {{ - matrix_sms_bridge_config_result.changed | default(false) - or matrix_sms_bridge_registration_result.changed | default(false) - or matrix_sms_bridge_cert_result.changed | default(false) - or matrix_sms_bridge_systemd_service_result.changed | default(false) - or matrix_sms_bridge_container_image_pull_result.changed | default(false) + matrix_bridge_sms_config_result.changed | default(false) + or matrix_bridge_sms_registration_result.changed | default(false) + or matrix_bridge_sms_cert_result.changed | default(false) + or matrix_bridge_sms_systemd_service_result.changed | default(false) + or matrix_bridge_sms_container_image_pull_result.changed | default(false) }} diff --git a/roles/custom/matrix-bridge-sms/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-sms/tasks/setup_uninstall.yml index f6e1e2a6e..c16eb5d6b 100644 --- a/roles/custom/matrix-bridge-sms/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-sms/tasks/setup_uninstall.yml @@ -9,7 +9,7 @@ - name: Check existence of matrix-sms-bridge service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-sms-bridge.service" - register: matrix_sms_bridge_service_stat + register: matrix_bridge_sms_service_stat - name: Ensure matrix-sms-bridge is stopped ansible.builtin.service: @@ -17,10 +17,10 @@ state: stopped enabled: false daemon_reload: true - when: "matrix_sms_bridge_service_stat.stat.exists" + when: "matrix_bridge_sms_service_stat.stat.exists" - name: Ensure matrix-sms-bridge.service doesn't exist ansible.builtin.file: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-sms-bridge.service" state: absent - when: "matrix_sms_bridge_service_stat.stat.exists" + when: "matrix_bridge_sms_service_stat.stat.exists" diff --git a/roles/custom/matrix-bridge-sms/tasks/validate_config.yml b/roles/custom/matrix-bridge-sms/tasks/validate_config.yml index 44960b820..0cac7dc72 100644 --- a/roles/custom/matrix-bridge-sms/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-sms/tasks/validate_config.yml @@ -14,11 +14,12 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_sms_bridge_docker_image', 'new': 'matrix_sms_bridge_container_image'} - - {'old': 'matrix_sms_bridge_docker_image_registry_prefix', 'new': 'matrix_sms_bridge_container_image_registry_prefix'} - - {'old': 'matrix_sms_bridge_docker_image_registry_prefix_upstream', 'new': 'matrix_sms_bridge_container_image_registry_prefix_upstream'} - - {'old': 'matrix_sms_bridge_docker_image_registry_prefix_upstream_default', 'new': 'matrix_sms_bridge_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_sms_bridge_docker_image_tag', 'new': 'matrix_sms_bridge_container_image_tag'} + - {'old': 'matrix_bridge_sms_docker_image', 'new': 'matrix_bridge_sms_container_image'} + - {'old': 'matrix_bridge_sms_docker_image_registry_prefix', 'new': 'matrix_bridge_sms_container_image_registry_prefix'} + - {'old': 'matrix_bridge_sms_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_sms_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_sms_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_sms_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_sms_docker_image_tag', 'new': 'matrix_bridge_sms_container_image_tag'} + - {'old': 'matrix_bridge_sms_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required matrix-bridge-sms settings not defined @@ -27,13 +28,13 @@ You need to define a required configuration setting (`{{ item }}`). when: "lookup('vars', item, default='') == ''" with_items: - - "matrix_sms_bridge_appservice_token" - - "matrix_sms_bridge_homeserver_hostname" - - "matrix_sms_bridge_homeserver_port" - - "matrix_sms_bridge_homeserver_token" - - "matrix_sms_bridge_default_region" - - "matrix_sms_bridge_default_timezone" - - "matrix_sms_bridge_provider_android_baseurl" - - "matrix_sms_bridge_provider_android_username" - - "matrix_sms_bridge_provider_android_password" - - "matrix_sms_bridge_container_network" + - "matrix_bridge_sms_appservice_token" + - "matrix_bridge_sms_homeserver_hostname" + - "matrix_bridge_sms_homeserver_port" + - "matrix_bridge_sms_homeserver_token" + - "matrix_bridge_sms_default_region" + - "matrix_bridge_sms_default_timezone" + - "matrix_bridge_sms_provider_android_baseurl" + - "matrix_bridge_sms_provider_android_username" + - "matrix_bridge_sms_provider_android_password" + - "matrix_bridge_sms_container_network" diff --git a/roles/custom/matrix-bridge-sms/templates/systemd/matrix-sms-bridge.service.j2 b/roles/custom/matrix-bridge-sms/templates/systemd/matrix-sms-bridge.service.j2 index 87218d266..6219c9c9d 100644 --- a/roles/custom/matrix-bridge-sms/templates/systemd/matrix-sms-bridge.service.j2 +++ b/roles/custom/matrix-bridge-sms/templates/systemd/matrix-sms-bridge.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix sms bridge -{% for service in matrix_sms_bridge_systemd_required_services_list %} +{% for service in matrix_bridge_sms_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_sms_bridge_systemd_wanted_services_list %} +{% for service in matrix_bridge_sms_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,21 +22,23 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_sms_bridge_container_network }} \ - {% if matrix_sms_bridge_container_http_host_bind_port %} - -p {{ matrix_sms_bridge_container_http_host_bind_port }}:8080 \ + --network={{ matrix_bridge_sms_container_network }} \ + {% if matrix_bridge_sms_container_http_host_bind_port %} + -p {{ matrix_bridge_sms_container_http_host_bind_port }}:8080 \ {% endif %} - --mount type=bind,src={{ matrix_sms_bridge_config_path }},dst=/config \ - --mount type=bind,src={{ matrix_sms_bridge_data_path }},dst=/data \ + --mount type=bind,src={{ matrix_bridge_sms_config_path }},dst=/config \ + --mount type=bind,src={{ matrix_bridge_sms_data_path }},dst=/data \ --env SPRING_CONFIG_ADDITIONAL_LOCATION=/config/application.yml \ - {% for arg in matrix_sms_bridge_container_extra_arguments %} + {% for arg in matrix_bridge_sms_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_sms_bridge_container_image }} + {{ matrix_bridge_sms_container_image }} -{% for network in matrix_sms_bridge_container_additional_networks %} +{% if matrix_bridge_sms_container_network != 'host' %} +{% for network in matrix_bridge_sms_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-sms-bridge {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-sms-bridge diff --git a/roles/custom/matrix-bridge-steam/defaults/main.yml b/roles/custom/matrix-bridge-steam/defaults/main.yml index b4c96b9fe..a721aef22 100644 --- a/roles/custom/matrix-bridge-steam/defaults/main.yml +++ b/roles/custom/matrix-bridge-steam/defaults/main.yml @@ -6,51 +6,59 @@ # matrix-steam-bridge is a Matrix <-> Steam bridge # See: https://github.com/jasonlaguidice/matrix-steam-bridge -matrix_steam_bridge_enabled: true +matrix_bridge_steam_enabled: true -matrix_steam_bridge_container_image_self_build: false -matrix_steam_bridge_container_image_self_build_repo: "https://github.com/jasonlaguidice/matrix-steam-bridge.git" -matrix_steam_bridge_container_image_self_build_repo_version: "{{ 'main' if matrix_steam_bridge_version == 'latest' else matrix_steam_bridge_version }}" +matrix_bridge_steam_container_image_self_build: false +matrix_bridge_steam_container_image_self_build_repo: "https://github.com/jasonlaguidice/matrix-steam-bridge.git" +matrix_bridge_steam_container_image_self_build_repo_version: "{{ 'main' if matrix_bridge_steam_version == 'latest' else matrix_bridge_steam_version }}" # renovate: datasource=docker depName=ghcr.io/jasonlaguidice/matrix-steam-bridge -matrix_steam_bridge_version: 1.1.0 -matrix_steam_bridge_container_image: "{{ matrix_steam_bridge_container_image_registry_prefix }}jasonlaguidice/matrix-steam-bridge:{{ matrix_steam_bridge_version }}" -matrix_steam_bridge_container_image_registry_prefix: "{{ 'localhost/' if matrix_steam_bridge_container_image_self_build else matrix_steam_bridge_container_image_registry_prefix_upstream }}" -matrix_steam_bridge_container_image_registry_prefix_upstream: "{{ matrix_steam_bridge_container_image_registry_prefix_upstream_default }}" -matrix_steam_bridge_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_steam_bridge_container_image_tag: "{{ matrix_steam_bridge_version }}" -matrix_steam_bridge_container_image_force_pull: "{{ matrix_steam_bridge_container_image.endswith(':latest') }}" - -matrix_steam_bridge_base_path: "{{ matrix_base_data_path }}/matrix-steam-bridge" -matrix_steam_bridge_config_path: "{{ matrix_steam_bridge_base_path }}/config" -matrix_steam_bridge_data_path: "{{ matrix_steam_bridge_base_path }}/data" -matrix_steam_bridge_container_src_files_path: "{{ matrix_steam_bridge_base_path }}/docker-src" - -matrix_steam_bridge_homeserver_address: "" -matrix_steam_bridge_homeserver_domain: "{{ matrix_domain }}" -matrix_steam_bridge_appservice_address: "http://matrix-steam-bridge:{{ matrix_steam_bridge_appservice_port }}" -matrix_steam_bridge_appservice_port: "8080" - -matrix_steam_bridge_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" -matrix_steam_bridge_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" +matrix_bridge_steam_version: 1.3.1 +matrix_bridge_steam_container_image: "{{ matrix_bridge_steam_container_image_registry_prefix }}jasonlaguidice/matrix-steam-bridge:{{ matrix_bridge_steam_version }}" +matrix_bridge_steam_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_steam_container_image_self_build else matrix_bridge_steam_container_image_registry_prefix_upstream }}" +matrix_bridge_steam_container_image_registry_prefix_upstream: "{{ matrix_bridge_steam_container_image_registry_prefix_upstream_default }}" +matrix_bridge_steam_container_image_registry_prefix_upstream_default: "ghcr.io/" +matrix_bridge_steam_container_image_tag: "{{ matrix_bridge_steam_version }}" + +matrix_bridge_steam_base_path: "{{ matrix_base_data_path }}/matrix-steam-bridge" +matrix_bridge_steam_config_path: "{{ matrix_bridge_steam_base_path }}/config" +matrix_bridge_steam_data_path: "{{ matrix_bridge_steam_base_path }}/data" +matrix_bridge_steam_container_src_files_path: "{{ matrix_bridge_steam_base_path }}/docker-src" + +matrix_bridge_steam_homeserver_address: "" +matrix_bridge_steam_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_steam_appservice_address: "http://matrix-steam-bridge:{{ matrix_bridge_steam_appservice_port }}" +matrix_bridge_steam_appservice_port: "8080" + +matrix_bridge_steam_msc4190_enabled: "{{ matrix_bridges_msc4190_enabled }}" +matrix_bridge_steam_self_sign_enabled: "{{ matrix_bridges_self_sign_enabled }}" # matrix -> steam presence -matrix_steam_bridge_network_presence_enabled: true +matrix_bridge_steam_network_presence_enabled: true # Default inactivity state # This is what the bridge sets it's status to after some time of no user interaction -matrix_steam_bridge_network_presence_inactivity_status: 'invisible' +matrix_bridge_steam_network_presence_inactivity_status: 'invisible' + +# steam -> matrix presence topic +# Master switch for setting a Steam friend's current game (+ rich presence flavor +# text) as the DM room's m.room.topic. +matrix_bridge_steam_network_presence_topic_enabled: false +# Append resolved rich presence flavor text to the topic (e.g. "Deadlock — Street Brawl: Paige (12 min)"). +matrix_bridge_steam_network_presence_topic_rich_presence_enabled: false +# Fallback: show the raw unresolved rich presence token if resolution fails. +matrix_bridge_steam_network_presence_topic_show_raw_tokens: false # A public address that external services can use to reach this appservice -matrix_steam_bridge_appservice_public_address: "https://{{ matrix_server_fqn_matrix }}" +matrix_bridge_steam_appservice_public_address: "https://{{ matrix_server_fqn_matrix }}" # Public media configuration for external access to bridge media -matrix_steam_bridge_public_media_enabled: true +matrix_bridge_steam_public_media_enabled: true # A key for signing public media URLs. If set to "generate", a random key will be generated. # This will be auto-generated deterministically if matrix_homeserver_generic_secret_key is set. -matrix_steam_bridge_public_media_signing_key: '' +matrix_bridge_steam_public_media_signing_key: '' # Number of seconds that public media URLs are valid for. If set to 0, URLs will never expire. -matrix_steam_bridge_public_media_expiry: 0 -matrix_steam_bridge_public_media_hash_length: 32 +matrix_bridge_steam_public_media_expiry: 0 +matrix_bridge_steam_public_media_hash_length: 32 # Display name template for Steam users. # Available template variables: @@ -59,200 +67,192 @@ matrix_steam_bridge_public_media_hash_length: 32 # {{.SteamID}} - The numeric Steam ID # {{.ProfileURL}} - The Steam profile URL # You can use template functions like {{or}} to provide fallbacks. -matrix_steam_bridge_network_displayname_template: "{% raw %}{{ .PersonaName }} (Steam){% endraw %}" +matrix_bridge_steam_network_displayname_template: "{% raw %}{{ .PersonaName }} (Steam){% endraw %}" -matrix_steam_bridge_command_prefix: "!steam" +matrix_bridge_steam_command_prefix: "!steam" -matrix_steam_bridge_bridge_permissions: | +matrix_bridge_steam_bridge_permissions: | {{ - {matrix_steam_bridge_homeserver_domain: 'user'} + {matrix_bridge_steam_homeserver_domain: 'user'} | combine ({matrix_admin: 'admin'} if matrix_admin else {}) }} # TODO: May need to set network for public media? -matrix_steam_bridge_container_network: "" +matrix_bridge_steam_container_network: "" -matrix_steam_bridge_container_additional_networks: "{{ matrix_steam_bridge_container_additional_networks_auto + matrix_steam_bridge_container_additional_networks_custom }}" -matrix_steam_bridge_container_additional_networks_auto: [] -matrix_steam_bridge_container_additional_networks_custom: [] +matrix_bridge_steam_container_additional_networks: "{{ matrix_bridge_steam_container_additional_networks_auto + matrix_bridge_steam_container_additional_networks_custom }}" +matrix_bridge_steam_container_additional_networks_auto: [] +matrix_bridge_steam_container_additional_networks_custom: [] -# matrix_steam_bridge_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# matrix_bridge_steam_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # -# To inject your own other container labels, see `matrix_steam_bridge_container_labels_additional_labels`. -matrix_steam_bridge_container_labels_traefik_enabled: true -matrix_steam_bridge_container_labels_traefik_docker_network: "{{ matrix_steam_bridge_container_network }}" -matrix_steam_bridge_container_labels_traefik_entrypoints: web-secure -matrix_steam_bridge_container_labels_traefik_tls: "{{ matrix_steam_bridge_container_labels_traefik_entrypoints != 'web' }}" -matrix_steam_bridge_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose mautrix-instagram's metrics -matrix_steam_bridge_container_labels_metrics_enabled: "{{ matrix_steam_bridge_metrics_enabled and matrix_steam_bridge_metrics_proxying_enabled }}" -matrix_steam_bridge_container_labels_metrics_traefik_rule: "Host(`{{ matrix_steam_bridge_metrics_proxying_hostname }}`) && PathPrefix(`{{ matrix_steam_bridge_metrics_proxying_path_prefix }}`)" -matrix_steam_bridge_container_labels_metrics_traefik_priority: 0 -matrix_steam_bridge_container_labels_metrics_traefik_entrypoints: "{{ matrix_steam_bridge_container_labels_traefik_entrypoints }}" -matrix_steam_bridge_container_labels_metrics_traefik_tls: "{{ matrix_steam_bridge_container_labels_metrics_traefik_entrypoints != 'web' }}" -matrix_steam_bridge_container_labels_metrics_traefik_tls_certResolver: "{{ matrix_steam_bridge_container_labels_traefik_tls_certResolver }}" # noqa var-naming -matrix_steam_bridge_container_labels_metrics_middleware_basic_auth_enabled: false -# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users -matrix_steam_bridge_container_labels_metrics_middleware_basic_auth_users: '' - -# matrix_steam_bridge_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# To inject your own other container labels, see `matrix_bridge_steam_container_labels_additional_labels`. +matrix_bridge_steam_container_labels_traefik_enabled: true +matrix_bridge_steam_container_labels_traefik_docker_network: "{{ matrix_bridge_steam_container_network }}" +matrix_bridge_steam_container_labels_traefik_entrypoints: web-secure +matrix_bridge_steam_container_labels_traefik_tls: "{{ matrix_bridge_steam_container_labels_traefik_entrypoints != 'web' }}" +matrix_bridge_steam_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Whether this bridge's HTTP API (including the provisioning API) is exposed at a +# public path via Traefik. Disabled by default. When enabled, requests to +# https:///... +# are forwarded to the bridge with that path prefix stripped. +matrix_bridge_steam_exposure_enabled: false +matrix_bridge_steam_exposure_hostname: '' +matrix_bridge_steam_exposure_path_prefix: '' + +matrix_bridge_steam_container_labels_exposure_enabled: "{{ matrix_bridge_steam_exposure_enabled }}" +matrix_bridge_steam_container_labels_exposure_traefik_rule: "Host(`{{ matrix_bridge_steam_exposure_hostname }}`) && PathPrefix(`{{ matrix_bridge_steam_exposure_path_prefix }}`)" +matrix_bridge_steam_container_labels_exposure_traefik_priority: 0 +matrix_bridge_steam_container_labels_exposure_traefik_entrypoints: "{{ matrix_bridge_steam_container_labels_traefik_entrypoints }}" +matrix_bridge_steam_container_labels_exposure_traefik_tls: "{{ matrix_bridge_steam_container_labels_exposure_traefik_entrypoints != 'web' }}" +matrix_bridge_steam_container_labels_exposure_traefik_tls_certResolver: "{{ matrix_bridge_steam_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bridge_steam_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # # Example: -# matrix_steam_bridge_container_labels_additional_labels: | +# matrix_bridge_steam_container_labels_additional_labels: | # my.label=1 # another.label="here" -matrix_steam_bridge_container_labels_additional_labels: '' +matrix_bridge_steam_container_labels_additional_labels: '' # A list of extra arguments to pass to the container -matrix_steam_bridge_container_extra_arguments: [] +matrix_bridge_steam_container_extra_arguments: [] -# List of systemd services that matrix_steam_bridge.service depends on. -matrix_steam_bridge_systemd_required_services_list: "{{ matrix_steam_bridge_systemd_required_services_list_default + matrix_steam_bridge_systemd_required_services_list_auto + matrix_steam_bridge_systemd_required_services_list_custom }}" -matrix_steam_bridge_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_steam_bridge_systemd_required_services_list_auto: [] -matrix_steam_bridge_systemd_required_services_list_custom: [] +# List of systemd services that matrix-steam-bridge.service depends on. +matrix_bridge_steam_systemd_required_services_list: "{{ matrix_bridge_steam_systemd_required_services_list_default + matrix_bridge_steam_systemd_required_services_list_auto + matrix_bridge_steam_systemd_required_services_list_custom }}" +matrix_bridge_steam_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_steam_systemd_required_services_list_auto: [] +matrix_bridge_steam_systemd_required_services_list_custom: [] -# List of systemd services that matrix_steam_bridge.service wants -matrix_steam_bridge_systemd_wanted_services_list: [] +# List of systemd services that matrix-steam-bridge.service wants +matrix_bridge_steam_systemd_wanted_services_list: [] -matrix_steam_bridge_appservice_token: '' -matrix_steam_bridge_homeserver_token: '' +matrix_bridge_steam_appservice_token: '' +matrix_bridge_steam_homeserver_token: '' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_steam_bridge_matrix_federate_rooms: false +matrix_bridge_steam_matrix_federate_rooms: false # Bridge configuration options # Should every user have their own portals rather than sharing them? -matrix_steam_bridge_bridge_split_portals: false +matrix_bridge_steam_bridge_split_portals: false # Cleanup on logout configuration -matrix_steam_bridge_bridge_cleanup_on_logout_enabled: false +matrix_bridge_steam_bridge_cleanup_on_logout_enabled: false # Valid values for cleanup actions: nothing, kick, unbridge, delete # nothing - Do nothing, let the user stay in the portals # kick - Remove the user from the portal rooms, but don't delete them # unbridge - Remove all ghosts in the room and disassociate it from the remote chat # delete - Remove all ghosts and users from the room (i.e. delete it) -matrix_steam_bridge_bridge_cleanup_on_logout_manual_private: nothing -matrix_steam_bridge_bridge_cleanup_on_logout_manual_relayed: nothing -matrix_steam_bridge_bridge_cleanup_on_logout_manual_shared_no_users: nothing -matrix_steam_bridge_bridge_cleanup_on_logout_manual_shared_has_users: nothing -matrix_steam_bridge_bridge_cleanup_on_logout_bad_credentials_private: nothing -matrix_steam_bridge_bridge_cleanup_on_logout_bad_credentials_relayed: nothing -matrix_steam_bridge_bridge_cleanup_on_logout_bad_credentials_shared_no_users: nothing -matrix_steam_bridge_bridge_cleanup_on_logout_bad_credentials_shared_has_users: nothing +matrix_bridge_steam_bridge_cleanup_on_logout_manual_private: nothing +matrix_bridge_steam_bridge_cleanup_on_logout_manual_relayed: nothing +matrix_bridge_steam_bridge_cleanup_on_logout_manual_shared_no_users: nothing +matrix_bridge_steam_bridge_cleanup_on_logout_manual_shared_has_users: nothing +matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_private: nothing +matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_relayed: nothing +matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_shared_no_users: nothing +matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_shared_has_users: nothing # Homeserver configuration options # Does the homeserver support MSC2246 (async media uploads)? -matrix_steam_bridge_homeserver_async_media: false +matrix_bridge_steam_homeserver_async_media: false # Database-related configuration fields. # # To use Postgres: -# - adjust your database credentials via the `matrix_steam_bridge_postgres_*` variables -matrix_steam_bridge_database_engine: 'postgres' +# - adjust your database credentials via the `matrix_bridge_steam_postgres_*` variables +matrix_bridge_steam_database_engine: 'postgres' -matrix_steam_bridge_database_username: 'matrix_steam_bridge' -matrix_steam_bridge_database_password: 'some-password' -matrix_steam_bridge_database_hostname: '' -matrix_steam_bridge_database_port: 5432 -matrix_steam_bridge_database_name: 'matrix_steam_bridge' -matrix_steam_bridge_database_sslmode: disable +matrix_bridge_steam_database_username: 'matrix_steam_bridge' +matrix_bridge_steam_database_password: 'some-password' +matrix_bridge_steam_database_hostname: '' +matrix_bridge_steam_database_port: 5432 +matrix_bridge_steam_database_name: 'matrix_steam_bridge' +matrix_bridge_steam_database_sslmode: disable -matrix_steam_bridge_database_connection_string: 'postgres://{{ matrix_steam_bridge_database_username }}:{{ matrix_steam_bridge_database_password }}@{{ matrix_steam_bridge_database_hostname }}:{{ matrix_steam_bridge_database_port }}/{{ matrix_steam_bridge_database_name }}?sslmode={{ matrix_steam_bridge_database_sslmode }}' +matrix_bridge_steam_database_connection_string: 'postgres://{{ matrix_bridge_steam_database_username }}:{{ matrix_bridge_steam_database_password }}@{{ matrix_bridge_steam_database_hostname }}:{{ matrix_bridge_steam_database_port }}/{{ matrix_bridge_steam_database_name }}?sslmode={{ matrix_bridge_steam_database_sslmode }}' -matrix_steam_bridge_database_uri: "{{ - { - 'postgres': matrix_steam_bridge_database_connection_string, - }[matrix_steam_bridge_database_engine] -}}" +matrix_bridge_steam_database_uri: "{{ { + 'postgres': matrix_bridge_steam_database_connection_string, +}[matrix_bridge_steam_database_engine] }}" -matrix_steam_bridge_double_puppet_secrets: "{{ matrix_steam_bridge_double_puppet_secrets_auto | combine(matrix_steam_bridge_double_puppet_secrets_custom) }}" -matrix_steam_bridge_double_puppet_secrets_auto: {} -matrix_steam_bridge_double_puppet_secrets_custom: {} +matrix_bridge_steam_double_puppet_secrets: "{{ matrix_bridge_steam_double_puppet_secrets_auto | combine(matrix_bridge_steam_double_puppet_secrets_custom) }}" +matrix_bridge_steam_double_puppet_secrets_auto: {} +matrix_bridge_steam_double_puppet_secrets_custom: {} -matrix_steam_bridge_appservice_bot_username: steambot -matrix_steam_bridge_appservice_bot_displayname: Steam bridge bot -matrix_steam_bridge_appservice_bot_avatar: mxc://shadowdrake.org/EeNKAcrmByNubPwoyceQsBaN +matrix_bridge_steam_appservice_bot_username: steambot +matrix_bridge_steam_appservice_bot_displayname: Steam bridge bot +matrix_bridge_steam_appservice_bot_avatar: mxc://shadowdrake.org/EeNKAcrmByNubPwoyceQsBaN -matrix_steam_bridge_backfill_enabled: true +matrix_bridge_steam_backfill_enabled: true # Maximum number of messages to backfill in empty rooms -matrix_steam_bridge_backfill_max_initial_messages: 50 +matrix_bridge_steam_backfill_max_initial_messages: 50 # Maximum number of missed messages to backfill after bridge restarts -matrix_steam_bridge_backfill_max_catchup_messages: 500 +matrix_bridge_steam_backfill_max_catchup_messages: 500 # Shared secret for authentication of provisioning API requests. # If set to "disable", the provisioning API will be disabled. -matrix_steam_bridge_provisioning_shared_secret: disable +matrix_bridge_steam_provisioning_shared_secret: disable # Minimum severity of journal log messages. # Valid values: fatal, error, warn, info, debug, trace -matrix_steam_bridge_logging_level: 'warn' - -# Whether or not metrics endpoint should be enabled. -# Enabling them is usually enough for a local (in-container) Prometheus to consume them. -# If metrics need to be consumed by another (external) Prometheus server, consider exposing them via `matrix_steam_bridge_metrics_proxying_enabled`. -matrix_steam_bridge_metrics_enabled: false - -# Controls whether metrics should be exposed on a public URL. -matrix_steam_bridge_metrics_proxying_enabled: false -matrix_steam_bridge_metrics_proxying_hostname: '' -matrix_steam_bridge_metrics_proxying_path_prefix: '' +matrix_bridge_steam_logging_level: 'warn' # Default configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_steam_bridge_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_steam_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_steam_bridge_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_steam_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_steam_bridge_configuration_extension_yaml: | +matrix_bridge_steam_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_steam_bridge_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_steam_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_steam_bridge_configuration_yaml`. + # completely redefining `matrix_bridge_steam_configuration_yaml`. -matrix_steam_bridge_configuration_extension: "{{ matrix_steam_bridge_configuration_extension_yaml | from_yaml if matrix_steam_bridge_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_steam_configuration_extension: "{{ matrix_bridge_steam_configuration_extension_yaml | from_yaml if matrix_bridge_steam_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_steam_bridge_configuration_yaml`. -matrix_steam_bridge_configuration: "{{ matrix_steam_bridge_configuration_yaml | from_yaml | combine(matrix_steam_bridge_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_steam_configuration_yaml`. +matrix_bridge_steam_configuration: "{{ matrix_bridge_steam_configuration_yaml | from_yaml | combine(matrix_bridge_steam_configuration_extension, recursive=True) }}" -matrix_steam_bridge_registration_yaml: | +matrix_bridge_steam_registration_yaml: | id: steam - as_token: "{{ matrix_steam_bridge_appservice_token }}" - hs_token: "{{ matrix_steam_bridge_homeserver_token }}" + as_token: "{{ matrix_bridge_steam_appservice_token }}" + hs_token: "{{ matrix_bridge_steam_homeserver_token }}" namespaces: users: - exclusive: true - regex: '^@steam_.+:{{ matrix_steam_bridge_homeserver_domain | regex_escape }}$' + regex: '^@steam_.+:{{ matrix_bridge_steam_homeserver_domain | regex_escape }}$' - exclusive: true - regex: '^@{{ matrix_steam_bridge_appservice_bot_username | regex_escape }}:{{ matrix_steam_bridge_homeserver_domain | regex_escape }}$' - url: {{ matrix_steam_bridge_appservice_address }} - sender_localpart: _bot_{{ matrix_steam_bridge_appservice_bot_username }} + regex: '^@{{ matrix_bridge_steam_appservice_bot_username | regex_escape }}:{{ matrix_bridge_steam_homeserver_domain | regex_escape }}$' + url: {{ matrix_bridge_steam_appservice_address }} + sender_localpart: _bot_{{ matrix_bridge_steam_appservice_bot_username }} rate_limited: false de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true - io.element.msc4190: {{ matrix_steam_bridge_msc4190_enabled | to_json }} + io.element.msc4190: {{ matrix_bridge_steam_msc4190_enabled | to_json }} -matrix_steam_bridge_registration: "{{ matrix_steam_bridge_registration_yaml | from_yaml }}" +matrix_bridge_steam_registration: "{{ matrix_bridge_steam_registration_yaml | from_yaml }}" # Enable End-to-bridge encryption -matrix_steam_bridge_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_steam_bridge_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" -matrix_steam_bridge_bridge_encryption_require: false -matrix_steam_bridge_bridge_encryption_appservice: false -matrix_steam_bridge_bridge_encryption_key_sharing_allow: "{{ matrix_steam_bridge_bridge_encryption_allow }}" -matrix_steam_bridge_bridge_encryption_pickle_key: mautrix.bridge.e2ee - -# matrix_steam_bridge_restart_necessary controls whether the service +matrix_bridge_steam_bridge_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_steam_bridge_encryption_default: "{{ matrix_bridges_encryption_default }}" +matrix_bridge_steam_bridge_encryption_require: false +matrix_bridge_steam_bridge_encryption_appservice: false +matrix_bridge_steam_bridge_encryption_key_sharing_allow: "{{ matrix_bridge_steam_bridge_encryption_allow }}" +matrix_bridge_steam_bridge_encryption_pickle_key: mautrix.bridge.e2ee + +# matrix_bridge_steam_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -260,4 +260,4 @@ matrix_steam_bridge_bridge_encryption_pickle_key: mautrix.bridge.e2ee # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_steam_bridge_restart_necessary: false +matrix_bridge_steam_restart_necessary: false diff --git a/roles/custom/matrix-bridge-steam/molecule/default/converge.yml b/roles/custom/matrix-bridge-steam/molecule/default/converge.yml new file mode 100644 index 000000000..fc8e99e74 --- /dev/null +++ b/roles/custom/matrix-bridge-steam/molecule/default/converge.yml @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-bridge-steam Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-bridge-steam Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +- name: Ensure matrix-bridge-steam is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the matrix-bridge-steam systemd service is started + ansible.builtin.systemd_service: + name: matrix-steam-bridge.service + state: started diff --git a/roles/custom/matrix-bridge-steam/molecule/default/molecule.yml b/roles/custom/matrix-bridge-steam/molecule/default/molecule.yml new file mode 100644 index 000000000..bb6fcd0e1 --- /dev/null +++ b/roles/custom/matrix-bridge-steam/molecule/default/molecule.yml @@ -0,0 +1,126 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-bridge-steam-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_bridge_steam_enabled: true + matrix_bridge_steam_container_network: matrix-bridge-steam-molecule + + # The stub is not a real homeserver and the scenario carries no Steam + # credentials. Logged out is the intended component boundary. + matrix_bridge_steam_homeserver_address: http://matrix.molecule.local:8008 + matrix_bridge_steam_homeserver_domain: molecule.local + matrix_bridge_steam_homeserver_async_media: true + + # Use a non-default listener to prove configuration, service command and + # routing labels agree on the appservice endpoint. + matrix_bridge_steam_appservice_port: 8766 + + # Postgres is the normal deployment path. Distinct names make the migrated + # schema evidence that the role composed this connection successfully. + matrix_bridge_steam_database_engine: postgres + matrix_bridge_steam_database_hostname: matrix-postgres-molecule + matrix_bridge_steam_database_name: molecule_steam + matrix_bridge_steam_database_username: molecule_steam + matrix_bridge_steam_database_password: molecule_pg_password_8f527c + + matrix_bridge_steam_appservice_token: molecule_steam_as_token_d74a61 + matrix_bridge_steam_homeserver_token: molecule_steam_hs_token_7b39e2 + matrix_bridge_steam_appservice_bot_username: molecule-steambot + matrix_bridge_steam_appservice_bot_displayname: Molecule Steam bridge + matrix_bridge_steam_appservice_bot_avatar: mxc://molecule.local/steamMoleculeAvatar + + # Exercise role-rendered Steam and generic bridge behavior with values that + # differ from the role and component defaults. + matrix_bridge_steam_network_displayname_template: "{% raw %}{{ .PersonaName }} via Molecule{% endraw %}" + matrix_bridge_steam_network_presence_enabled: false + matrix_bridge_steam_network_presence_inactivity_status: snooze + matrix_bridge_steam_network_presence_topic_enabled: true + matrix_bridge_steam_network_presence_topic_rich_presence_enabled: true + matrix_bridge_steam_network_presence_topic_show_raw_tokens: true + matrix_bridge_steam_command_prefix: "!molecule-steam" + matrix_bridge_steam_bridge_permissions: + "*": commands + molecule.local: admin + matrix_bridge_steam_bridge_split_portals: true + matrix_bridge_steam_bridge_cleanup_on_logout_enabled: true + matrix_bridge_steam_bridge_cleanup_on_logout_manual_private: kick + matrix_bridge_steam_bridge_cleanup_on_logout_manual_relayed: unbridge + matrix_bridge_steam_bridge_cleanup_on_logout_manual_shared_no_users: delete + matrix_bridge_steam_bridge_cleanup_on_logout_manual_shared_has_users: kick + matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_private: delete + matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_relayed: kick + matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_shared_no_users: unbridge + matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_shared_has_users: delete + matrix_bridge_steam_matrix_federate_rooms: true + matrix_bridge_steam_backfill_enabled: false + matrix_bridge_steam_backfill_max_initial_messages: 17 + matrix_bridge_steam_backfill_max_catchup_messages: 29 + matrix_bridge_steam_provisioning_shared_secret: molecule_steam_provisioning_secret_43c1ea + matrix_bridge_steam_double_puppet_secrets_custom: + molecule.remote: molecule_steam_double_puppet_51d28a + matrix_bridge_steam_logging_level: info + + # Public media needs no external test fixture and is disabled here; bridge API + # exposure remains enabled to exercise its generated Traefik contract. + matrix_bridge_steam_public_media_enabled: false + matrix_bridge_steam_appservice_public_address: http://steam-public.molecule.local + matrix_bridge_steam_exposure_enabled: true + matrix_bridge_steam_exposure_hostname: steam-api.molecule.local + matrix_bridge_steam_exposure_path_prefix: /bridges/steam-api + matrix_bridge_steam_container_labels_traefik_enabled: true + matrix_bridge_steam_container_labels_traefik_entrypoints: web + matrix_bridge_steam_container_labels_traefik_tls: false + matrix_bridge_steam_container_labels_additional_labels: | + molecule.steam.coverage=enabled + + matrix_bridge_steam_container_extra_arguments: + - --hostname=steam-bridge-molecule-runtime + - --label=molecule.steam.extra-argument=reached + + # verify.yml is a separate play, where role defaults are out of scope. + matrix_bridge_steam_base_path: /matrix/matrix-steam-bridge + matrix_bridge_steam_config_path: /matrix/matrix-steam-bridge/config + matrix_bridge_steam_data_path: /matrix/matrix-steam-bridge/data + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-bridge-steam/molecule/default/prepare.yml b/roles/custom/matrix-bridge-steam/molecule/default/prepare.yml new file mode 100644 index 000000000..ee62a77e1 --- /dev/null +++ b/roles/custom/matrix-bridge-steam/molecule/default/prepare.yml @@ -0,0 +1,87 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-bridge-steam Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + # The role creates this in converge, but both fixtures attach to it first. + - name: Ensure the container network the role attaches to exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_bridge_steam_container_network }}" + register: matrix_bridge_steam_molecule_network + changed_when: matrix_bridge_steam_molecule_network.rc == 0 + failed_when: + - matrix_bridge_steam_molecule_network.rc != 0 + - "'already exists' not in matrix_bridge_steam_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_bridge_steam_container_network }}" + molecule_shared_postgres_database: "{{ matrix_bridge_steam_database_name }}" + molecule_shared_postgres_username: "{{ matrix_bridge_steam_database_username }}" + molecule_shared_postgres_password: "{{ matrix_bridge_steam_database_password }}" + + # The logged-out bridge checks the appservice bot identity during startup. + - name: Ensure the homeserver stub is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/homeserver-stub.yml" + vars: + molecule_shared_stub_network: "{{ matrix_bridge_steam_container_network }}" + molecule_shared_stub_server_name: "{{ matrix_bridge_steam_homeserver_domain }}" + molecule_shared_stub_user_id: "@{{ matrix_bridge_steam_appservice_bot_username }}:{{ matrix_bridge_steam_homeserver_domain }}" diff --git a/roles/custom/matrix-bridge-steam/molecule/default/requirements.yml b/roles/custom/matrix-bridge-steam/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-bridge-steam/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-bridge-steam/molecule/default/verify.yml b/roles/custom/matrix-bridge-steam/molecule/default/verify.yml new file mode 100644 index 000000000..3ecb8810d --- /dev/null +++ b/roles/custom/matrix-bridge-steam/molecule/default/verify.yml @@ -0,0 +1,495 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the logged-out bridge starts, accepts the role-rendered configuration and +# registration, migrates real Postgres and opens its appservice listener. Steam +# credentials are deliberately outside the scenario boundary. +- name: Verify matrix-bridge-steam + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + matrix_bridge_steam_config: "{{ matrix_bridge_steam_config_file.content | b64decode | from_yaml }}" + matrix_bridge_steam_registration: "{{ matrix_bridge_steam_registration_file.content | b64decode | from_yaml }}" + matrix_bridge_steam_labels_rendered: "{{ matrix_bridge_steam_labels_file.content | b64decode }}" + matrix_bridge_steam_runtime: "{{ (matrix_bridge_steam_container_inspect.stdout | from_json) | first }}" + gather_facts: false + + tasks: + # A Renovate bump changes this source of truth and therefore the image expectation. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_bridge_steam_role_defaults + + - name: Wait for the Steam bridge service to become active + ansible.builtin.systemd_service: + name: matrix-steam-bridge.service + register: matrix_bridge_steam_service + until: matrix_bridge_steam_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_bridge_steam_service.status.ActiveState == 'active' + - matrix_bridge_steam_service.status.NRestarts is defined + - matrix_bridge_steam_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-steam-bridge.service is + {{ matrix_bridge_steam_service.status.ActiveState | default('unknown') }} after + {{ matrix_bridge_steam_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-steam-bridge.service is active and has not restarted" + + - name: Wait for the bridge liveness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_steam_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - "http://matrix-steam-bridge:{{ matrix_bridge_steam_appservice_port }}/_matrix/mau/live" + register: matrix_bridge_steam_live + changed_when: false + until: matrix_bridge_steam_live.rc == 0 and matrix_bridge_steam_live.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Wait for the bridge readiness endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_steam_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - "http://matrix-steam-bridge:{{ matrix_bridge_steam_appservice_port }}/_matrix/mau/ready" + register: matrix_bridge_steam_ready + changed_when: false + until: matrix_bridge_steam_ready.rc == 0 and matrix_bridge_steam_ready.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the bridge is live and ready on the configured appservice port + ansible.builtin.assert: + that: + - matrix_bridge_steam_live.rc == 0 + - matrix_bridge_steam_live.stdout == 'HTTP_STATUS=200' + - matrix_bridge_steam_ready.rc == 0 + - matrix_bridge_steam_ready.stdout == 'HTTP_STATUS=200' + fail_msg: >- + Health probes returned live={{ matrix_bridge_steam_live.stdout | default('none') }} and + ready={{ matrix_bridge_steam_ready.stdout | default('none') }} + success_msg: "The bridge is live and ready on the configured appservice port" + + # This is the live homeserver-to-appservice half of the registration handshake. + # It detects the old image-entrypoint mismatch, which generated unrelated tokens + # under /app/data while the role's registration remained unused under /app/config. + - name: Submit an empty appservice transaction with the configured token + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_steam_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --fail-with-body + - --request + - PUT + - --header + - "Content-Type: application/json" + - --header + - "Authorization: Bearer {{ matrix_bridge_steam_homeserver_token }}" + - --data-binary + - '{"events": [], "ephemeral": []}' + - "http://matrix-steam-bridge:{{ matrix_bridge_steam_appservice_port }}/_matrix/app/v1/transactions/molecule-coverage" + register: matrix_bridge_steam_transaction + changed_when: false + + - name: Submit an appservice transaction with an invalid token + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_steam_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - --request + - PUT + - --header + - "Content-Type: application/json" + - --header + - "Authorization: Bearer definitely-wrong-molecule-token" + - --data-binary + - '{"events": [], "ephemeral": []}' + - "http://matrix-steam-bridge:{{ matrix_bridge_steam_appservice_port }}/_matrix/app/v1/transactions/molecule-unauthorized" + register: matrix_bridge_steam_transaction_unauthorized + changed_when: false + failed_when: false + + - name: Assert the live appservice accepts only the configured handshake token + ansible.builtin.assert: + that: + - matrix_bridge_steam_transaction.rc == 0 + - matrix_bridge_steam_transaction.stdout | from_json == {} + - matrix_bridge_steam_transaction_unauthorized.rc == 0 + - matrix_bridge_steam_transaction_unauthorized.stdout == 'HTTP_STATUS=401' + fail_msg: "The live appservice did not enforce the role-rendered hs_token" + success_msg: "The live appservice accepts the role-rendered hs_token and rejects another" + + - name: Query the authenticated Steam provisioning login flows + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_steam_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --fail-with-body + - --header + - "Authorization: Bearer {{ matrix_bridge_steam_provisioning_shared_secret }}" + - "http://matrix-steam-bridge:{{ matrix_bridge_steam_appservice_port }}/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: matrix_bridge_steam_login_flows + changed_when: false + + - name: Query the provisioning API with an invalid secret + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_bridge_steam_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - --header + - "Authorization: Bearer definitely-wrong-molecule-secret" + - "http://matrix-steam-bridge:{{ matrix_bridge_steam_appservice_port }}/_matrix/provision/v3/login/flows?user_id=%40alice%3Amolecule.local" + register: matrix_bridge_steam_login_flows_unauthorized + changed_when: false + failed_when: false + + - name: Assert the live provisioning API enforces auth and advertises Steam login + ansible.builtin.assert: + that: + - matrix_bridge_steam_login_flows.rc == 0 + - (matrix_bridge_steam_login_flows.stdout | from_json).flows is sequence + - (matrix_bridge_steam_login_flows.stdout | from_json).flows | length > 0 + - matrix_bridge_steam_login_flows_unauthorized.rc == 0 + - matrix_bridge_steam_login_flows_unauthorized.stdout == 'HTTP_STATUS=401' + fail_msg: "The provisioning API did not enforce its secret or return Steam login flows" + success_msg: "The provisioning API enforces its secret and returns Steam login flows" + + - name: Read the configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_steam_config_path }}/config.yaml" + register: matrix_bridge_steam_config_file + + - name: Assert the rendered configuration carries the appservice identity + ansible.builtin.assert: + that: + - matrix_bridge_steam_config.homeserver.address == matrix_bridge_steam_homeserver_address + - matrix_bridge_steam_config.homeserver.domain == matrix_bridge_steam_homeserver_domain + - matrix_bridge_steam_config.homeserver.async_media + - matrix_bridge_steam_config.appservice.id == 'steam' + - matrix_bridge_steam_config.appservice.address == 'http://matrix-steam-bridge:8766' + - matrix_bridge_steam_config.appservice.public_address == matrix_bridge_steam_appservice_public_address + - matrix_bridge_steam_config.appservice.port == 8766 + - matrix_bridge_steam_config.appservice.bot.username == matrix_bridge_steam_appservice_bot_username + - matrix_bridge_steam_config.appservice.bot.displayname == matrix_bridge_steam_appservice_bot_displayname + - matrix_bridge_steam_config.appservice.bot.avatar == matrix_bridge_steam_appservice_bot_avatar + - matrix_bridge_steam_config.appservice.as_token == matrix_bridge_steam_appservice_token + - matrix_bridge_steam_config.appservice.hs_token == matrix_bridge_steam_homeserver_token + fail_msg: "The rendered configuration does not carry the scenario's appservice identity" + success_msg: "The rendered configuration carries the scenario's appservice identity" + + - name: Assert the rendered configuration carries non-default Steam behavior + ansible.builtin.assert: + that: + - matrix_bridge_steam_config.network.displayname_template == matrix_bridge_steam_network_displayname_template + - not matrix_bridge_steam_config.network.presence.enabled + - matrix_bridge_steam_config.network.presence.inactivity_status == 'snooze' + - matrix_bridge_steam_config.network.presence_topic.enabled + - matrix_bridge_steam_config.network.presence_topic.rich_presence_enabled + - matrix_bridge_steam_config.network.presence_topic.show_raw_tokens + - matrix_bridge_steam_config.bridge.command_prefix == matrix_bridge_steam_command_prefix + - matrix_bridge_steam_config.bridge.split_portals + - matrix_bridge_steam_config.bridge.permissions['*'] == 'commands' + - matrix_bridge_steam_config.bridge.permissions[matrix_bridge_steam_homeserver_domain] == 'admin' + - matrix_bridge_steam_config.matrix.federate_rooms + - matrix_bridge_steam_config.logging.min_level == matrix_bridge_steam_logging_level + fail_msg: "The rendered configuration does not carry the scenario's Steam behavior" + success_msg: "The rendered configuration carries the scenario's Steam behavior" + + - name: Assert the rendered configuration carries the cleanup policy + ansible.builtin.assert: + that: + - matrix_bridge_steam_config.bridge.cleanup_on_logout.enabled + - matrix_bridge_steam_config.bridge.cleanup_on_logout.manual.private == 'kick' + - matrix_bridge_steam_config.bridge.cleanup_on_logout.manual.relayed == 'unbridge' + - matrix_bridge_steam_config.bridge.cleanup_on_logout.manual.shared_no_users == 'delete' + - matrix_bridge_steam_config.bridge.cleanup_on_logout.manual.shared_has_users == 'kick' + - matrix_bridge_steam_config.bridge.cleanup_on_logout.bad_credentials.private == 'delete' + - matrix_bridge_steam_config.bridge.cleanup_on_logout.bad_credentials.relayed == 'kick' + - matrix_bridge_steam_config.bridge.cleanup_on_logout.bad_credentials.shared_no_users == 'unbridge' + - matrix_bridge_steam_config.bridge.cleanup_on_logout.bad_credentials.shared_has_users == 'delete' + fail_msg: "The rendered configuration does not carry the scenario's cleanup policy" + success_msg: "The rendered configuration carries the scenario's cleanup policy" + + - name: Assert the rendered configuration carries integration and backfill settings + ansible.builtin.assert: + that: + - matrix_bridge_steam_config.provisioning.shared_secret == matrix_bridge_steam_provisioning_shared_secret + - matrix_bridge_steam_config.double_puppet.secrets['molecule.remote'] == 'molecule_steam_double_puppet_51d28a' + - not matrix_bridge_steam_config.public_media.enabled + - not matrix_bridge_steam_config.backfill.enabled + - matrix_bridge_steam_config.backfill.max_initial_messages == 17 + - matrix_bridge_steam_config.backfill.max_catchup_messages == 29 + fail_msg: "The rendered configuration lost the scenario's integration or backfill settings" + success_msg: "The rendered configuration carries the integration and backfill settings" + + - name: Assert the configuration points at the scenario's Postgres database + ansible.builtin.assert: + that: + - matrix_bridge_steam_config.database.type == matrix_bridge_steam_database_engine + - matrix_bridge_steam_database_username in matrix_bridge_steam_config.database.uri + - matrix_bridge_steam_database_hostname in matrix_bridge_steam_config.database.uri + - matrix_bridge_steam_database_name in matrix_bridge_steam_config.database.uri + fail_msg: "The rendered database URI was not composed from the scenario's settings" + success_msg: "The configuration points at the scenario's Postgres database" + + - name: Read the appservice registration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_steam_config_path }}/registration.yaml" + register: matrix_bridge_steam_registration_file + + - name: Assert the registration carries the configured handshake values + ansible.builtin.assert: + that: + - matrix_bridge_steam_registration.id == 'steam' + - matrix_bridge_steam_registration.as_token == matrix_bridge_steam_appservice_token + - matrix_bridge_steam_registration.hs_token == matrix_bridge_steam_homeserver_token + - matrix_bridge_steam_registration.sender_localpart == '_bot_' + matrix_bridge_steam_appservice_bot_username + - matrix_bridge_steam_registration.url == 'http://matrix-steam-bridge:8766' + fail_msg: "The registration does not carry the configured handshake values" + success_msg: "The registration carries the configured handshake values" + + - name: Check for an entrypoint-generated registration in the writable data path + ansible.builtin.stat: + path: "{{ matrix_bridge_steam_data_path }}/registration.yaml" + register: matrix_bridge_steam_generated_registration + + - name: Assert the image entrypoint did not generate a second registration + ansible.builtin.assert: + that: + - not matrix_bridge_steam_generated_registration.stat.exists + fail_msg: >- + The image generated a second registration under the writable data path instead + of consuming the role-rendered registration mounted under /app/config + success_msg: "The image consumes the role-rendered registration without generating another" + + - name: Assert the registration namespaces cover only Steam ghosts and the bridge bot + ansible.builtin.assert: + that: + - matrix_bridge_steam_ghost_regex | length > 0 + - matrix_bridge_steam_bot_regex | length > 0 + - matrix_bridge_steam_ghost_mxid is match(matrix_bridge_steam_ghost_regex) + - matrix_bridge_steam_wrong_ghost_mxid is not match(matrix_bridge_steam_ghost_regex) + - matrix_bridge_steam_bot_mxid is match(matrix_bridge_steam_bot_regex) + fail_msg: "The registration namespaces do not cover only Steam ghosts and the bot" + success_msg: "The registration namespaces cover only Steam ghosts and the bot" + vars: + matrix_bridge_steam_user_regexes: "{{ matrix_bridge_steam_registration.namespaces.users | map(attribute='regex') | list }}" + matrix_bridge_steam_ghost_regex: "{{ matrix_bridge_steam_user_regexes | select('search', 'steam_') | first | default('') }}" + matrix_bridge_steam_bot_regex: "{{ matrix_bridge_steam_user_regexes | reject('search', 'steam_') | first | default('') }}" + matrix_bridge_steam_ghost_mxid: "@steam_76561198000000000:{{ matrix_bridge_steam_homeserver_domain }}" + matrix_bridge_steam_wrong_ghost_mxid: "@discord_76561198000000000:{{ matrix_bridge_steam_homeserver_domain }}" + matrix_bridge_steam_bot_mxid: "@{{ matrix_bridge_steam_appservice_bot_username }}:{{ matrix_bridge_steam_homeserver_domain }}" + + # Tables can appear only after DNS resolution, authentication and real migrations. + - name: List the tables the bridge created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_bridge_steam_database_username }} + - --dbname={{ matrix_bridge_steam_database_name }} + - --tuples-only + - --no-align + - "--command=SELECT tablename FROM pg_tables WHERE schemaname = 'public'" + register: matrix_bridge_steam_tables + changed_when: false + + - name: Assert the bridge migrated its schema into the configured database + ansible.builtin.assert: + that: + - matrix_bridge_steam_tables.rc == 0 + - "'version' in matrix_bridge_steam_table_names" + - "'portal' in matrix_bridge_steam_table_names" + - "'message' in matrix_bridge_steam_table_names" + - matrix_bridge_steam_table_names | length > 8 + fail_msg: >- + The bridge did not migrate its schema into {{ matrix_bridge_steam_database_name }} + (found {{ matrix_bridge_steam_table_names | length }} table(s): {{ matrix_bridge_steam_table_names | join(', ') }}) + success_msg: "The bridge migrated its schema into the configured database" + vars: + matrix_bridge_steam_table_names: "{{ matrix_bridge_steam_tables.stdout_lines | select | list }}" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_bridge_steam_base_path }}/labels" + register: matrix_bridge_steam_labels_file + + - name: Assert the labels route the exposed API to the configured appservice port + ansible.builtin.assert: + that: + - "'traefik.enable=true' in matrix_bridge_steam_labels_rendered" + - "'traefik.docker.network=' + matrix_bridge_steam_container_network in matrix_bridge_steam_labels_rendered" + - "'traefik.http.services.matrix-steam-bridge.loadbalancer.server.port=8766' in matrix_bridge_steam_labels_rendered" + - "'traefik.http.routers.matrix-steam-bridge-exposure.rule=Host(`steam-api.molecule.local`) && PathPrefix(`/bridges/steam-api`)' in matrix_bridge_steam_labels_rendered" + - "'traefik.http.middlewares.matrix-steam-bridge-exposure-strip-prefix.stripprefix.prefixes=/bridges/steam-api' in matrix_bridge_steam_labels_rendered" + - "'traefik.http.routers.matrix-steam-bridge-exposure.entrypoints=web' in matrix_bridge_steam_labels_rendered" + - "'traefik.http.routers.matrix-steam-bridge-exposure.tls=false' in matrix_bridge_steam_labels_rendered" + - "'matrix-steam-bridge-public-media' not in matrix_bridge_steam_labels_rendered" + - "'molecule.steam.coverage=enabled' in matrix_bridge_steam_labels_rendered" + fail_msg: "The rendered labels do not carry the scenario's exposure contract" + success_msg: "The rendered labels carry the scenario's exposure contract" + + - name: Inspect the running Steam bridge container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-steam-bridge + register: matrix_bridge_steam_container_inspect + changed_when: false + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - matrix_bridge_steam_runtime.Config.Image == matrix_bridge_steam_expected_image + fail_msg: >- + The running container uses {{ matrix_bridge_steam_runtime.Config.Image }}, expected + {{ matrix_bridge_steam_expected_image }} + success_msg: "The running container uses the exact image pinned by the role" + vars: + matrix_bridge_steam_expected_image: >- + {{ matrix_bridge_steam_role_defaults.matrix_bridge_steam_container_image_registry_prefix_upstream_default }}jasonlaguidice/matrix-steam-bridge:{{ matrix_bridge_steam_role_defaults.matrix_bridge_steam_version }} + + - name: Assert the running container uses the playbook-supplied runtime + ansible.builtin.assert: + that: + - matrix_bridge_steam_runtime.Config.User == (matrix_user_uid | string) ~ ':' ~ (matrix_user_gid | string) + - matrix_bridge_steam_runtime.Config.Entrypoint == ['/app/entrypoint.sh'] + - matrix_bridge_steam_runtime.Config.Cmd == ['-r', '/app/config/registration.yaml', '--no-update'] + - matrix_bridge_steam_runtime.Config.WorkingDir == '/app' + - "'CONFIG_FILE=/app/config/config.yaml' in matrix_bridge_steam_runtime.Config.Env" + - "'REGISTRATION_FILE=/app/config/registration.yaml' in matrix_bridge_steam_runtime.Config.Env" + - matrix_bridge_steam_runtime.HostConfig.RestartPolicy.Name == 'no' + - matrix_bridge_steam_runtime.HostConfig.AutoRemove is sameas true + - matrix_bridge_steam_runtime.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container does not use the image entrypoint with the role's exact registration and lifecycle contract" + success_msg: "The running container uses the image entrypoint with the role's exact registration and lifecycle contract" + + - name: Assert the running container has the intended privilege isolation + ansible.builtin.assert: + that: + - matrix_bridge_steam_runtime.HostConfig.Privileged is sameas false + - matrix_bridge_steam_runtime.HostConfig.CapAdd | default([], true) | length == 0 + - matrix_bridge_steam_runtime.HostConfig.CapDrop == ['ALL'] + fail_msg: "The running container does not have the intended privilege isolation" + success_msg: "The running container drops all capabilities and is unprivileged" + + - name: Assert the running container carries the exact config and data mounts + ansible.builtin.assert: + that: + - matrix_bridge_steam_config_mount | length > 0 + - matrix_bridge_steam_config_mount.Source == matrix_bridge_steam_config_path + - not matrix_bridge_steam_config_mount.RW + - matrix_bridge_steam_data_mount | length > 0 + - matrix_bridge_steam_data_mount.Source == matrix_bridge_steam_data_path + - matrix_bridge_steam_data_mount.RW + - matrix_bridge_steam_logs_mount | length > 0 + - matrix_bridge_steam_logs_mount.Type == 'volume' + - matrix_bridge_steam_logs_mount.RW + - matrix_bridge_steam_runtime.Mounts | length == 3 + fail_msg: "The running container does not carry the expected role and upstream image mounts" + success_msg: "The running container carries read-only config, writable data, and the upstream logs volume" + vars: + matrix_bridge_steam_config_mount: >- + {{ matrix_bridge_steam_runtime.Mounts + | selectattr('Destination', 'equalto', '/app/config') + | first | default({}) }} + matrix_bridge_steam_data_mount: >- + {{ matrix_bridge_steam_runtime.Mounts + | selectattr('Destination', 'equalto', '/app/data') + | first | default({}) }} + matrix_bridge_steam_logs_mount: >- + {{ matrix_bridge_steam_runtime.Mounts + | selectattr('Destination', 'equalto', '/app/logs') + | first | default({}) }} + + - name: Assert the rendered and extra labels reached the running container + ansible.builtin.assert: + that: + - matrix_bridge_steam_runtime.Config.Labels['traefik.enable'] == 'true' + - matrix_bridge_steam_runtime.Config.Labels['traefik.docker.network'] == matrix_bridge_steam_container_network + - matrix_bridge_steam_runtime.Config.Labels['traefik.http.services.matrix-steam-bridge.loadbalancer.server.port'] == '8766' + - matrix_bridge_steam_runtime.Config.Labels['molecule.steam.coverage'] == 'enabled' + - matrix_bridge_steam_runtime.Config.Labels['molecule.steam.extra-argument'] == 'reached' + fail_msg: "The running container does not carry the labels the role rendered and passed" + success_msg: "The configured labels reached the running container" + + - name: Assert the running container has the exact network and port exposure + ansible.builtin.assert: + that: + - matrix_bridge_steam_runtime.HostConfig.NetworkMode == matrix_bridge_steam_container_network + - matrix_bridge_steam_container_network in matrix_bridge_steam_runtime.NetworkSettings.Networks + - matrix_bridge_steam_runtime.NetworkSettings.Networks | length == 1 + - matrix_bridge_steam_runtime.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: >- + The container has unexpected networks or host ports: + networks={{ matrix_bridge_steam_runtime.NetworkSettings.Networks.keys() | list }}, + ports={{ matrix_bridge_steam_runtime.HostConfig.PortBindings | default({}) }} + success_msg: "The container uses only its dedicated network and publishes no host ports" + + - name: Assert the observable extra runtime argument reached Docker + ansible.builtin.assert: + that: + - matrix_bridge_steam_runtime.Config.Hostname == 'steam-bridge-molecule-runtime' + fail_msg: "The configured container hostname extra argument did not reach Docker" + success_msg: "The configured container extra argument reached Docker" diff --git a/roles/custom/matrix-bridge-steam/tasks/main.yml b/roles/custom/matrix-bridge-steam/tasks/main.yml index fc28fb7d3..8ea70730c 100644 --- a/roles/custom/matrix-bridge-steam/tasks/main.yml +++ b/roles/custom/matrix-bridge-steam/tasks/main.yml @@ -10,15 +10,15 @@ - install-all - install-matrix-steam-bridge block: - - when: matrix_steam_bridge_enabled | bool + - when: matrix_bridge_steam_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_steam_bridge_enabled | bool + - when: matrix_bridge_steam_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - setup-matrix-steam-bridge block: - - when: not matrix_steam_bridge_enabled | bool + - when: not matrix_bridge_steam_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-bridge-steam/tasks/setup_install.yml b/roles/custom/matrix-bridge-steam/tasks/setup_install.yml index 6905582da..33c8de1fa 100644 --- a/roles/custom/matrix-bridge-steam/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-steam/tasks/setup_install.yml @@ -5,19 +5,17 @@ --- - ansible.builtin.set_fact: - matrix_steam_bridge_migration_requires_restart: false + matrix_bridge_steam_migration_requires_restart: false - name: Ensure Steam bridge image is pulled - community.docker.docker_image: - name: "{{ matrix_steam_bridge_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_steam_bridge_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_steam_bridge_container_image_force_pull }}" - when: matrix_steam_bridge_enabled | bool and not matrix_steam_bridge_container_image_self_build - register: matrix_steam_bridge_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_steam_container_image }}" + pull: always + when: matrix_bridge_steam_enabled | bool and not matrix_bridge_steam_container_image_self_build + register: matrix_bridge_steam_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_steam_bridge_container_image_pull_result is not failed + until: matrix_bridge_steam_container_image_pull_result is not failed - name: Ensure Steam bridge paths exist ansible.builtin.file: @@ -27,67 +25,77 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_steam_bridge_base_path }}", when: true} - - {path: "{{ matrix_steam_bridge_config_path }}", when: true} - - {path: "{{ matrix_steam_bridge_data_path }}", when: true} - - {path: "{{ matrix_steam_bridge_container_src_files_path }}", when: "{{ matrix_steam_bridge_container_image_self_build }}"} + - {path: "{{ matrix_bridge_steam_base_path }}", when: true} + - {path: "{{ matrix_bridge_steam_config_path }}", when: true} + - {path: "{{ matrix_bridge_steam_data_path }}", when: true} + - {path: "{{ matrix_bridge_steam_container_src_files_path }}", when: "{{ matrix_bridge_steam_container_image_self_build }}"} when: item.when | bool +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Steam bridge repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_steam_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_bridge_steam_enabled | bool and matrix_bridge_steam_container_image_self_build" + - name: Ensure Steam bridge repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_steam_bridge_container_image_self_build_repo }}" - version: "{{ matrix_steam_bridge_container_image_self_build_repo_version }}" - dest: "{{ matrix_steam_bridge_container_src_files_path }}" + repo: "{{ matrix_bridge_steam_container_image_self_build_repo }}" + version: "{{ matrix_bridge_steam_container_image_self_build_repo_version }}" + dest: "{{ matrix_bridge_steam_container_src_files_path }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_steam_bridge_git_pull_results - when: "matrix_steam_bridge_enabled | bool and matrix_steam_bridge_container_image_self_build" + register: matrix_bridge_steam_git_pull_results + when: "matrix_bridge_steam_enabled | bool and matrix_bridge_steam_container_image_self_build" - name: Ensure Steam bridge Docker image is built - community.docker.docker_image: - name: "{{ matrix_steam_bridge_container_image }}" - source: build - force_source: "{{ matrix_steam_bridge_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_steam_bridge_container_src_files_path }}" - pull: true - when: "matrix_steam_bridge_enabled | bool and matrix_steam_bridge_container_image_self_build | bool" + community.docker.docker_image_build: + name: "{{ matrix_bridge_steam_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_steam_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_steam_git_pull_results.changed | bool else 'never' }}" + when: "matrix_bridge_steam_enabled | bool and matrix_bridge_steam_container_image_self_build | bool" + register: matrix_bridge_steam_container_image_build_result - name: Ensure matrix-steam-bridge config.yaml installed ansible.builtin.copy: - content: "{{ matrix_steam_bridge_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_steam_bridge_config_path }}/config.yaml" + content: "{{ matrix_bridge_steam_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_steam_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_steam_bridge_config_result + register: matrix_bridge_steam_config_result - name: Ensure matrix-steam-bridge registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_steam_bridge_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_steam_bridge_config_path }}/registration.yaml" + content: "{{ matrix_bridge_steam_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_steam_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_steam_bridge_registration_result + register: matrix_bridge_steam_registration_result - name: Ensure matrix-steam-bridge support files installed ansible.builtin.template: src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_steam_bridge_base_path }}/{{ item }}" + dest: "{{ matrix_bridge_steam_base_path }}/{{ item }}" mode: '0640' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - labels - register: matrix_steam_bridge_support_files_result + register: matrix_bridge_steam_support_files_result - name: Ensure matrix-steam-bridge container network is created + when: matrix_bridge_steam_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_steam_bridge_container_network }}" + name: "{{ matrix_bridge_steam_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -96,18 +104,19 @@ src: "{{ role_path }}/templates/systemd/matrix-steam-bridge.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-steam-bridge.service" mode: '0644' - register: matrix_steam_bridge_systemd_service_result + register: matrix_bridge_steam_systemd_service_result - name: Determine whether matrix-steam-bridge needs a restart ansible.builtin.set_fact: - matrix_steam_bridge_restart_necessary: >- + matrix_bridge_steam_restart_necessary: >- {{ - matrix_steam_bridge_migration_requires_restart | default(false) - or matrix_steam_bridge_config_result.changed | default(false) - or matrix_steam_bridge_registration_result.changed | default(false) - or matrix_steam_bridge_support_files_result.changed | default(false) - or matrix_steam_bridge_systemd_service_result.changed | default(false) - or matrix_steam_bridge_container_image_pull_result.changed | default(false) + matrix_bridge_steam_migration_requires_restart | default(false) + or matrix_bridge_steam_config_result.changed | default(false) + or matrix_bridge_steam_registration_result.changed | default(false) + or matrix_bridge_steam_support_files_result.changed | default(false) + or matrix_bridge_steam_systemd_service_result.changed | default(false) + or matrix_bridge_steam_container_image_pull_result.changed | default(false) + or matrix_bridge_steam_container_image_build_result.changed | default(false) }} - name: Ensure matrix-steam-bridge.service restarted, if necessary @@ -115,4 +124,4 @@ name: "matrix-steam-bridge.service" state: restarted daemon_reload: true - when: "matrix_steam_bridge_migration_requires_restart | bool" + when: "matrix_bridge_steam_migration_requires_restart | bool" diff --git a/roles/custom/matrix-bridge-steam/tasks/setup_uninstall.yml b/roles/custom/matrix-bridge-steam/tasks/setup_uninstall.yml index 361be0420..a47a47e3e 100644 --- a/roles/custom/matrix-bridge-steam/tasks/setup_uninstall.yml +++ b/roles/custom/matrix-bridge-steam/tasks/setup_uninstall.yml @@ -7,9 +7,9 @@ - name: Check existence of matrix-steam-bridge service ansible.builtin.stat: path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-steam-bridge.service" - register: matrix_steam_bridge_service_stat + register: matrix_bridge_steam_service_stat -- when: matrix_steam_bridge_service_stat.stat.exists | bool +- when: matrix_bridge_steam_service_stat.stat.exists | bool block: - name: Ensure matrix-steam-bridge is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-steam/tasks/validate_config.yml b/roles/custom/matrix-bridge-steam/tasks/validate_config.yml index 8ea0b8236..b3e2db974 100644 --- a/roles/custom/matrix-bridge-steam/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-steam/tasks/validate_config.yml @@ -11,26 +11,37 @@ Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_steam_bridge_docker_image_name_prefix', 'new': 'matrix_steam_bridge_container_image_registry_prefix'} - - {'old': 'matrix_steam_bridge_docker_image', 'new': 'matrix_steam_bridge_container_image'} - - {'old': 'matrix_steam_bridge_docker_image_force_pull', 'new': 'matrix_steam_bridge_container_image_force_pull'} - - {'old': 'matrix_steam_bridge_docker_image_registry_prefix', 'new': 'matrix_steam_bridge_container_image_registry_prefix'} - - {'old': 'matrix_steam_bridge_docker_image_registry_prefix_upstream', 'new': 'matrix_steam_bridge_container_image_registry_prefix_upstream'} - - {'old': 'matrix_steam_bridge_docker_image_registry_prefix_upstream_default', 'new': 'matrix_steam_bridge_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_steam_bridge_docker_image_tag', 'new': 'matrix_steam_bridge_container_image_tag'} - - {'old': 'matrix_steam_bridge_docker_src_files_path', 'new': 'matrix_steam_bridge_container_src_files_path'} + - {'old': 'matrix_bridge_steam_docker_image_name_prefix', 'new': 'matrix_bridge_steam_container_image_registry_prefix'} + - {'old': 'matrix_bridge_steam_docker_image', 'new': 'matrix_bridge_steam_container_image'} + - {'old': 'matrix_bridge_steam_docker_image_force_pull', 'new': 'matrix_bridge_steam_container_image_force_pull'} + - {'old': 'matrix_bridge_steam_docker_image_registry_prefix', 'new': 'matrix_bridge_steam_container_image_registry_prefix'} + - {'old': 'matrix_bridge_steam_docker_image_registry_prefix_upstream', 'new': 'matrix_bridge_steam_container_image_registry_prefix_upstream'} + - {'old': 'matrix_bridge_steam_docker_image_registry_prefix_upstream_default', 'new': 'matrix_bridge_steam_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_bridge_steam_docker_image_tag', 'new': 'matrix_bridge_steam_container_image_tag'} + - {'old': 'matrix_bridge_steam_docker_src_files_path', 'new': 'matrix_bridge_steam_container_src_files_path'} + - {'old': 'matrix_bridge_steam_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_steam_metrics_enabled', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_metrics_proxying_enabled', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_metrics_proxying_hostname', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_metrics_proxying_path_prefix', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_container_labels_metrics_enabled', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_container_labels_metrics_traefik_rule', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_container_labels_metrics_traefik_priority', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_container_labels_metrics_traefik_entrypoints', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_container_labels_metrics_traefik_tls', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_container_labels_metrics_traefik_tls_certResolver', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_container_labels_metrics_middleware_basic_auth_enabled', 'new': ' (the Steam bridge does not support metrics)'} + - {'old': 'matrix_bridge_steam_container_labels_metrics_middleware_basic_auth_users', 'new': ' (the Steam bridge does not support metrics)'} -- name: Fail if required matrix_steam_bridge settings not defined +- name: Fail if required matrix_bridge_steam settings not defined ansible.builtin.fail: msg: >- You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_steam_bridge_appservice_token', when: true} - - {'name': 'matrix_steam_bridge_homeserver_address', when: true} - - {'name': 'matrix_steam_bridge_homeserver_token', when: true} - - {'name': 'matrix_steam_bridge_database_hostname', when: "{{ matrix_steam_bridge_database_engine == 'postgres' }}"} - - {'name': 'matrix_steam_bridge_container_network', when: true} - - {'name': 'matrix_steam_bridge_metrics_proxying_hostname', when: "{{ matrix_steam_bridge_metrics_proxying_enabled }}"} - - {'name': 'matrix_steam_bridge_metrics_proxying_path_prefix', when: "{{ matrix_steam_bridge_metrics_proxying_enabled }}"} + - {'name': 'matrix_bridge_steam_appservice_token', when: true} + - {'name': 'matrix_bridge_steam_homeserver_address', when: true} + - {'name': 'matrix_bridge_steam_homeserver_token', when: true} + - {'name': 'matrix_bridge_steam_database_hostname', when: "{{ matrix_bridge_steam_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_steam_container_network', when: true} # TODO: Confirm additional config isn't mandatory for public_media diff --git a/roles/custom/matrix-bridge-steam/templates/config.yaml.j2 b/roles/custom/matrix-bridge-steam/templates/config.yaml.j2 index 3704a6523..1df813e0b 100644 --- a/roles/custom/matrix-bridge-steam/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-steam/templates/config.yaml.j2 @@ -7,7 +7,7 @@ network: get_proxy_url: null # Displayname template for Steam users. - displayname_template: {{ matrix_steam_bridge_network_displayname_template | to_json }} + displayname_template: {{ matrix_bridge_steam_network_displayname_template | to_json }} # Maximum number of conversations to sync on startup conversation_sync_limit: 20 @@ -22,7 +22,7 @@ network: # Enable presence tracking from Matrix to Steam # When enabled, your Steam status will automatically change based on # your Matrix presence and activity - enabled: {{ matrix_steam_bridge_network_presence_enabled | to_json }} + enabled: {{ matrix_bridge_steam_network_presence_enabled | to_json }} # Inactivity timeout in minutes before changing Steam status # This is used as a fallback when your Matrix server doesn't support @@ -33,7 +33,7 @@ network: # Status to set after inactivity timeout # Valid values: "snooze" (appear away/idle) or "invisible" (appear offline) - inactivity_status: {{ matrix_steam_bridge_network_presence_inactivity_status | to_json }} + inactivity_status: {{ matrix_bridge_steam_network_presence_inactivity_status | to_json }} # Whether typing events in Matrix should reset the inactivity timer # When true, typing will count as activity and keep you marked as online typing_resets_presence: true @@ -42,11 +42,21 @@ network: # When true, reading messages will count as activity and keep you marked as online read_receipts_reset_presence: false + # Presence topic settings + # Sets a Steam friend's current game (+ rich presence flavor text) as the DM room's m.room.topic. + presence_topic: + # Master switch for setting the DM room topic to the friend's current game + enabled: {{ matrix_bridge_steam_network_presence_topic_enabled | to_json }} + # Append resolved rich presence flavor text to the topic (e.g. "Deadlock — Street Brawl: Paige (12 min)") + rich_presence_enabled: {{ matrix_bridge_steam_network_presence_topic_rich_presence_enabled | to_json }} + # Fallback: show the raw unresolved rich presence token if resolution fails + show_raw_tokens: {{ matrix_bridge_steam_network_presence_topic_show_raw_tokens | to_json }} + # Config options that affect the central bridge module. bridge: # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_steam_bridge_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_steam_command_prefix | to_json }} # Should the bridge create a space for each login containing the rooms that account is in? personal_filtering_spaces: true # Whether the bridge should set names and avatars explicitly for DM portals. @@ -60,7 +70,7 @@ bridge: # By default, users who are in the same group on the remote network will be # in the same Matrix room bridged to that group. If this is set to true, # every user will get their own Matrix room instead. - split_portals: {{ matrix_steam_bridge_bridge_split_portals | to_json }} + split_portals: {{ matrix_bridge_steam_bridge_split_portals | to_json }} # Should the bridge resend `m.bridge` events to all portals on startup? resend_bridge_info: false # Should `m.bridge` events be sent without a state key? @@ -99,24 +109,24 @@ bridge: # delete - Remove all ghosts and users from the room (i.e. delete it) cleanup_on_logout: # Should cleanup on logout be enabled at all? - enabled: {{ matrix_steam_bridge_bridge_cleanup_on_logout_enabled | to_json }} + enabled: {{ matrix_bridge_steam_bridge_cleanup_on_logout_enabled | to_json }} # Settings for manual logouts (explicitly initiated by the Matrix user) manual: # Action for private portals which will never be shared with other Matrix users. - private: {{ matrix_steam_bridge_bridge_cleanup_on_logout_manual_private | to_json }} + private: {{ matrix_bridge_steam_bridge_cleanup_on_logout_manual_private | to_json }} # Action for portals with a relay user configured. - relayed: {{ matrix_steam_bridge_bridge_cleanup_on_logout_manual_relayed | to_json }} + relayed: {{ matrix_bridge_steam_bridge_cleanup_on_logout_manual_relayed | to_json }} # Action for portals which may be shared, but don't currently have any other Matrix users. - shared_no_users: {{ matrix_steam_bridge_bridge_cleanup_on_logout_manual_shared_no_users | to_json }} + shared_no_users: {{ matrix_bridge_steam_bridge_cleanup_on_logout_manual_shared_no_users | to_json }} # Action for portals which have other logged-in Matrix users. - shared_has_users: {{ matrix_steam_bridge_bridge_cleanup_on_logout_manual_shared_has_users | to_json }} + shared_has_users: {{ matrix_bridge_steam_bridge_cleanup_on_logout_manual_shared_has_users | to_json }} # Settings for credentials being invalidated (initiated by the remote network, possibly through user action). # Keys have the same meanings as in the manual section. bad_credentials: - private: {{ matrix_steam_bridge_bridge_cleanup_on_logout_bad_credentials_private | to_json }} - relayed: {{ matrix_steam_bridge_bridge_cleanup_on_logout_bad_credentials_relayed | to_json }} - shared_no_users: {{ matrix_steam_bridge_bridge_cleanup_on_logout_bad_credentials_shared_no_users | to_json }} - shared_has_users: {{ matrix_steam_bridge_bridge_cleanup_on_logout_bad_credentials_shared_has_users | to_json }} + private: {{ matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_private | to_json }} + relayed: {{ matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_relayed | to_json }} + shared_no_users: {{ matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_shared_no_users | to_json }} + shared_has_users: {{ matrix_bridge_steam_bridge_cleanup_on_logout_bad_credentials_shared_has_users | to_json }} # Settings for relay mode relay: @@ -163,7 +173,7 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_steam_bridge_bridge_permissions | to_json }} + permissions: {{ matrix_bridge_steam_bridge_permissions | to_json }} # Config for the bridge's database. database: @@ -174,7 +184,7 @@ database: # https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_steam_bridge_database_uri | to_json }} + uri: {{ matrix_bridge_steam_database_uri | to_json }} # Maximum number of connections. max_open_conns: 5 max_idle_conns: 2 @@ -188,9 +198,9 @@ homeserver: # The address that this appservice can use to connect to the homeserver. # Local addresses without HTTPS are generally recommended when the bridge is running on the same machine, # but https also works if they run on different machines. - address: {{ matrix_steam_bridge_homeserver_address | to_json }} + address: {{ matrix_bridge_steam_homeserver_address | to_json }} # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: {{ matrix_steam_bridge_homeserver_domain | to_json }} + domain: {{ matrix_bridge_steam_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -206,7 +216,7 @@ homeserver: # The bridge will use the appservice as_token to authorize requests. message_send_checkpoint_endpoint: # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_steam_bridge_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_steam_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -222,27 +232,27 @@ appservice: # Like the homeserver address, a local non-https address is recommended when the bridge is on the same machine. # If the bridge is elsewhere, you must secure the connection yourself (e.g. with https or wireguard) # If you want to use https, you need to use a reverse proxy. The bridge does not have TLS support built in. - address: {{ matrix_steam_bridge_appservice_address | to_json }} + address: {{ matrix_bridge_steam_appservice_address | to_json }} # A public address that external services can use to reach this appservice. # This is only needed for things like public media. A reverse proxy is generally necessary when using this field. # This value doesn't affect the registration file. - public_address: {{ matrix_steam_bridge_appservice_public_address | to_json }} + public_address: {{ matrix_bridge_steam_appservice_public_address | to_json }} # The hostname and port where this appservice should listen. # For Docker, you generally have to change the hostname to 0.0.0.0. hostname: 0.0.0.0 - port: {{ matrix_steam_bridge_appservice_port }} + port: {{ matrix_bridge_steam_appservice_port }} # The unique ID of this appservice. id: steam # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_steam_bridge_appservice_bot_username | to_json }} + username: {{ matrix_bridge_steam_appservice_bot_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. - displayname: {{ matrix_steam_bridge_appservice_bot_displayname | to_json(ensure_ascii=False) }} - avatar: {{ matrix_steam_bridge_appservice_bot_avatar | to_json }} + displayname: {{ matrix_bridge_steam_appservice_bot_displayname | to_json(ensure_ascii=False) }} + avatar: {{ matrix_bridge_steam_appservice_bot_avatar | to_json }} # Whether to receive ephemeral events via appservice transactions. ephemeral_events: true @@ -253,8 +263,8 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_steam_bridge_appservice_token | to_json }} - hs_token: {{ matrix_steam_bridge_homeserver_token | to_json }} + as_token: {{ matrix_bridge_steam_appservice_token | to_json }} + hs_token: {{ matrix_bridge_steam_homeserver_token | to_json }} # Localpart template of MXIDs for remote users. # {% raw %}{{.}}{% endraw %} is replaced with the internal ID of the user. @@ -272,7 +282,7 @@ matrix: sync_direct_chat_list: true # Whether created rooms should have federation enabled. If false, created portal rooms # will never be federated. Changing this option requires recreating rooms. - federate_rooms: {{ matrix_steam_bridge_matrix_federate_rooms | to_json }} + federate_rooms: {{ matrix_bridge_steam_matrix_federate_rooms | to_json }} # The threshold as bytes after which the bridge should roundtrip uploads via the disk # rather than keeping the whole file in memory. upload_file_threshold: 5242880 @@ -292,7 +302,7 @@ provisioning: prefix: /_matrix/provision # Shared secret for authentication. If set to "generate" or null, a random secret will be generated, # or if set to "disable", the provisioning API will be disabled. - shared_secret: {{ matrix_steam_bridge_provisioning_shared_secret | to_json }} + shared_secret: {{ matrix_bridge_steam_provisioning_shared_secret | to_json }} # Whether to allow provisioning API requests to be authed using Matrix access tokens. # This follows the same rules as double puppeting to determine which server to contact to check the token, # which means that by default, it only works for users on the same server as the bridge. @@ -306,15 +316,15 @@ provisioning: public_media: # Should public media be enabled at all? # The public_address field under the appservice section MUST be set when enabling public media. - enabled: {{ matrix_steam_bridge_public_media_enabled | to_json }} + enabled: {{ matrix_bridge_steam_public_media_enabled | to_json }} # A key for signing public media URLs. # If set to "generate", a random key will be generated. - signing_key: {{ matrix_steam_bridge_public_media_signing_key | to_json }} + signing_key: {{ matrix_bridge_steam_public_media_signing_key | to_json }} # Number of seconds that public media URLs are valid for. # If set to 0, URLs will never expire. - expiry: {{ matrix_steam_bridge_public_media_expiry | to_json }} + expiry: {{ matrix_bridge_steam_public_media_expiry | to_json }} # Length of hash to use for public media URLs. Must be between 0 and 32. - hash_length: {{ matrix_steam_bridge_public_media_hash_length | to_json }} + hash_length: {{ matrix_bridge_steam_public_media_hash_length | to_json }} # Settings for converting remote media to custom mxc:// URIs instead of reuploading. # More details can be found at https://docs.mau.fi/bridges/go/discord/direct-media.html @@ -343,11 +353,11 @@ direct_media: # See https://docs.mau.fi/bridges/general/backfill.html for more details. backfill: # Whether to do backfilling at all. - enabled: {{ matrix_steam_bridge_backfill_enabled | to_json }} + enabled: {{ matrix_bridge_steam_backfill_enabled | to_json }} # Maximum number of messages to backfill in empty rooms. - max_initial_messages: {{ matrix_steam_bridge_backfill_max_initial_messages | to_json }} + max_initial_messages: {{ matrix_bridge_steam_backfill_max_initial_messages | to_json }} # Maximum number of missed messages to backfill after bridge restarts. - max_catchup_messages: {{ matrix_steam_bridge_backfill_max_catchup_messages | to_json }} + max_catchup_messages: {{ matrix_bridge_steam_backfill_max_catchup_messages | to_json }} # If a backfilled chat is older than this number of hours, # mark it as read even if it's unread on the remote network. unread_hours_threshold: 720 @@ -382,35 +392,35 @@ double_puppet: allow_discovery: false # Shared secrets for automatic double puppeting. # See https://docs.mau.fi/bridges/general/double-puppeting.html for instructions. - secrets: {{ matrix_steam_bridge_double_puppet_secrets | to_json }} + secrets: {{ matrix_bridge_steam_double_puppet_secrets | to_json }} # End-to-bridge encryption support options. # # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. - allow: {{ matrix_steam_bridge_bridge_encryption_allow | to_json }} + allow: {{ matrix_bridge_steam_bridge_encryption_allow | to_json }} # Whether to force-enable encryption in all bridged rooms. - default: {{ matrix_steam_bridge_bridge_encryption_default | to_json }} + default: {{ matrix_bridge_steam_bridge_encryption_default | to_json }} # Whether to require all messages to be encrypted and drop any unencrypted messages. - require: {{ matrix_steam_bridge_bridge_encryption_require | to_json }} + require: {{ matrix_bridge_steam_bridge_encryption_require | to_json }} # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. # This option is not yet compatible with standard Matrix servers like Synapse and should not be used. - appservice: {{ matrix_steam_bridge_bridge_encryption_appservice | to_json }} + appservice: {{ matrix_bridge_steam_bridge_encryption_appservice | to_json }} # Whether to use MSC4190 instead of appservice login to create the bridge bot device. # Requires the homeserver to support MSC4190 and the device masquerading parts of MSC3202. # Only relevant when using end-to-bridge encryption, required when using encryption with next-gen auth (MSC3861). # Changing this option requires updating the appservice registration file. - msc4190: {{ matrix_steam_bridge_msc4190_enabled | to_json }} + msc4190: {{ matrix_bridge_steam_msc4190_enabled | to_json }} # Whether to enable self-signing for bridges (Only the bridge bot uses this for now) # Requires msc4190 to replace keys on reset - self_sign: {{ matrix_steam_bridge_self_sign_enabled | to_json }} + self_sign: {{ matrix_bridge_steam_self_sign_enabled | to_json }} # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: {{ matrix_steam_bridge_bridge_encryption_key_sharing_allow | to_json }} + allow_key_sharing: {{ matrix_bridge_steam_bridge_encryption_key_sharing_allow | to_json }} # Pickle key for encrypting encryption keys in the bridge database. # If set to generate, a random key will be generated. - pickle_key: {{ matrix_steam_bridge_bridge_encryption_pickle_key | to_json }} + pickle_key: {{ matrix_bridge_steam_bridge_encryption_pickle_key | to_json }} # Options for deleting megolm sessions from the bridge. delete_keys: # Beeper-specific: delete outbound sessions when hungryserv confirms @@ -469,7 +479,7 @@ encryption: # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_steam_bridge_logging_level | to_json }} + min_level: {{ matrix_bridge_steam_logging_level | to_json }} writers: - type: stdout format: pretty-colored diff --git a/roles/custom/matrix-bridge-steam/templates/labels.j2 b/roles/custom/matrix-bridge-steam/templates/labels.j2 index 77fa05a4c..ff94dcfa3 100644 --- a/roles/custom/matrix-bridge-steam/templates/labels.j2 +++ b/roles/custom/matrix-bridge-steam/templates/labels.j2 @@ -4,70 +4,66 @@ SPDX-FileCopyrightText: 2025 MDAD project contributors SPDX-License-Identifier: AGPL-3.0-or-later #} -{% if matrix_steam_bridge_container_labels_traefik_enabled %} +{% if matrix_bridge_steam_container_labels_traefik_enabled %} traefik.enable=true -{% if matrix_steam_bridge_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_steam_bridge_container_labels_traefik_docker_network }} +{% if matrix_bridge_steam_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bridge_steam_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.matrix-steam-bridge.loadbalancer.server.port={{ matrix_steam_bridge_appservice_port }} -traefik.http.services.matrix-steam-bridge-metrics.loadbalancer.server.port=8000 +traefik.http.services.matrix-steam-bridge.loadbalancer.server.port={{ matrix_bridge_steam_appservice_port }} -{% if matrix_steam_bridge_container_labels_metrics_enabled %} +{% if matrix_bridge_steam_public_media_enabled %} ############################################################ # # -# Metrics # +# Public Media # # # ############################################################ -{% if matrix_steam_bridge_container_labels_metrics_middleware_basic_auth_enabled %} -traefik.http.middlewares.matrix-steam-bridge-metrics-basic-auth.basicauth.users={{ matrix_steam_bridge_container_labels_metrics_middleware_basic_auth_users }} -traefik.http.routers.matrix-steam-bridge-metrics.middlewares=matrix-steam-bridge-metrics-basic-auth -{% endif %} - -traefik.http.routers.matrix-steam-bridge-metrics.rule={{ matrix_steam_bridge_container_labels_metrics_traefik_rule }} - -{% if matrix_steam_bridge_container_labels_metrics_traefik_priority | int > 0 %} -traefik.http.routers.matrix-steam-bridge-metrics.priority={{ matrix_steam_bridge_container_labels_metrics_traefik_priority }} +# Router for public media +traefik.http.routers.matrix-steam-bridge-public-media.rule=Host(`{{ matrix_server_fqn_matrix }}`) && PathPrefix(`/_mautrix/publicmedia/{{ matrix_domain }}/`) +traefik.http.routers.matrix-steam-bridge-public-media.service=matrix-steam-bridge +traefik.http.routers.matrix-steam-bridge-public-media.entrypoints={{ matrix_bridge_steam_container_labels_traefik_entrypoints }} +traefik.http.routers.matrix-steam-bridge-public-media.tls={{ matrix_bridge_steam_container_labels_traefik_tls | to_json }} +{% if matrix_bridge_steam_container_labels_traefik_tls %} +traefik.http.routers.matrix-steam-bridge-public-media.tls.certResolver={{ matrix_bridge_steam_container_labels_traefik_tls_certResolver }} {% endif %} -traefik.http.routers.matrix-steam-bridge-metrics.service=matrix-steam-bridge-metrics -traefik.http.routers.matrix-steam-bridge-metrics.entrypoints={{ matrix_steam_bridge_container_labels_metrics_traefik_entrypoints }} - -traefik.http.routers.matrix-steam-bridge-metrics.tls={{ matrix_steam_bridge_container_labels_metrics_traefik_tls | to_json }} -{% if matrix_steam_bridge_container_labels_metrics_traefik_tls %} -traefik.http.routers.matrix-steam-bridge-metrics.tls.certResolver={{ matrix_steam_bridge_container_labels_metrics_traefik_tls_certResolver }} -{% endif %} ############################################################ # # -# /Metrics # +# /Public Media # # # ############################################################ {% endif %} - -{% if matrix_steam_bridge_public_media_enabled %} +{% if matrix_bridge_steam_container_labels_exposure_enabled %} ############################################################ # # -# Public Media # +# Bridge API exposure # # # ############################################################ -# Router for public media -traefik.http.routers.matrix-steam-bridge-public-media.rule=Host(`{{ matrix_server_fqn_matrix }}`) && PathPrefix(`/_mautrix/publicmedia/{{ matrix_domain }}/`) -traefik.http.routers.matrix-steam-bridge-public-media.service=matrix-steam-bridge -traefik.http.routers.matrix-steam-bridge-public-media.entrypoints={{ matrix_steam_bridge_container_labels_traefik_entrypoints }} -traefik.http.routers.matrix-steam-bridge-public-media.tls={{ matrix_steam_bridge_container_labels_traefik_tls | to_json }} -{% if matrix_steam_bridge_container_labels_traefik_tls %} -traefik.http.routers.matrix-steam-bridge-public-media.tls.certResolver={{ matrix_steam_bridge_container_labels_traefik_tls_certResolver }} +traefik.http.middlewares.matrix-steam-bridge-exposure-strip-prefix.stripprefix.prefixes={{ matrix_bridge_steam_exposure_path_prefix }} +traefik.http.routers.matrix-steam-bridge-exposure.middlewares=matrix-steam-bridge-exposure-strip-prefix + +traefik.http.routers.matrix-steam-bridge-exposure.rule={{ matrix_bridge_steam_container_labels_exposure_traefik_rule }} + +{% if matrix_bridge_steam_container_labels_exposure_traefik_priority | int > 0 %} +traefik.http.routers.matrix-steam-bridge-exposure.priority={{ matrix_bridge_steam_container_labels_exposure_traefik_priority }} {% endif %} +traefik.http.routers.matrix-steam-bridge-exposure.service=matrix-steam-bridge +traefik.http.routers.matrix-steam-bridge-exposure.entrypoints={{ matrix_bridge_steam_container_labels_exposure_traefik_entrypoints }} + +traefik.http.routers.matrix-steam-bridge-exposure.tls={{ matrix_bridge_steam_container_labels_exposure_traefik_tls | to_json }} +{% if matrix_bridge_steam_container_labels_exposure_traefik_tls %} +traefik.http.routers.matrix-steam-bridge-exposure.tls.certResolver={{ matrix_bridge_steam_container_labels_exposure_traefik_tls_certResolver }} +{% endif %} ############################################################ # # -# /Public Media # +# /Bridge API exposure # # # ############################################################ {% endif %} @@ -75,4 +71,4 @@ traefik.http.routers.matrix-steam-bridge-public-media.tls.certResolver={{ matrix {% endif %} -{{ matrix_steam_bridge_container_labels_additional_labels }} +{{ matrix_bridge_steam_container_labels_additional_labels }} diff --git a/roles/custom/matrix-bridge-steam/templates/systemd/matrix-steam-bridge.service.j2 b/roles/custom/matrix-bridge-steam/templates/systemd/matrix-steam-bridge.service.j2 index adfc9db9a..6a4e97dd4 100644 --- a/roles/custom/matrix-bridge-steam/templates/systemd/matrix-steam-bridge.service.j2 +++ b/roles/custom/matrix-bridge-steam/templates/systemd/matrix-steam-bridge.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix Steam bridge -{% for service in matrix_steam_bridge_systemd_required_services_list %} +{% for service in matrix_bridge_steam_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_steam_bridge_systemd_wanted_services_list %} +{% for service in matrix_bridge_steam_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,19 +22,22 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_steam_bridge_container_network }} \ - --mount type=bind,src={{ matrix_steam_bridge_config_path }},dst=/app/config,ro \ - --mount type=bind,src={{ matrix_steam_bridge_data_path }},dst=/app/data \ - --label-file={{ matrix_steam_bridge_base_path }}/labels \ - {% for arg in matrix_steam_bridge_container_extra_arguments %} + --network={{ matrix_bridge_steam_container_network }} \ + --mount type=bind,src={{ matrix_bridge_steam_config_path }},dst=/app/config,ro \ + --mount type=bind,src={{ matrix_bridge_steam_data_path }},dst=/app/data \ + --env=REGISTRATION_FILE=/app/config/registration.yaml \ + --label-file={{ matrix_bridge_steam_base_path }}/labels \ + {% for arg in matrix_bridge_steam_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_steam_bridge_container_image }} \ - /usr/bin/steam -c /app/config/config.yaml -r /app/config/registration.yaml --no-update + {{ matrix_bridge_steam_container_image }} \ + -r /app/config/registration.yaml --no-update -{% for network in matrix_steam_bridge_container_additional_networks %} +{% if matrix_bridge_steam_container_network != 'host' %} +{% for network in matrix_bridge_steam_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-steam-bridge {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-steam-bridge diff --git a/roles/custom/matrix-bridge-wechat/defaults/main.yml b/roles/custom/matrix-bridge-wechat/defaults/main.yml index 286843e08..b947a9bb5 100644 --- a/roles/custom/matrix-bridge-wechat/defaults/main.yml +++ b/roles/custom/matrix-bridge-wechat/defaults/main.yml @@ -8,163 +8,161 @@ # WeChat Bridge is a Matrix <-> WeChat bridge # Project source code URL: https://github.com/duo/matrix-wechat -matrix_wechat_enabled: true +matrix_bridge_wechat_enabled: true # renovate: datasource=docker depName=lxduo/matrix-wechat -matrix_wechat_version: 0.2.4 -matrix_wechat_container_image: "{{ matrix_wechat_container_image_registry_prefix }}lxduo/matrix-wechat:{{ matrix_wechat_version }}" -matrix_wechat_container_image_registry_prefix: "{{ 'localhost/' if matrix_wechat_container_image_self_build else matrix_wechat_container_image_registry_prefix_upstream }}" -matrix_wechat_container_image_registry_prefix_upstream: "{{ matrix_wechat_container_image_registry_prefix_upstream_default }}" -matrix_wechat_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_wechat_container_image_force_pull: "{{ matrix_wechat_container_image.endswith(':latest') }}" +matrix_bridge_wechat_version: 0.2.4 +matrix_bridge_wechat_container_image: "{{ matrix_bridge_wechat_container_image_registry_prefix }}lxduo/matrix-wechat:{{ matrix_bridge_wechat_version }}" +matrix_bridge_wechat_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_wechat_container_image_self_build else matrix_bridge_wechat_container_image_registry_prefix_upstream }}" +matrix_bridge_wechat_container_image_registry_prefix_upstream: "{{ matrix_bridge_wechat_container_image_registry_prefix_upstream_default }}" +matrix_bridge_wechat_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_wechat_container_image_self_build: false -matrix_wechat_container_image_self_build_repo: "https://github.com/duo/matrix-wechat.git" -matrix_wechat_container_image_self_build_branch: "{{ 'master' if matrix_wechat_version == 'latest' else matrix_wechat_version }}" +matrix_bridge_wechat_container_image_self_build: false +matrix_bridge_wechat_container_image_self_build_repo: "https://github.com/duo/matrix-wechat.git" +matrix_bridge_wechat_container_image_self_build_branch: "{{ 'master' if matrix_bridge_wechat_version == 'latest' else matrix_bridge_wechat_version }}" # renovate: datasource=docker depName=lxduo/matrix-wechat-agent -matrix_wechat_agent_version: 0.0.1 -matrix_wechat_agent_container_image: "{{ matrix_wechat_agent_container_image_registry_prefix }}lxduo/matrix-wechat-agent:{{ matrix_wechat_agent_version }}" -matrix_wechat_agent_container_image_registry_prefix: "{{ 'localhost/' if matrix_wechat_agent_container_image_self_build else matrix_wechat_agent_container_image_registry_prefix_upstream }}" -matrix_wechat_agent_container_image_registry_prefix_upstream: "{{ matrix_wechat_agent_container_image_registry_prefix_upstream_default }}" -matrix_wechat_agent_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_wechat_agent_container_image_force_pull: "{{ matrix_wechat_agent_container_image.endswith(':latest') }}" +matrix_bridge_wechat_agent_version: 0.0.1 +matrix_bridge_wechat_agent_container_image: "{{ matrix_bridge_wechat_agent_container_image_registry_prefix }}lxduo/matrix-wechat-agent:{{ matrix_bridge_wechat_agent_version }}" +matrix_bridge_wechat_agent_container_image_registry_prefix: "{{ 'localhost/' if matrix_bridge_wechat_agent_container_image_self_build else matrix_bridge_wechat_agent_container_image_registry_prefix_upstream }}" +matrix_bridge_wechat_agent_container_image_registry_prefix_upstream: "{{ matrix_bridge_wechat_agent_container_image_registry_prefix_upstream_default }}" +matrix_bridge_wechat_agent_container_image_registry_prefix_upstream_default: "docker.io/" # The agent needs to write to /home/user/.vnc. # `/home/user` is owned by `user:group` (`1000:1000`), so it needs to run with that user/group. -matrix_wechat_agent_container_user_uid: 1000 -matrix_wechat_agent_container_user_gid: 1000 +matrix_bridge_wechat_agent_container_user_uid: 1000 +matrix_bridge_wechat_agent_container_user_gid: 1000 -matrix_wechat_agent_container_image_self_build: false -matrix_wechat_agent_container_image_self_build_repo: "https://github.com/duo/matrix-wechat-agent.git" -matrix_wechat_agent_container_image_self_build_branch: "{{ 'master' if matrix_wechat_agent_version == 'latest' else matrix_wechat_agent_version }}" +matrix_bridge_wechat_agent_container_image_self_build: false +matrix_bridge_wechat_agent_container_image_self_build_repo: "https://github.com/duo/matrix-wechat-agent.git" +matrix_bridge_wechat_agent_container_image_self_build_branch: "{{ 'master' if matrix_bridge_wechat_agent_version == 'latest' else matrix_bridge_wechat_agent_version }}" -matrix_wechat_base_path: "{{ matrix_base_data_path }}/wechat" -matrix_wechat_config_path: "{{ matrix_wechat_base_path }}/config" -matrix_wechat_data_path: "{{ matrix_wechat_base_path }}/data" -matrix_wechat_container_src_files_path: "{{ matrix_wechat_base_path }}/container-src" -matrix_wechat_agent_container_src_files_path: "{{ matrix_wechat_base_path }}/agent-container-src" +matrix_bridge_wechat_base_path: "{{ matrix_base_data_path }}/wechat" +matrix_bridge_wechat_config_path: "{{ matrix_bridge_wechat_base_path }}/config" +matrix_bridge_wechat_data_path: "{{ matrix_bridge_wechat_base_path }}/data" +matrix_bridge_wechat_container_src_files_path: "{{ matrix_bridge_wechat_base_path }}/container-src" +matrix_bridge_wechat_agent_container_src_files_path: "{{ matrix_bridge_wechat_base_path }}/agent-container-src" -matrix_wechat_homeserver_address: "" -matrix_wechat_homeserver_domain: "{{ matrix_domain }}" +matrix_bridge_wechat_homeserver_address: "" +matrix_bridge_wechat_homeserver_domain: "{{ matrix_domain }}" # Whether asynchronous uploads via MSC2246 should be enabled for media. # Requires a homeserver that supports MSC2246 (https://github.com/matrix-org/matrix-spec-proposals/pull/2246). -matrix_wechat_homeserver_async_media: false -matrix_wechat_appservice_address: 'http://matrix-wechat:8080' +matrix_bridge_wechat_homeserver_async_media: false +matrix_bridge_wechat_appservice_address: 'http://matrix-wechat:8080' -matrix_wechat_container_network: "" +matrix_bridge_wechat_container_network: "" -matrix_wechat_container_additional_networks: "{{ matrix_wechat_container_additional_networks_auto + matrix_wechat_container_additional_networks_custom }}" -matrix_wechat_container_additional_networks_auto: [] -matrix_wechat_container_additional_networks_custom: [] +matrix_bridge_wechat_container_additional_networks: "{{ matrix_bridge_wechat_container_additional_networks_auto + matrix_bridge_wechat_container_additional_networks_custom }}" +matrix_bridge_wechat_container_additional_networks_auto: [] +matrix_bridge_wechat_container_additional_networks_custom: [] # A list of extra arguments to pass to the container -matrix_wechat_container_extra_arguments: [] +matrix_bridge_wechat_container_extra_arguments: [] # List of systemd services that matrix-wechat.service depends on. -matrix_wechat_systemd_required_services_list: "{{ matrix_wechat_systemd_required_services_list_default + matrix_wechat_systemd_required_services_list_auto + matrix_wechat_systemd_required_services_list_custom }}" -matrix_wechat_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_wechat_systemd_required_services_list_auto: [] -matrix_wechat_systemd_required_services_list_custom: [] +matrix_bridge_wechat_systemd_required_services_list: "{{ matrix_bridge_wechat_systemd_required_services_list_default + matrix_bridge_wechat_systemd_required_services_list_auto + matrix_bridge_wechat_systemd_required_services_list_custom }}" +matrix_bridge_wechat_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_bridge_wechat_systemd_required_services_list_auto: [] +matrix_bridge_wechat_systemd_required_services_list_custom: [] # List of systemd services that matrix-wechat.service wants -matrix_wechat_systemd_wanted_services_list: [] +matrix_bridge_wechat_systemd_wanted_services_list: [] -matrix_wechat_appservice_token: '' -matrix_wechat_homeserver_token: '' +matrix_bridge_wechat_appservice_token: '' +matrix_bridge_wechat_homeserver_token: '' -matrix_wechat_appservice_bot_username: wechatbot +matrix_bridge_wechat_appservice_bot_username: wechatbot -matrix_wechat_command_prefix: "!wechat" +matrix_bridge_wechat_command_prefix: "!wechat" # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. -matrix_wechat_federate_rooms: true +matrix_bridge_wechat_federate_rooms: true # Database-related configuration fields. -matrix_wechat_database_engine: 'postgres' -matrix_wechat_database_username: 'matrix_wechat' -matrix_wechat_database_password: 'some-password' -matrix_wechat_database_hostname: '' -matrix_wechat_database_port: 5432 -matrix_wechat_database_name: 'matrix_wechat' -matrix_wechat_database_sslmode: disable -matrix_wechat_database_connection_string: 'postgresql://{{ matrix_wechat_database_username }}:{{ matrix_wechat_database_password }}@{{ matrix_wechat_database_hostname }}:{{ matrix_wechat_database_port }}/{{ matrix_wechat_database_name }}?sslmode={{ matrix_wechat_database_sslmode }}' +matrix_bridge_wechat_database_engine: 'postgres' +matrix_bridge_wechat_database_username: 'matrix_wechat' +matrix_bridge_wechat_database_password: 'some-password' +matrix_bridge_wechat_database_hostname: '' +matrix_bridge_wechat_database_port: 5432 +matrix_bridge_wechat_database_name: 'matrix_wechat' +matrix_bridge_wechat_database_sslmode: disable +matrix_bridge_wechat_database_connection_string: 'postgresql://{{ matrix_bridge_wechat_database_username }}:{{ matrix_bridge_wechat_database_password }}@{{ matrix_bridge_wechat_database_hostname }}:{{ matrix_bridge_wechat_database_port }}/{{ matrix_bridge_wechat_database_name }}?sslmode={{ matrix_bridge_wechat_database_sslmode }}' -matrix_wechat_bridge_listen_secret: '' +matrix_bridge_wechat_bridge_listen_secret: '' # Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth). -matrix_wechat_login_shared_secret: '' -matrix_wechat_login_shared_secret_map: - "{{ {matrix_wechat_homeserver_domain: matrix_wechat_login_shared_secret} if matrix_wechat_login_shared_secret else {} }}" +matrix_bridge_wechat_login_shared_secret: '' +matrix_bridge_wechat_login_shared_secret_map: + "{{ {matrix_bridge_wechat_homeserver_domain: matrix_bridge_wechat_login_shared_secret} if matrix_bridge_wechat_login_shared_secret else {} }}" # Servers to always allow double puppeting from -matrix_wechat_double_puppet_server_map: - "{{ matrix_wechat_homeserver_domain: matrix_wechat_homeserver_address }}" +matrix_bridge_wechat_double_puppet_server_map: + "{{ matrix_bridge_wechat_homeserver_domain: matrix_bridge_wechat_homeserver_address }}" # Enable End-to-bridge encryption -matrix_wechat_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" -matrix_wechat_encryption_default: "{{ matrix_wechat_encryption_allow }}" +matrix_bridge_wechat_encryption_allow: "{{ matrix_bridges_encryption_enabled }}" +matrix_bridge_wechat_encryption_default: "{{ matrix_bridge_wechat_encryption_allow }}" # Minimum severity of journal log messages. # Valid values: fatal, error, warn, info, debug -matrix_wechat_log_level: 'warn' +matrix_bridge_wechat_log_level: 'warn' -matrix_wechat_permissions: | +matrix_bridge_wechat_permissions: | {{ - {matrix_wechat_homeserver_domain: 'user'} + {matrix_bridge_wechat_homeserver_domain: 'user'} | combine({matrix_admin: 'admin'} if matrix_admin else {}) }} # Default Wechat configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # -# For a more advanced customization, you can extend the default (see `matrix_wechat_configuration_extension_yaml`) +# For a more advanced customization, you can extend the default (see `matrix_bridge_wechat_configuration_extension_yaml`) # or completely replace this variable with your own template. -matrix_wechat_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" +matrix_bridge_wechat_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" -matrix_wechat_configuration_extension_yaml: | +matrix_bridge_wechat_configuration_extension_yaml: | # Your custom YAML configuration goes here. - # This configuration extends the default starting configuration (`matrix_wechat_configuration_yaml`). + # This configuration extends the default starting configuration (`matrix_bridge_wechat_configuration_yaml`). # # You can override individual variables from the default configuration, or introduce new ones. # # If you need something more special, you can take full control by - # completely redefining `matrix_wechat_configuration_yaml`. + # completely redefining `matrix_bridge_wechat_configuration_yaml`. -matrix_wechat_configuration_extension: "{{ matrix_wechat_configuration_extension_yaml | from_yaml if matrix_wechat_configuration_extension_yaml | from_yaml is mapping else {} }}" +matrix_bridge_wechat_configuration_extension: "{{ matrix_bridge_wechat_configuration_extension_yaml | from_yaml if matrix_bridge_wechat_configuration_extension_yaml | from_yaml is mapping else {} }}" # Holds the final configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_wechat_configuration_yaml`. -matrix_wechat_configuration: "{{ matrix_wechat_configuration_yaml | from_yaml | combine(matrix_wechat_configuration_extension, recursive=True) }}" +# You most likely don't need to touch this variable. Instead, see `matrix_bridge_wechat_configuration_yaml`. +matrix_bridge_wechat_configuration: "{{ matrix_bridge_wechat_configuration_yaml | from_yaml | combine(matrix_bridge_wechat_configuration_extension, recursive=True) }}" -matrix_wechat_registration_yaml: | +matrix_bridge_wechat_registration_yaml: | id: wechat - url: {{ matrix_wechat_appservice_address }} - as_token: "{{ matrix_wechat_appservice_token }}" - hs_token: "{{ matrix_wechat_homeserver_token }}" + url: {{ matrix_bridge_wechat_appservice_address }} + as_token: "{{ matrix_bridge_wechat_appservice_token }}" + hs_token: "{{ matrix_bridge_wechat_homeserver_token }}" # See https://github.com/mautrix/signal/issues/43 - sender_localpart: _bot_{{ matrix_wechat_appservice_bot_username }} + sender_localpart: _bot_{{ matrix_bridge_wechat_appservice_bot_username }} rate_limited: false namespaces: users: - - regex: '^@_wechat_(.*):{{ matrix_wechat_homeserver_domain | regex_escape }}$' + - regex: '^@_wechat_(.*):{{ matrix_bridge_wechat_homeserver_domain | regex_escape }}$' exclusive: true - exclusive: true - regex: '^@{{ matrix_wechat_appservice_bot_username | regex_escape }}:{{ matrix_wechat_homeserver_domain | regex_escape }}$' + regex: '^@{{ matrix_bridge_wechat_appservice_bot_username | regex_escape }}:{{ matrix_bridge_wechat_homeserver_domain | regex_escape }}$' de.sorunome.msc2409.push_ephemeral: true receive_ephemeral: true -matrix_wechat_registration: "{{ matrix_wechat_registration_yaml | from_yaml }}" +matrix_bridge_wechat_registration: "{{ matrix_bridge_wechat_registration_yaml | from_yaml }}" -matrix_wechat_agent_service_secret: "{{ matrix_wechat_bridge_listen_secret }}" +matrix_bridge_wechat_agent_service_secret: "{{ matrix_bridge_wechat_bridge_listen_secret }}" -matrix_wechat_agent_configuration_yaml: "{{ lookup('template', 'templates/agent-config.yaml.j2') }}" +matrix_bridge_wechat_agent_configuration_yaml: "{{ lookup('template', 'templates/agent-config.yaml.j2') }}" -matrix_wechat_agent_configuration: "{{ matrix_wechat_agent_configuration_yaml | from_yaml }}" +matrix_bridge_wechat_agent_configuration: "{{ matrix_bridge_wechat_agent_configuration_yaml | from_yaml }}" -# matrix_wechat_restart_necessary controls whether the service +# matrix_bridge_wechat_restart_necessary controls whether the service # will be restarted (when true) or merely started (when false) by the # systemd service manager role (when conditional restart is enabled). # @@ -172,4 +170,4 @@ matrix_wechat_agent_configuration: "{{ matrix_wechat_agent_configuration_yaml | # any configuration files, the systemd service file, or the container image changed. # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). -matrix_wechat_restart_necessary: false +matrix_bridge_wechat_restart_necessary: false diff --git a/roles/custom/matrix-bridge-wechat/tasks/install.yml b/roles/custom/matrix-bridge-wechat/tasks/install.yml index 57047e954..890dd8d87 100644 --- a/roles/custom/matrix-bridge-wechat/tasks/install.yml +++ b/roles/custom/matrix-bridge-wechat/tasks/install.yml @@ -13,114 +13,125 @@ owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" with_items: - - {path: "{{ matrix_wechat_base_path }}", when: true} - - {path: "{{ matrix_wechat_config_path }}", when: true} - - {path: "{{ matrix_wechat_data_path }}", when: true} - - {path: "{{ matrix_wechat_container_src_files_path }}", when: "{{ matrix_wechat_container_image_self_build }}"} - - {path: "{{ matrix_wechat_agent_container_src_files_path }}", when: "{{ matrix_wechat_agent_container_image_self_build }}"} + - {path: "{{ matrix_bridge_wechat_base_path }}", when: true} + - {path: "{{ matrix_bridge_wechat_config_path }}", when: true} + - {path: "{{ matrix_bridge_wechat_data_path }}", when: true} + - {path: "{{ matrix_bridge_wechat_container_src_files_path }}", when: "{{ matrix_bridge_wechat_container_image_self_build }}"} + - {path: "{{ matrix_bridge_wechat_agent_container_src_files_path }}", when: "{{ matrix_bridge_wechat_agent_container_image_self_build }}"} when: item.when | bool - name: Ensure WeChat Bridge image is pulled - community.docker.docker_image: - name: "{{ matrix_wechat_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_wechat_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_wechat_container_image_force_pull }}" - when: not matrix_wechat_container_image_self_build - register: matrix_wechat_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_wechat_container_image }}" + pull: always + when: not matrix_bridge_wechat_container_image_self_build + register: matrix_bridge_wechat_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_wechat_container_image_pull_result is not failed + until: matrix_bridge_wechat_container_image_pull_result is not failed -- when: matrix_wechat_container_image_self_build | bool +- when: matrix_bridge_wechat_container_image_self_build | bool block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure WeChat Bridge repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_wechat_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure WeChat Bridge repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_wechat_container_image_self_build_repo }}" - dest: "{{ matrix_wechat_container_src_files_path }}" - version: "{{ matrix_wechat_container_image_self_build_branch }}" + repo: "{{ matrix_bridge_wechat_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_wechat_container_src_files_path }}" + version: "{{ matrix_bridge_wechat_container_image_self_build_branch }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_wechat_git_pull_results + register: matrix_bridge_wechat_git_pull_results - name: Ensure WeChat Bridge container image is built - community.docker.docker_image: - name: "{{ matrix_wechat_container_image }}" - source: build - force_source: "{{ matrix_wechat_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_wechat_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_wechat_container_src_files_path }}" - pull: true + community.docker.docker_image_build: + name: "{{ matrix_bridge_wechat_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_wechat_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_wechat_git_pull_results.changed | bool else 'never' }}" + register: matrix_bridge_wechat_container_image_build_result - name: Ensure WeChat Agent image is pulled - community.docker.docker_image: - name: "{{ matrix_wechat_agent_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_wechat_agent_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_wechat_agent_container_image_force_pull }}" - when: not matrix_wechat_agent_container_image_self_build - register: matrix_wechat_agent_container_image_pull_result + community.docker.docker_image_pull: + name: "{{ matrix_bridge_wechat_agent_container_image }}" + pull: always + when: not matrix_bridge_wechat_agent_container_image_self_build + register: matrix_bridge_wechat_agent_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_wechat_agent_container_image_pull_result is not failed + until: matrix_bridge_wechat_agent_container_image_pull_result is not failed -- when: matrix_wechat_agent_container_image_self_build | bool +- when: matrix_bridge_wechat_agent_container_image_self_build | bool block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure WeChat Agent repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_bridge_wechat_agent_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure WeChat Agent repository is present on self-build ansible.builtin.git: - repo: "{{ matrix_wechat_agent_container_image_self_build_repo }}" - dest: "{{ matrix_wechat_agent_container_src_files_path }}" - version: "{{ matrix_wechat_agent_container_image_self_build_branch }}" + repo: "{{ matrix_bridge_wechat_agent_container_image_self_build_repo }}" + dest: "{{ matrix_bridge_wechat_agent_container_src_files_path }}" + version: "{{ matrix_bridge_wechat_agent_container_image_self_build_branch }}" force: "yes" become: true become_user: "{{ matrix_user_name }}" - register: matrix_wechat_agent_git_pull_results + register: matrix_bridge_wechat_agent_git_pull_results - name: Ensure WeChat Agent container image is built - community.docker.docker_image: - name: "{{ matrix_wechat_agent_container_image }}" - source: build - force_source: "{{ matrix_wechat_agent_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_wechat_agent_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_wechat_agent_container_src_files_path }}" - pull: true + community.docker.docker_image_build: + name: "{{ matrix_bridge_wechat_agent_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_bridge_wechat_agent_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_bridge_wechat_agent_git_pull_results.changed | bool else 'never' }}" + register: matrix_bridge_wechat_agent_container_image_build_result - name: Ensure WeChat configuration installed ansible.builtin.copy: - content: "{{ matrix_wechat_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_wechat_config_path }}/config.yaml" + content: "{{ matrix_bridge_wechat_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_wechat_config_path }}/config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_wechat_config_result + register: matrix_bridge_wechat_config_result - name: Ensure WeChat registration.yaml installed ansible.builtin.copy: - content: "{{ matrix_wechat_registration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_wechat_config_path }}/registration.yaml" + content: "{{ matrix_bridge_wechat_registration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_wechat_config_path }}/registration.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_wechat_registration_result + register: matrix_bridge_wechat_registration_result - name: Ensure Wechat Agent configuration installed ansible.builtin.copy: - content: "{{ matrix_wechat_agent_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_wechat_config_path }}/agent-config.yaml" + content: "{{ matrix_bridge_wechat_agent_configuration | to_nice_yaml(indent=2, width=999999) }}" + dest: "{{ matrix_bridge_wechat_config_path }}/agent-config.yaml" mode: '0644' owner: "{{ matrix_user_name }}" group: "{{ matrix_group_name }}" - register: matrix_wechat_agent_config_result + register: matrix_bridge_wechat_agent_config_result - name: Ensure matrix-wechat container network is created + when: matrix_bridge_wechat_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_wechat_container_network }}" + name: "{{ matrix_bridge_wechat_container_network }}" driver: bridge driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" @@ -129,24 +140,26 @@ src: "{{ role_path }}/templates/systemd/matrix-wechat.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-wechat.service" mode: '0644' - register: matrix_wechat_systemd_service_result + register: matrix_bridge_wechat_systemd_service_result - name: Ensure matrix-wechat-agent.service installed ansible.builtin.template: src: "{{ role_path }}/templates/systemd/matrix-wechat-agent.service.j2" dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-wechat-agent.service" mode: '0644' - register: matrix_wechat_agent_systemd_service_result + register: matrix_bridge_wechat_agent_systemd_service_result - name: Determine whether WeChat Bridge needs a restart ansible.builtin.set_fact: - matrix_wechat_restart_necessary: >- + matrix_bridge_wechat_restart_necessary: >- {{ - matrix_wechat_config_result.changed | default(false) - or matrix_wechat_registration_result.changed | default(false) - or matrix_wechat_agent_config_result.changed | default(false) - or matrix_wechat_systemd_service_result.changed | default(false) - or matrix_wechat_agent_systemd_service_result.changed | default(false) - or matrix_wechat_container_image_pull_result.changed | default(false) - or matrix_wechat_agent_container_image_pull_result.changed | default(false) + matrix_bridge_wechat_config_result.changed | default(false) + or matrix_bridge_wechat_registration_result.changed | default(false) + or matrix_bridge_wechat_agent_config_result.changed | default(false) + or matrix_bridge_wechat_systemd_service_result.changed | default(false) + or matrix_bridge_wechat_agent_systemd_service_result.changed | default(false) + or matrix_bridge_wechat_container_image_pull_result.changed | default(false) + or matrix_bridge_wechat_agent_container_image_pull_result.changed | default(false) + or matrix_bridge_wechat_container_image_build_result.changed | default(false) + or matrix_bridge_wechat_agent_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-bridge-wechat/tasks/main.yml b/roles/custom/matrix-bridge-wechat/tasks/main.yml index bcad351ab..8ed084797 100644 --- a/roles/custom/matrix-bridge-wechat/tasks/main.yml +++ b/roles/custom/matrix-bridge-wechat/tasks/main.yml @@ -10,15 +10,15 @@ - install-all - install-wechat block: - - when: matrix_wechat_enabled | bool + - when: matrix_bridge_wechat_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_wechat_enabled | bool + - when: matrix_bridge_wechat_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/install.yml" - tags: - setup-all - setup-wechat block: - - when: not matrix_wechat_enabled | bool + - when: not matrix_bridge_wechat_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/uninstall.yml" diff --git a/roles/custom/matrix-bridge-wechat/tasks/uninstall.yml b/roles/custom/matrix-bridge-wechat/tasks/uninstall.yml index 7972bd7df..8cc746eb9 100644 --- a/roles/custom/matrix-bridge-wechat/tasks/uninstall.yml +++ b/roles/custom/matrix-bridge-wechat/tasks/uninstall.yml @@ -7,9 +7,9 @@ - name: Check existence of matrix-wechat service ansible.builtin.stat: path: "/etc/systemd/system/matrix-wechat.service" - register: matrix_wechat_service_stat + register: matrix_bridge_wechat_service_stat -- when: matrix_wechat_service_stat.stat.exists | bool +- when: matrix_bridge_wechat_service_stat.stat.exists | bool block: - name: Ensure matrix-wechat is stopped ansible.builtin.service: @@ -26,9 +26,9 @@ - name: Check existence of matrix-wechat-agent service ansible.builtin.stat: path: "/etc/systemd/system/matrix-wechat-agent.service" - register: matrix_wechat_agent_service_stat + register: matrix_bridge_wechat_agent_service_stat -- when: matrix_wechat_agent_service_stat.stat.exists | bool +- when: matrix_bridge_wechat_agent_service_stat.stat.exists | bool block: - name: Ensure matrix-wechat-agent is stopped ansible.builtin.service: diff --git a/roles/custom/matrix-bridge-wechat/tasks/validate_config.yml b/roles/custom/matrix-bridge-wechat/tasks/validate_config.yml index 324cb8e1a..86ffa70a8 100644 --- a/roles/custom/matrix-bridge-wechat/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-wechat/tasks/validate_config.yml @@ -10,12 +10,12 @@ You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" with_items: - - {'name': 'matrix_wechat_appservice_token', when: true} - - {'name': 'matrix_wechat_homeserver_address', when: true} - - {'name': 'matrix_wechat_homeserver_token', when: true} - - {'name': 'matrix_wechat_database_hostname', when: "{{ matrix_wechat_database_engine == 'postgres' }}"} - - {'name': 'matrix_wechat_container_network', when: true} - - {'name': 'matrix_wechat_bridge_listen_secret', when: true} + - {'name': 'matrix_bridge_wechat_appservice_token', when: true} + - {'name': 'matrix_bridge_wechat_homeserver_address', when: true} + - {'name': 'matrix_bridge_wechat_homeserver_token', when: true} + - {'name': 'matrix_bridge_wechat_database_hostname', when: "{{ matrix_bridge_wechat_database_engine == 'postgres' }}"} + - {'name': 'matrix_bridge_wechat_container_network', when: true} + - {'name': 'matrix_bridge_wechat_bridge_listen_secret', when: true} - name: Fail if WeChat enabled on ARM64 (not supported by the wechat agent, even with self-building) when: matrix_architecture not in ['amd64'] @@ -28,5 +28,7 @@ The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - - {'old': 'matrix_wechat_container_image_name_prefix', 'new': 'matrix_wechat_container_image_registry_prefix'} - - {'old': 'matrix_wechat_agent_container_image_name_prefix', 'new': 'matrix_wechat_agent_container_image_registry_prefix'} + - {'old': 'matrix_bridge_wechat_container_image_name_prefix', 'new': 'matrix_bridge_wechat_container_image_registry_prefix'} + - {'old': 'matrix_bridge_wechat_agent_container_image_name_prefix', 'new': 'matrix_bridge_wechat_agent_container_image_registry_prefix'} + - {'old': 'matrix_bridge_wechat_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_bridge_wechat_agent_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-bridge-wechat/templates/agent-config.yaml.j2 b/roles/custom/matrix-bridge-wechat/templates/agent-config.yaml.j2 index 6b30c6345..cd2d05d50 100644 --- a/roles/custom/matrix-bridge-wechat/templates/agent-config.yaml.j2 +++ b/roles/custom/matrix-bridge-wechat/templates/agent-config.yaml.j2 @@ -12,7 +12,7 @@ wechat: service: addr: ws://matrix-wechat:20002 - secret: {{ matrix_wechat_bridge_listen_secret | to_json }} + secret: {{ matrix_bridge_wechat_bridge_listen_secret | to_json }} ping_interval: 30s log: diff --git a/roles/custom/matrix-bridge-wechat/templates/config.yaml.j2 b/roles/custom/matrix-bridge-wechat/templates/config.yaml.j2 index 86330ed48..694ab341f 100644 --- a/roles/custom/matrix-bridge-wechat/templates/config.yaml.j2 +++ b/roles/custom/matrix-bridge-wechat/templates/config.yaml.j2 @@ -2,9 +2,9 @@ # Homeserver details. homeserver: # The address that this appservice can use to connect to the homeserver. - address: {{ matrix_wechat_homeserver_address | to_json }} + address: {{ matrix_bridge_wechat_homeserver_address | to_json }} # The domain of the homeserver (for MXIDs, etc). - domain: {{ matrix_wechat_homeserver_domain | to_json }} + domain: {{ matrix_bridge_wechat_homeserver_domain | to_json }} # What software is the homeserver running? # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. @@ -16,7 +16,7 @@ homeserver: # Endpoint for reporting per-message status. message_send_checkpoint_endpoint: null # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: {{ matrix_wechat_homeserver_async_media | to_json }} + async_media: {{ matrix_bridge_wechat_homeserver_async_media | to_json }} # Should the bridge use a websocket for connecting to the homeserver? # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, @@ -29,7 +29,7 @@ homeserver: # Changing these values requires regeneration of the registration. appservice: # The address that the homeserver can use to connect to this appservice. - address: {{ matrix_wechat_appservice_address | to_json }} + address: {{ matrix_bridge_wechat_appservice_address | to_json }} # The hostname and port where this appservice should listen. hostname: 0.0.0.0 @@ -43,7 +43,7 @@ appservice: # SQLite: File name is enough. https://github.com/mattn/go-sqlite3#connection-string # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: {{ matrix_wechat_database_connection_string | to_json }} + uri: {{ matrix_bridge_wechat_database_connection_string | to_json }} # Maximum number of connections. Mostly relevant for Postgres. max_open_conns: 20 max_idle_conns: 2 @@ -57,7 +57,7 @@ appservice: # Appservice bot details. bot: # Username of the appservice bot. - username: {{ matrix_wechat_appservice_bot_username | to_json }} + username: {{ matrix_bridge_wechat_appservice_bot_username | to_json }} # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty # to leave display name/avatar as-is. displayname: WeChat bridge bot @@ -73,8 +73,8 @@ appservice: async_transactions: false # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: {{ matrix_wechat_appservice_token | to_json }} - hs_token: {{ matrix_wechat_homeserver_token | to_json }} + as_token: {{ matrix_bridge_wechat_appservice_token | to_json }} + hs_token: {{ matrix_bridge_wechat_homeserver_token | to_json }} # Bridge config bridge: @@ -85,7 +85,7 @@ bridge: displayname_template: "{% raw %}{{if .Name}}{{.Name}}{{else}}{{.Uin}}{{end}} (WeChat){% endraw %}" # WeChat listen address (for agent connection) listen_address: "0.0.0.0:20002" - listen_secret: {{ matrix_wechat_bridge_listen_secret | to_json }} + listen_secret: {{ matrix_bridge_wechat_bridge_listen_secret | to_json }} # Should the bridge create a space for each logged-in user and add bridged rooms to it? # Users who logged in before turning this on should run `!wa sync space` to create and fill the space for the first time. personal_filtering_spaces: true @@ -112,7 +112,7 @@ bridge: send_presence_on_typing: false # Servers to always allow double puppeting from double_puppet_server_map: - "{{ matrix_wechat_homeserver_domain }}": {{ matrix_wechat_homeserver_address }} + "{{ matrix_bridge_wechat_homeserver_domain }}": {{ matrix_bridge_wechat_homeserver_address }} # Allow using double puppeting from any server with a valid client .well-known file. double_puppet_allow_discovery: false # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth @@ -120,7 +120,7 @@ bridge: # If set, double puppeting will be enabled automatically for local users # instead of users having to find an access token and run `login-matrix` # manually. - login_shared_secret_map: {{ matrix_wechat_login_shared_secret_map | to_json }} + login_shared_secret_map: {{ matrix_bridge_wechat_login_shared_secret_map | to_json }} # Whether to explicitly set the avatar and room name for private chat portal rooms. # If set to `default`, this will be enabled in encrypted rooms and disabled in unencrypted rooms. # If set to `always`, all DM rooms will have explicit names and avatars set. @@ -154,7 +154,7 @@ bridge: deadline: 120s # The prefix for commands. Only required in non-management rooms. - command_prefix: {{ matrix_wechat_command_prefix | to_json }} + command_prefix: {{ matrix_bridge_wechat_command_prefix | to_json }} # Messages sent upon joining a management room. # Markdown is supported. The defaults are listed below. @@ -173,10 +173,10 @@ bridge: # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. encryption: # Allow encryption, work in group chat rooms with e2ee enabled - allow: {{ matrix_wechat_encryption_allow | to_json }} + allow: {{ matrix_bridge_wechat_encryption_allow | to_json }} # Default to encryption, force-enable encryption in all portals the bridge creates # This will cause the bridge bot to be in private chats for the encryption to work properly. - default: {{ matrix_wechat_encryption_default | to_json }} + default: {{ matrix_bridge_wechat_encryption_default | to_json }} # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. appservice: false # Require encryption, drop any unencrypted messages. @@ -255,11 +255,11 @@ bridge: # * - All Matrix users # domain - All users on that homeserver # mxid - Specific user - permissions: {{ matrix_wechat_permissions | to_json }} + permissions: {{ matrix_bridge_wechat_permissions | to_json }} # Logging config. See https://github.com/tulir/zeroconfig for details. logging: - min_level: {{ matrix_wechat_log_level }} + min_level: {{ matrix_bridge_wechat_log_level }} writers: - type: stdout format: pretty-colored diff --git a/roles/custom/matrix-bridge-wechat/templates/systemd/matrix-wechat-agent.service.j2 b/roles/custom/matrix-bridge-wechat/templates/systemd/matrix-wechat-agent.service.j2 index 9f9a195c2..ed0975140 100644 --- a/roles/custom/matrix-bridge-wechat/templates/systemd/matrix-wechat-agent.service.j2 +++ b/roles/custom/matrix-bridge-wechat/templates/systemd/matrix-wechat-agent.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix WeChat Agent -{% for service in matrix_wechat_systemd_required_services_list %} +{% for service in matrix_bridge_wechat_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_wechat_systemd_wanted_services_list %} +{% for service in matrix_bridge_wechat_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -24,18 +24,20 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --rm \ --name=matrix-wechat-agent \ --log-driver=none \ - --user={{ matrix_wechat_agent_container_user_uid }}:{{ matrix_wechat_agent_container_user_gid }} \ + --user={{ matrix_bridge_wechat_agent_container_user_uid }}:{{ matrix_bridge_wechat_agent_container_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_wechat_container_network }} \ - --mount type=bind,src={{ matrix_wechat_config_path }}/agent-config.yaml,dst=/home/user/matrix-wechat-agent/configure.yaml,ro \ - {% for arg in matrix_wechat_container_extra_arguments %} + --network={{ matrix_bridge_wechat_container_network }} \ + --mount type=bind,src={{ matrix_bridge_wechat_config_path }}/agent-config.yaml,dst=/home/user/matrix-wechat-agent/configure.yaml,ro \ + {% for arg in matrix_bridge_wechat_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_wechat_agent_container_image }} + {{ matrix_bridge_wechat_agent_container_image }} -{% for network in matrix_wechat_container_additional_networks %} +{% if matrix_bridge_wechat_container_network != 'host' %} +{% for network in matrix_bridge_wechat_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-wechat-agent {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-wechat-agent diff --git a/roles/custom/matrix-bridge-wechat/templates/systemd/matrix-wechat.service.j2 b/roles/custom/matrix-bridge-wechat/templates/systemd/matrix-wechat.service.j2 index 4c9deb056..b748402df 100644 --- a/roles/custom/matrix-bridge-wechat/templates/systemd/matrix-wechat.service.j2 +++ b/roles/custom/matrix-bridge-wechat/templates/systemd/matrix-wechat.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] Description=Matrix WeChat Bridge -{% for service in matrix_wechat_systemd_required_services_list %} +{% for service in matrix_bridge_wechat_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_wechat_systemd_wanted_services_list %} +{% for service in matrix_bridge_wechat_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -22,18 +22,20 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ - --network={{ matrix_wechat_container_network }} \ - --mount type=bind,src={{ matrix_wechat_config_path }},dst=/config,ro \ - --mount type=bind,src={{ matrix_wechat_data_path }},dst=/data \ + --network={{ matrix_bridge_wechat_container_network }} \ + --mount type=bind,src={{ matrix_bridge_wechat_config_path }},dst=/config,ro \ + --mount type=bind,src={{ matrix_bridge_wechat_data_path }},dst=/data \ --workdir=/data \ - {% for arg in matrix_wechat_container_extra_arguments %} + {% for arg in matrix_bridge_wechat_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_wechat_container_image }} \ + {{ matrix_bridge_wechat_container_image }} \ /usr/bin/matrix-wechat -c /config/config.yaml -r /config/registration.yaml --no-update -{% for network in matrix_wechat_container_additional_networks %} +{% if matrix_bridge_wechat_container_network != 'host' %} +{% for network in matrix_bridge_wechat_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-wechat {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-wechat diff --git a/roles/custom/matrix-cactus-comments-client/defaults/main.yml b/roles/custom/matrix-cactus-comments-client/defaults/main.yml index 8809a3aca..0fe0210e6 100644 --- a/roles/custom/matrix-cactus-comments-client/defaults/main.yml +++ b/roles/custom/matrix-cactus-comments-client/defaults/main.yml @@ -18,14 +18,13 @@ matrix_cactus_comments_client_public_path: "{{ matrix_cactus_comments_client_bas matrix_cactus_comments_client_public_path_file_permissions: "0644" # renovate: datasource=docker depName=joseluisq/static-web-server -matrix_cactus_comments_client_version: 2.42.0 +matrix_cactus_comments_client_version: 2.44.0 matrix_cactus_comments_client_container_image: "{{ matrix_cactus_comments_client_container_image_registry_prefix }}joseluisq/static-web-server:{{ matrix_cactus_comments_client_container_image_tag }}" matrix_cactus_comments_client_container_image_registry_prefix: "{{ matrix_cactus_comments_client_container_image_registry_prefix_upstream }}" matrix_cactus_comments_client_container_image_registry_prefix_upstream: "{{ matrix_cactus_comments_client_container_image_registry_prefix_upstream_default }}" matrix_cactus_comments_client_container_image_registry_prefix_upstream_default: docker.io/ matrix_cactus_comments_client_container_image_tag: "{{ 'latest' if matrix_cactus_comments_client_version == 'latest' else (matrix_cactus_comments_client_version + '-alpine') }}" -matrix_cactus_comments_client_container_image_force_pull: "{{ matrix_cactus_comments_client_container_image.endswith(':latest') }}" matrix_cactus_comments_client_container_network: "" diff --git a/roles/custom/matrix-cactus-comments-client/tasks/install.yml b/roles/custom/matrix-cactus-comments-client/tasks/install.yml index fd2975577..f7caca0cc 100644 --- a/roles/custom/matrix-cactus-comments-client/tasks/install.yml +++ b/roles/custom/matrix-cactus-comments-client/tasks/install.yml @@ -67,17 +67,16 @@ group: "{{ matrix_group_name }}" - name: Ensure matrix-cactus-comments-client container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_cactus_comments_client_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_cactus_comments_client_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_cactus_comments_client_container_image_force_pull }}" + pull: always register: matrix_cactus_comments_client_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_cactus_comments_client_container_image_pull_result is not failed - name: Ensure matrix-cactus-comments-client container network is created + when: matrix_cactus_comments_client_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_cactus_comments_client_container_network }}" diff --git a/roles/custom/matrix-cactus-comments-client/tasks/validate_config.yml b/roles/custom/matrix-cactus-comments-client/tasks/validate_config.yml index b76cc963a..fccf2edd7 100644 --- a/roles/custom/matrix-cactus-comments-client/tasks/validate_config.yml +++ b/roles/custom/matrix-cactus-comments-client/tasks/validate_config.yml @@ -13,3 +13,11 @@ - matrix_cactus_comments_client_hostname - matrix_cactus_comments_client_path_prefix - matrix_cactus_comments_client_container_network + +- name: (Deprecation) Catch and report renamed matrix-cactus-comments-client variables + ansible.builtin.fail: + msg: >- + The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_cactus_comments_client_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-cactus-comments-client/templates/systemd/matrix-cactus-comments-client.service.j2 b/roles/custom/matrix-cactus-comments-client/templates/systemd/matrix-cactus-comments-client.service.j2 index 995ce5d6f..bb7601042 100755 --- a/roles/custom/matrix-cactus-comments-client/templates/systemd/matrix-cactus-comments-client.service.j2 +++ b/roles/custom/matrix-cactus-comments-client/templates/systemd/matrix-cactus-comments-client.service.j2 @@ -32,9 +32,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --mount type=bind,src={{ matrix_cactus_comments_client_public_path }},dst=/var/public,ro \ {{ matrix_cactus_comments_client_container_image }} +{% if matrix_cactus_comments_client_container_network != 'host' %} {% for network in matrix_cactus_comments_client_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-cactus-comments-client {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-cactus-comments-client diff --git a/roles/custom/matrix-cactus-comments/defaults/main.yml b/roles/custom/matrix-cactus-comments/defaults/main.yml index dde192bd6..e70629108 100644 --- a/roles/custom/matrix-cactus-comments/defaults/main.yml +++ b/roles/custom/matrix-cactus-comments/defaults/main.yml @@ -38,7 +38,6 @@ matrix_cactus_comments_container_image_registry_prefix: "{{ 'localhost/' if matr matrix_cactus_comments_container_image_registry_prefix_upstream: "{{ matrix_cactus_comments_container_image_registry_prefix_upstream_default }}" matrix_cactus_comments_container_image_registry_prefix_upstream_default: docker.io/ matrix_cactus_comments_container_image_tag: "{{ matrix_cactus_comments_version }}" -matrix_cactus_comments_container_image_force_pull: "{{ matrix_cactus_comments_container_image.endswith(':latest') }}" matrix_cactus_comments_container_network: "" diff --git a/roles/custom/matrix-cactus-comments/tasks/setup_install.yml b/roles/custom/matrix-cactus-comments/tasks/setup_install.yml index 2c76c0e1d..2e3e3546a 100644 --- a/roles/custom/matrix-cactus-comments/tasks/setup_install.yml +++ b/roles/custom/matrix-cactus-comments/tasks/setup_install.yml @@ -38,17 +38,25 @@ register: matrix_cactus_comments_config_appservice_result - name: Ensure matrix-cactus-comments image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_cactus_comments_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_cactus_comments_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_cactus_comments_container_image_force_pull }}" + pull: always when: "not matrix_cactus_comments_container_image_self_build | bool" register: matrix_cactus_comments_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_cactus_comments_container_image_pull_result is not failed +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure matrix-cactus-comments repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_cactus_comments_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_cactus_comments_container_image_self_build | bool" + - name: Ensure matrix-cactus-comments repository is present on self-build ansible.builtin.git: repo: "{{ matrix_cactus_comments_container_repo }}" @@ -61,16 +69,14 @@ when: "matrix_cactus_comments_container_image_self_build | bool" - name: Ensure matrix-cactus-comments image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_cactus_comments_container_image }}" - source: build - force_source: "{{ matrix_cactus_comments_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_cactus_comments_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_cactus_comments_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_cactus_comments_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_cactus_comments_git_pull_results.changed | bool else 'never' }}" when: "matrix_cactus_comments_container_image_self_build | bool" + register: matrix_cactus_comments_container_image_build_result - name: Ensure matrix-cactus-comments.service installed ansible.builtin.template: @@ -87,4 +93,5 @@ or matrix_cactus_comments_config_appservice_result.changed | default(false) or matrix_cactus_comments_systemd_service_result.changed | default(false) or matrix_cactus_comments_container_image_pull_result.changed | default(false) + or matrix_cactus_comments_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-cactus-comments/tasks/validate_config.yml b/roles/custom/matrix-cactus-comments/tasks/validate_config.yml index a5c4d8769..cc9b1a477 100644 --- a/roles/custom/matrix-cactus-comments/tasks/validate_config.yml +++ b/roles/custom/matrix-cactus-comments/tasks/validate_config.yml @@ -28,6 +28,7 @@ - {'old': 'matrix_cactus_comments_docker_repo', 'new': 'matrix_cactus_comments_container_repo'} - {'old': 'matrix_cactus_comments_docker_repo_version', 'new': 'matrix_cactus_comments_container_repo_version'} - {'old': 'matrix_cactus_comments_docker_src_files_path', 'new': 'matrix_cactus_comments_container_src_files_path'} + - {'old': 'matrix_cactus_comments_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required matrix-cactus-comments settings not defined ansible.builtin.fail: diff --git a/roles/custom/matrix-cactus-comments/templates/systemd/matrix-cactus-comments.service.j2 b/roles/custom/matrix-cactus-comments/templates/systemd/matrix-cactus-comments.service.j2 index 5d7cb201a..5db5accc9 100644 --- a/roles/custom/matrix-cactus-comments/templates/systemd/matrix-cactus-comments.service.j2 +++ b/roles/custom/matrix-cactus-comments/templates/systemd/matrix-cactus-comments.service.j2 @@ -28,9 +28,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --network={{ matrix_cactus_comments_container_network }} \ {{ matrix_cactus_comments_container_image }} +{% if matrix_cactus_comments_container_network != 'host' %} {% for network in matrix_cactus_comments_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-cactus-comments {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-cactus-comments diff --git a/roles/custom/matrix-client-commet/defaults/main.yml b/roles/custom/matrix-client-commet/defaults/main.yml index 17ba27b7e..b59a9b519 100644 --- a/roles/custom/matrix-client-commet/defaults/main.yml +++ b/roles/custom/matrix-client-commet/defaults/main.yml @@ -10,6 +10,9 @@ matrix_client_commet_enabled: true # The git branch, tag, or SHA to build from matrix_client_commet_version: "main" +# The scheme used for serving Commet. +matrix_client_commet_scheme: https + # The hostname at which Commet is served (e.g. commet.example.com) matrix_client_commet_hostname: "" diff --git a/roles/custom/matrix-client-commet/tasks/main.yml b/roles/custom/matrix-client-commet/tasks/main.yml index c5a421018..488c474da 100644 --- a/roles/custom/matrix-client-commet/tasks/main.yml +++ b/roles/custom/matrix-client-commet/tasks/main.yml @@ -10,6 +10,9 @@ - install-all - install-client-commet block: + - when: matrix_client_commet_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" + - when: matrix_client_commet_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" diff --git a/roles/custom/matrix-client-commet/tasks/setup_install.yml b/roles/custom/matrix-client-commet/tasks/setup_install.yml index 07b44e15d..15515b4a4 100644 --- a/roles/custom/matrix-client-commet/tasks/setup_install.yml +++ b/roles/custom/matrix-client-commet/tasks/setup_install.yml @@ -17,11 +17,9 @@ - "{{ matrix_client_commet_config_path }}" - name: Ensure Commet container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_client_commet_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_client_commet_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_client_commet_container_image_force_pull }}" + pull: always when: "not matrix_client_commet_container_image_self_build | bool" register: matrix_client_commet_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -42,6 +40,15 @@ when: not matrix_client_commet_git_config_file_stat.stat.exists become: true + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure Commet repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_client_commet_container_src_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure Commet repository is present on self-build ansible.builtin.git: repo: "{{ matrix_client_commet_container_image_self_build_repo }}" @@ -91,6 +98,7 @@ register: matrix_client_commet_support_files_result - name: Ensure Commet container network is created + when: matrix_client_commet_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_client_commet_container_network }}" diff --git a/roles/custom/matrix-client-commet/tasks/validate_config.yml b/roles/custom/matrix-client-commet/tasks/validate_config.yml new file mode 100644 index 000000000..c32eb165d --- /dev/null +++ b/roles/custom/matrix-client-commet/tasks/validate_config.yml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2026 MDAD project contributors +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: (Deprecation) Catch and report renamed matrix-client-commet variables + ansible.builtin.fail: + msg: >- + The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_client_commet_container_image_force_pull', 'new': ' (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-client-commet/templates/systemd/matrix-client-commet.service.j2 b/roles/custom/matrix-client-commet/templates/systemd/matrix-client-commet.service.j2 index adf998351..afd4a4310 100644 --- a/roles/custom/matrix-client-commet/templates/systemd/matrix-client-commet.service.j2 +++ b/roles/custom/matrix-client-commet/templates/systemd/matrix-client-commet.service.j2 @@ -41,9 +41,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_client_commet_container_image }} +{% if matrix_client_commet_container_network != 'host' %} {% for network in matrix_client_commet_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-client-commet {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-client-commet diff --git a/roles/custom/matrix-client-element/defaults/main.yml b/roles/custom/matrix-client-element/defaults/main.yml index 330448f31..ad25e205b 100644 --- a/roles/custom/matrix-client-element/defaults/main.yml +++ b/roles/custom/matrix-client-element/defaults/main.yml @@ -29,16 +29,16 @@ matrix_client_element_container_image_self_build_repo: "https://github.com/eleme matrix_client_element_container_image_self_build_low_memory_system_patch_enabled: "{{ ansible_facts['memtotal_mb'] < 4096 }}" # renovate: datasource=docker depName=ghcr.io/element-hq/element-web -matrix_client_element_version: v1.12.13 +matrix_client_element_version: v1.12.27 matrix_client_element_container_image: "{{ matrix_client_element_container_image_registry_prefix }}element-hq/element-web:{{ matrix_client_element_version }}" matrix_client_element_container_image_registry_prefix: "{{ 'localhost/' if matrix_client_element_container_image_self_build else matrix_client_element_container_image_registry_prefix_upstream }}" matrix_client_element_container_image_registry_prefix_upstream: "{{ matrix_client_element_container_image_registry_prefix_upstream_default }}" matrix_client_element_container_image_registry_prefix_upstream_default: ghcr.io/ -matrix_client_element_container_image_force_pull: "{{ matrix_client_element_container_image.endswith(':latest') }}" matrix_client_element_data_path: "{{ matrix_base_data_path }}/client-element" matrix_client_element_container_src_files_path: "{{ matrix_client_element_data_path }}/docker-src" +matrix_client_element_container_src_dockerfile_path: "{{ matrix_client_element_container_src_files_path }}/apps/web/Dockerfile" # The base container network matrix_client_element_container_network: '' @@ -189,15 +189,10 @@ matrix_client_element_room_directory_servers: ['matrix.org'] # Branding of Element matrix_client_element_brand: "Element" -# URL to Logo on welcome page +# URL to the logo shown on the welcome and login pages. +# This is the default for `matrix_client_element_branding_auth_header_logo_url` below. matrix_client_element_welcome_logo: "themes/element/img/logos/element-logo.svg" -# URL of link on welcome image -matrix_client_element_welcome_logo_link: "https://element.io" - -matrix_client_element_welcome_headline: "_t(\"welcome_to_element\")" -matrix_client_element_welcome_text: "_t(\"powered_by_matrix_with_logo\")" - # Links, shown in footer of welcome page: # [{"text": "Link text", "url": "https://link.target"}, {"text": "Other link"}] matrix_client_element_branding_auth_footer_links: ~ # noqa var-naming @@ -206,7 +201,7 @@ matrix_client_element_branding_auth_footer_links: ~ # noqa var-naming matrix_client_element_branding_auth_header_logo_url: "{{ matrix_client_element_welcome_logo }}" # noqa var-naming # URL to Wallpaper, shown in background of welcome page -matrix_client_element_branding_welcome_background_url: ~ # noqa var-naming +matrix_client_element_branding_welcome_background_url: "themes/element/img/backgrounds/lake.jpg" # Controls the `features` section of the Element Web configuration. matrix_client_element_features: "{{ matrix_client_element_features_default | combine(matrix_client_element_features_auto, recursive=True) | combine(matrix_client_element_features_custom, recursive=True) }}" @@ -269,8 +264,6 @@ matrix_client_element_element_call_brand: "Element Call" # Controls the `element_call.use_exclusively` setting in the Element Web configuration. matrix_client_element_element_call_use_exclusively: true -matrix_client_element_page_template_welcome_path: "{{ role_path }}/templates/welcome.html.j2" - # By default, there's no Element Web homepage (when logged in). If you wish to have one, # point this to a `home.html` template file on your local filesystem. matrix_client_element_embedded_pages_home_path: ~ @@ -346,6 +339,10 @@ matrix_client_element_configuration: "{{ matrix_client_element_configuration_def # How to host your own map tile server: https://matrix.org/docs/guides/map-tile-server matrix_client_element_location_sharing_enabled: false +# Controls the value of the `Access-Control-Allow-Origin` header attached to responses for `map_style.json`. +# Element Desktop loads the map style from a `vector://vector` origin, so cross-origin access needs to be allowed. +matrix_client_element_location_sharing_map_style_access_control_allow_origin: "*" + # Default Element location sharing map style configuration template which covers the generic use case. # You can customize it by controlling the various variables inside it. # diff --git a/roles/custom/matrix-client-element/molecule/default/converge.yml b/roles/custom/matrix-client-element/molecule/default/converge.yml new file mode 100644 index 000000000..f4b8ecef8 --- /dev/null +++ b/roles/custom/matrix-client-element/molecule/default/converge.yml @@ -0,0 +1,53 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-client-element Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include base roles for matrix-client-element Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + loop_control: + loop_var: role_name + + # The role's main task file also carries the separately-invoked `self-check` + # action. A tagless include would run it before systemd_service_manager has + # started the component. Include the same setup task files selected by the + # playbook's setup-client-element tag, then start the unit below. + - name: Include matrix-client-element setup task files + ansible.builtin.include_role: + name: "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + public: true + tasks_from: "{{ role_task_file }}" + loop: + - validate_config.yml + - prepare_themes.yml + - setup_install.yml + loop_control: + loop_var: role_task_file + +# The component role installs its unit; systemd_service_manager starts it in the +# full playbook. Start it directly here so the scenario remains role-scoped. +- name: Ensure matrix-client-element is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure matrix-client-element systemd service is started + ansible.builtin.systemd_service: + name: matrix-client-element.service + state: started diff --git a/roles/custom/matrix-client-element/molecule/default/molecule.yml b/roles/custom/matrix-client-element/molecule/default/molecule.yml new file mode 100644 index 000000000..43b0101d2 --- /dev/null +++ b/roles/custom/matrix-client-element/molecule/default/molecule.yml @@ -0,0 +1,133 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-client-element-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + # verify.yml runs as its own play, where the role's defaults are out of scope, + # so paths and runtime settings read there are pinned explicitly. + matrix_client_element_data_path: /matrix/client-element + matrix_client_element_container_network: matrix-client-element-molecule + matrix_client_element_container_port: 18081 + matrix_client_element_container_http_host_bind_port: '' + + # Keep the scenario on the prebuilt image and avoid all optional downloads. + matrix_client_element_container_image_self_build: false + matrix_client_element_themes_enabled: false + matrix_client_element_location_sharing_enabled: false + + # Exercise the labels with a non-root route, compression, plain HTTP and a + # scenario marker. No Traefik instance is needed to inspect attached labels. + matrix_client_element_hostname: element-web.molecule.local + matrix_client_element_path_prefix: /molecule-element + matrix_client_element_container_labels_traefik_enabled: true + matrix_client_element_container_labels_traefik_entrypoints: web + matrix_client_element_container_labels_traefik_compression_middleware_enabled: true + matrix_client_element_container_labels_traefik_compression_middleware_name: molecule-compress@file + matrix_client_element_container_labels_traefik_priority: 73 + matrix_client_element_container_labels_traefik_additional_response_headers_custom: + X-Molecule-Element: rendered + matrix_client_element_container_labels_additional_labels: | + molecule.scenario=matrix-client-element + + # These values differ from both role and Element defaults. Element Web is a + # static client and does not contact any of these endpoints during startup. + matrix_client_element_default_hs_url: https://homeserver.molecule.invalid + matrix_client_element_default_server_name: alternate.molecule.local + matrix_client_element_default_is_url: https://identity.molecule.invalid + matrix_client_element_disable_custom_urls: false + matrix_client_element_disable_guests: false + matrix_client_element_mobile_guide_app_variant: molecule-element + matrix_client_element_default_theme: dark + matrix_client_element_default_country_code: DE + matrix_client_element_permalink_prefix: https://links.molecule.invalid + matrix_client_element_bug_report_endpoint_url: https://bugs.molecule.invalid/report + matrix_client_element_room_directory_servers: + - directory-one.molecule.local + - directory-two.molecule.local + matrix_client_element_brand: Molecule Element + matrix_client_element_branding_auth_footer_links: + - text: Molecule help + url: https://help.molecule.invalid + matrix_client_element_branding_auth_header_logo_url: https://assets.molecule.invalid/logo.svg + matrix_client_element_branding_welcome_background_url: https://assets.molecule.invalid/background.svg + + matrix_client_element_integrations_ui_url: https://integrations.molecule.invalid/ui + matrix_client_element_integrations_rest_url: https://integrations.molecule.invalid/api + matrix_client_element_integrations_widgets_urls: + - https://integrations.molecule.invalid/widgets + matrix_client_element_integrations_jitsi_widget_url: https://integrations.molecule.invalid/jitsi + + matrix_client_element_features_feature_group_calls: true + matrix_client_element_features_feature_oidc_native_flow: true + matrix_client_element_features_custom: + feature_molecule_scenario: labs + + matrix_client_element_element_call_enabled: true + matrix_client_element_element_call_url: https://call.molecule.invalid + matrix_client_element_element_call_participant_limit: 23 + matrix_client_element_element_call_brand: Molecule Call + matrix_client_element_element_call_use_exclusively: false + + # This custom theme is data embedded in config.json; themes_enabled remains false, + # so the role does not clone the external theme repository. + matrix_client_element_setting_defaults_custom_themes: + - name: Molecule Midnight + is_dark: true + colors: + accent-color: '#123456' + + matrix_client_element_configuration_extension_json: | + { + "disable_3pid_login": true, + "disable_login_language_selector": true, + "molecule_extension": { + "enabled": true, + "marker": "element-config-extension", + "sequence": 42 + } + } + + matrix_client_element_environment_variables_extension: | + MOLECULE_ELEMENT_MARKER=environment-reached + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-client-element/molecule/default/prepare.yml b/roles/custom/matrix-client-element/molecule/default/prepare.yml new file mode 100644 index 000000000..695f8bfa2 --- /dev/null +++ b/roles/custom/matrix-client-element/molecule/default/prepare.yml @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-client-element Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks resolve owner and group by name. matrix-base creates + # these during a real deployment, so the scenario supplies that prerequisite. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" diff --git a/roles/custom/matrix-client-element/molecule/default/requirements.yml b/roles/custom/matrix-client-element/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-client-element/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-client-element/molecule/default/verify.yml b/roles/custom/matrix-client-element/molecule/default/verify.yml new file mode 100644 index 000000000..694b340e0 --- /dev/null +++ b/roles/custom/matrix-client-element/molecule/default/verify.yml @@ -0,0 +1,323 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Verify matrix-client-element + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + + tasks: + # Load the shipped version independently of the scenario. The expected image + # below is therefore advanced by the role's own version bump, not a test pin. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_client_element_role_defaults + + - name: Wait for the matrix-client-element service to become active + ansible.builtin.systemd_service: + name: matrix-client-element.service + register: matrix_client_element_service + until: matrix_client_element_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_client_element_service.status.ActiveState == 'active' + - matrix_client_element_service.status.NRestarts is defined + - matrix_client_element_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-client-element.service is + {{ matrix_client_element_service.status.ActiveState | default('unknown') }} + after {{ matrix_client_element_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-client-element.service is active and has not restarted" + + # Probe over the private container network. The role intentionally publishes + # no host port, matching the path Traefik uses in a real deployment. + - name: Fetch Element Web's root document + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_client_element_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - "http://matrix-client-element:{{ matrix_client_element_container_port }}/" + register: matrix_client_element_root_response + changed_when: false + until: "'HTTP_STATUS=200' in matrix_client_element_root_response.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the root endpoint serves the Element application + ansible.builtin.assert: + that: + - "'HTTP_STATUS=200' in matrix_client_element_root_response.stdout" + - "'Element' in matrix_client_element_root_response.stdout" + fail_msg: >- + Element Web did not serve its application root on the configured internal + port ({{ matrix_client_element_root_response.stdout | default('no output') }}) + success_msg: "Element Web serves its application root on the configured internal port" + + - name: Fetch Element Web's served configuration + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_client_element_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - "http://matrix-client-element:{{ matrix_client_element_container_port }}/config.json" + register: matrix_client_element_served_config_response + changed_when: false + failed_when: false + + - name: Assert config.json is served successfully + ansible.builtin.assert: + that: + - "'HTTP_STATUS=200' in matrix_client_element_served_config_response.stdout" + fail_msg: >- + Element Web did not serve config.json on the configured internal port + ({{ matrix_client_element_served_config_response.stdout | default('no output') }}) + success_msg: "Element Web serves config.json on the configured internal port" + + - name: Read the rendered configuration + ansible.builtin.slurp: + src: "{{ matrix_client_element_data_path }}/config.json" + register: matrix_client_element_rendered_config_file + + - name: Parse the served and rendered configurations + ansible.builtin.set_fact: + matrix_client_element_served_config: >- + {{ matrix_client_element_served_config_response.stdout | regex_replace('HTTP_STATUS=[0-9]+$', '') | trim | from_json }} + matrix_client_element_rendered_config: >- + {{ matrix_client_element_rendered_config_file.content | b64decode | from_json }} + + - name: Assert the served configuration is the file the role rendered + ansible.builtin.assert: + that: + - matrix_client_element_served_config == matrix_client_element_rendered_config + fail_msg: "The config.json served by Element differs from the file the role rendered" + success_msg: "Element serves the exact configuration the role rendered" + + - name: Assert the rendered configuration carries the homeserver identity + ansible.builtin.assert: + that: + - matrix_client_element_rendered_config.default_server_config['m.homeserver'].base_url == matrix_client_element_default_hs_url + - matrix_client_element_rendered_config.default_server_config['m.homeserver'].server_name == matrix_client_element_default_server_name + - matrix_client_element_rendered_config.default_server_config['m.identity_server'].base_url == matrix_client_element_default_is_url + fail_msg: "The rendered configuration does not carry the scenario's homeserver identity" + success_msg: "The rendered configuration carries the scenario's homeserver identity" + + - name: Assert the rendered configuration carries the appearance and client behavior + ansible.builtin.assert: + that: + - matrix_client_element_rendered_config.brand == matrix_client_element_brand + - matrix_client_element_rendered_config.default_theme == matrix_client_element_default_theme + - matrix_client_element_rendered_config.disable_custom_urls == matrix_client_element_disable_custom_urls + - matrix_client_element_rendered_config.disable_guests == matrix_client_element_disable_guests + - matrix_client_element_rendered_config.default_country_code == matrix_client_element_default_country_code + - matrix_client_element_rendered_config.setting_defaults.custom_themes[0].name == 'Molecule Midnight' + - matrix_client_element_rendered_config.branding.auth_footer_links[0].text == 'Molecule help' + - matrix_client_element_rendered_config.branding.auth_header_logo_url == matrix_client_element_branding_auth_header_logo_url + fail_msg: "The rendered configuration does not carry the scenario's appearance and client behavior" + success_msg: "The rendered configuration carries the scenario's appearance and client behavior" + + - name: Assert the rendered configuration carries the integration endpoints + ansible.builtin.assert: + that: + - matrix_client_element_rendered_config.integrations_ui_url == matrix_client_element_integrations_ui_url + - matrix_client_element_rendered_config.integrations_rest_url == matrix_client_element_integrations_rest_url + - matrix_client_element_rendered_config.integrations_widgets_urls == matrix_client_element_integrations_widgets_urls + - matrix_client_element_rendered_config.integrations_jitsi_widget_url == matrix_client_element_integrations_jitsi_widget_url + fail_msg: "The rendered configuration does not carry the scenario's integration endpoints" + success_msg: "The rendered configuration carries the scenario's integration endpoints" + + - name: Assert the rendered configuration carries the feature and Element Call settings + ansible.builtin.assert: + that: + - matrix_client_element_rendered_config.features.feature_group_calls == true + - matrix_client_element_rendered_config.features.feature_oidc_native_flow == true + - matrix_client_element_rendered_config.features.feature_molecule_scenario == 'labs' + - matrix_client_element_rendered_config.element_call.url == matrix_client_element_element_call_url + - matrix_client_element_rendered_config.element_call.participant_limit == matrix_client_element_element_call_participant_limit + - matrix_client_element_rendered_config.element_call.brand == matrix_client_element_element_call_brand + # Element Web documents the omitted use_exclusively setting as false; + # the role deliberately leaves this default-valued key out of lean JSON. + - "'use_exclusively' not in matrix_client_element_rendered_config.element_call" + fail_msg: "The rendered configuration does not carry the scenario's feature and Element Call settings" + success_msg: "The rendered configuration carries the scenario's feature and Element Call settings" + + - name: Assert the configuration extension was merged structurally + ansible.builtin.assert: + that: + - matrix_client_element_rendered_config.disable_3pid_login == true + - matrix_client_element_rendered_config.disable_login_language_selector == true + - matrix_client_element_rendered_config.molecule_extension.enabled == true + - matrix_client_element_rendered_config.molecule_extension.marker == 'element-config-extension' + - matrix_client_element_rendered_config.molecule_extension.sequence == 42 + fail_msg: "The configuration extension was not merged under the expected keys" + success_msg: "The configuration extension was merged structurally" + + - name: Read the environment file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_client_element_data_path }}/env" + register: matrix_client_element_env_file + + - name: Initialize the parsed environment + ansible.builtin.set_fact: + matrix_client_element_env_parsed: {} + + - name: Parse the rendered environment + ansible.builtin.set_fact: + matrix_client_element_env_parsed: >- + {{ matrix_client_element_env_parsed | combine({item.split('=', 1)[0]: item.split('=', 1)[1]}) }} + loop: "{{ (matrix_client_element_env_file.content | b64decode).splitlines() | reject('equalto', '') }}" + when: "'=' in item" + no_log: true + + - name: Inspect the running Element container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-client-element + register: matrix_client_element_container_inspect_command + changed_when: false + + - name: Parse the running container inspection + ansible.builtin.set_fact: + matrix_client_element_container: "{{ (matrix_client_element_container_inspect_command.stdout | from_json)[0] }}" + + - name: Assert the rendered environment file carries the scenario values + ansible.builtin.assert: + that: + - matrix_client_element_env_parsed.ELEMENT_WEB_PORT == matrix_client_element_container_port | string + - matrix_client_element_env_parsed.MOLECULE_ELEMENT_MARKER == 'environment-reached' + fail_msg: "The parsed environment file does not carry the scenario's values" + success_msg: "The parsed environment file carries the scenario's values" + + - name: Assert the configured environment reached the running container + ansible.builtin.assert: + that: + - "('ELEMENT_WEB_PORT=' ~ (matrix_client_element_container_port | string)) in matrix_client_element_container.Config.Env" + - "'MOLECULE_ELEMENT_MARKER=environment-reached' in matrix_client_element_container.Config.Env" + fail_msg: "The running container environment does not carry the scenario's values" + success_msg: "The configured environment reached the running container" + + - name: Read the labels file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_client_element_data_path }}/labels" + register: matrix_client_element_labels_file + + - name: Initialize the parsed labels + ansible.builtin.set_fact: + matrix_client_element_labels_parsed: {} + + - name: Parse the rendered labels + ansible.builtin.set_fact: + matrix_client_element_labels_parsed: >- + {{ matrix_client_element_labels_parsed | combine({item.split('=', 1)[0]: item.split('=', 1)[1]}) }} + loop: "{{ (matrix_client_element_labels_file.content | b64decode).splitlines() | reject('equalto', '') }}" + when: "'=' in item" + no_log: true + + - name: Assert the rendered labels carry the routing configuration + ansible.builtin.assert: + that: + - matrix_client_element_labels_parsed['traefik.enable'] == 'true' + - matrix_client_element_labels_parsed['traefik.docker.network'] == matrix_client_element_container_network + - matrix_client_element_labels_parsed['traefik.http.services.matrix-client-element.loadbalancer.server.port'] == matrix_client_element_container_port | string + - "('Host(`' ~ matrix_client_element_hostname ~ '`)') in matrix_client_element_labels_parsed['traefik.http.routers.matrix-client-element.rule']" + - "('PathPrefix(`' ~ matrix_client_element_path_prefix ~ '`)') in matrix_client_element_labels_parsed['traefik.http.routers.matrix-client-element.rule']" + - matrix_client_element_labels_parsed['traefik.http.routers.matrix-client-element.priority'] == '73' + - matrix_client_element_labels_parsed['traefik.http.routers.matrix-client-element.tls'] == 'false' + - "matrix_client_element_container_labels_traefik_compression_middleware_name in matrix_client_element_labels_parsed['traefik.http.routers.matrix-client-element.middlewares']" + - matrix_client_element_labels_parsed['traefik.http.middlewares.matrix-client-element-add-headers.headers.customresponseheaders.X-Molecule-Element'] == 'rendered' + - matrix_client_element_labels_parsed['molecule.scenario'] == 'matrix-client-element' + fail_msg: "The rendered labels do not carry the scenario's routing configuration" + success_msg: "The rendered labels carry the scenario's routing configuration" + + - name: Assert the rendered labels are attached to the running container + ansible.builtin.assert: + that: + - matrix_client_element_container.Config.Labels['traefik.enable'] == 'true' + - matrix_client_element_container.Config.Labels['traefik.docker.network'] == matrix_client_element_container_network + - matrix_client_element_container.Config.Labels['traefik.http.services.matrix-client-element.loadbalancer.server.port'] == matrix_client_element_container_port | string + - matrix_client_element_container.Config.Labels['molecule.scenario'] == 'matrix-client-element' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The running container carries the labels the role rendered" + + - name: Assert the running container uses the exact image and version the role pins + ansible.builtin.assert: + that: + - matrix_client_element_container.Config.Image == matrix_client_element_expected_image + fail_msg: >- + The running container uses {{ matrix_client_element_container.Config.Image }}, + expected {{ matrix_client_element_expected_image }} + success_msg: "The running container uses the exact image and version defaults/main.yml pins" + vars: + matrix_client_element_expected_image: >- + {{ matrix_client_element_role_defaults.matrix_client_element_container_image_registry_prefix_upstream_default }}element-hq/element-web:{{ matrix_client_element_role_defaults.matrix_client_element_version }} + + - name: Assert the running container uses the configured UID and GID + ansible.builtin.assert: + that: + - matrix_client_element_container.Config.User == (matrix_user_uid | string) ~ ':' ~ (matrix_user_gid | string) + fail_msg: >- + The running container uses {{ matrix_client_element_container.Config.User }}, + expected {{ matrix_user_uid }}:{{ matrix_user_gid }} + success_msg: "The running container uses the configured UID and GID" + + - name: Assert the running container has a read-only root filesystem + ansible.builtin.assert: + that: + - matrix_client_element_container.HostConfig.ReadonlyRootfs == true + fail_msg: "The running container's root filesystem is writable" + success_msg: "The running container has a read-only root filesystem" + + - name: Assert all intended writable paths are tmpfs mounts + ansible.builtin.assert: + that: + - "'/tmp' in matrix_client_element_container.HostConfig.Tmpfs" + - "'/var/cache/nginx' in matrix_client_element_container.HostConfig.Tmpfs" + - "'/var/run' in matrix_client_element_container.HostConfig.Tmpfs" + - "'/tmp/element-web-config' in matrix_client_element_container.HostConfig.Tmpfs" + - "'/etc/nginx/conf.d' in matrix_client_element_container.HostConfig.Tmpfs" + fail_msg: "The running container is missing one or more intended tmpfs mounts" + success_msg: "All intended writable paths are tmpfs mounts" + + - name: Assert the running container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_client_element_container.NetworkSettings.Networks.keys() | list | length == 1 + - matrix_client_element_container_network in matrix_client_element_container.NetworkSettings.Networks + fail_msg: >- + The running container is attached to unexpected networks: + {{ matrix_client_element_container.NetworkSettings.Networks.keys() | list }} + success_msg: "The running container is attached only to its dedicated network" + + - name: Assert the running container publishes no host ports + ansible.builtin.assert: + that: + - matrix_client_element_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: "The running container unexpectedly publishes a host port" + success_msg: "The running container publishes no host ports" diff --git a/roles/custom/matrix-client-element/tasks/prepare_themes.yml b/roles/custom/matrix-client-element/tasks/prepare_themes.yml index 56ddb3403..133c8a803 100644 --- a/roles/custom/matrix-client-element/tasks/prepare_themes.yml +++ b/roles/custom/matrix-client-element/tasks/prepare_themes.yml @@ -15,11 +15,17 @@ delegate_to: 127.0.0.1 become: false block: + # This checkout lives on the Ansible controller, so we cannot correct its ownership like we do for checkouts on the server. + # Marking it as a safe directory keeps git's dubious-ownership protection from failing the task when the playbook directory belongs to another user. - name: Ensure Element Web themes repository is pulled ansible.builtin.git: repo: "{{ matrix_client_element_themes_repository_url }}" version: "{{ matrix_client_element_themes_repository_version }}" dest: "{{ role_path }}/files/scratchpad/themes" + environment: + GIT_CONFIG_COUNT: "1" + GIT_CONFIG_KEY_0: safe.directory + GIT_CONFIG_VALUE_0: "{{ role_path }}/files/scratchpad/themes" - name: Find all Element Web theme files ansible.builtin.find: diff --git a/roles/custom/matrix-client-element/tasks/setup_install.yml b/roles/custom/matrix-client-element/tasks/setup_install.yml index 314f7241f..116d50f89 100644 --- a/roles/custom/matrix-client-element/tasks/setup_install.yml +++ b/roles/custom/matrix-client-element/tasks/setup_install.yml @@ -24,17 +24,25 @@ when: "item.when | bool" - name: Ensure Element Web Docker image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_client_element_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_client_element_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_client_element_container_image_force_pull }}" + pull: always when: "not matrix_client_element_container_image_self_build | bool" register: matrix_client_element_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_client_element_container_image_pull_result is not failed +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Element Web repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_client_element_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_client_element_container_image_self_build | bool" + - name: Ensure Element Web repository is present on self-build ansible.builtin.git: repo: "{{ matrix_client_element_container_image_self_build_repo }}" @@ -65,7 +73,7 @@ cmd: |- {{ devture_systemd_docker_base_host_command_docker }} buildx build --tag={{ matrix_client_element_container_image }} - --file={{ matrix_client_element_container_src_files_path }}/Dockerfile + --file={{ matrix_client_element_container_src_dockerfile_path }} {{ matrix_client_element_container_src_files_path }} changed_when: true when: matrix_client_element_container_image_self_build | bool @@ -99,7 +107,6 @@ with_items: - {src: "{{ role_path }}/templates/labels.j2", name: "labels"} - {src: "{{ role_path }}/templates/env.j2", name: "env"} - - {src: "{{ matrix_client_element_page_template_welcome_path }}", name: "welcome.html"} - {src: "{{ matrix_client_element_embedded_pages_home_path }}", name: "home.html"} when: "item.src is not none" register: matrix_client_element_support_files_result @@ -115,9 +122,12 @@ state: absent with_items: - {src: "{{ matrix_client_element_embedded_pages_home_path }}", name: "home.html"} + # The playbook no longer ships a custom welcome.html (Element Web renders its own built-in welcome page). + - {src: ~, name: "welcome.html"} when: "item.src is none" - name: Ensure Element Web container network is created + when: matrix_client_element_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_client_element_container_network }}" diff --git a/roles/custom/matrix-client-element/tasks/validate_config.yml b/roles/custom/matrix-client-element/tasks/validate_config.yml index cf6106cd2..0c6b091bf 100644 --- a/roles/custom/matrix-client-element/tasks/validate_config.yml +++ b/roles/custom/matrix-client-element/tasks/validate_config.yml @@ -29,6 +29,11 @@ - {'old': 'matrix_client_element_docker_image_registry_prefix_upstream', 'new': 'matrix_client_element_container_image_registry_prefix_upstream'} - {'old': 'matrix_client_element_docker_image_registry_prefix_upstream_default', 'new': 'matrix_client_element_container_image_registry_prefix_upstream_default'} - {'old': 'matrix_client_element_docker_src_files_path', 'new': 'matrix_client_element_container_src_files_path'} + - {'old': 'matrix_client_element_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_client_element_welcome_headline', 'new': '<removed> (Element Web now renders its own built-in welcome page and no longer loads the custom welcome.html this variable applied to; a logo and background can still be customized via matrix_client_element_branding_auth_header_logo_url and matrix_client_element_branding_welcome_background_url, and a fully custom page can be self-hosted and wired via embedded_pages.welcome_url in matrix_client_element_configuration_extension_json)'} + - {'old': 'matrix_client_element_welcome_text', 'new': '<removed> (Element Web now renders its own built-in welcome page and no longer loads the custom welcome.html this variable applied to; see matrix_client_element_welcome_headline for alternatives)'} + - {'old': 'matrix_client_element_welcome_logo_link', 'new': '<removed> (Element Web now renders its own built-in welcome page and no longer loads the custom welcome.html this variable applied to; see matrix_client_element_welcome_headline for alternatives)'} + - {'old': 'matrix_client_element_page_template_welcome_path', 'new': '<removed> (Element Web now renders its own built-in welcome page; a fully custom page can be self-hosted and wired via embedded_pages.welcome_url in matrix_client_element_configuration_extension_json)'} - name: Fail if required Element Web settings not defined ansible.builtin.fail: diff --git a/roles/custom/matrix-client-element/templates/labels.j2 b/roles/custom/matrix-client-element/templates/labels.j2 index 2d12275e5..64f8edc1b 100644 --- a/roles/custom/matrix-client-element/templates/labels.j2 +++ b/roles/custom/matrix-client-element/templates/labels.j2 @@ -11,7 +11,7 @@ traefik.enable=true traefik.docker.network={{ matrix_client_element_container_labels_traefik_docker_network }} {% endif %} -traefik.http.services.matrix-client-element.loadbalancer.server.port=8080 +traefik.http.services.matrix-client-element.loadbalancer.server.port={{ matrix_client_element_container_port }} {% set middlewares = [] %} @@ -51,6 +51,23 @@ traefik.http.routers.matrix-client-element.tls={{ matrix_client_element_containe traefik.http.routers.matrix-client-element.tls.certResolver={{ matrix_client_element_container_labels_traefik_tls_certResolver }} {% endif %} +{% if matrix_client_element_location_sharing_enabled %} +{# + A dedicated router for the map style file, which attaches an Access-Control-Allow-Origin header. + Element Desktop loads the map style from a `vector://vector` origin, so it needs to be allowed cross-origin access. +#} +traefik.http.middlewares.matrix-client-element-map-style-add-headers.headers.customresponseheaders.Access-Control-Allow-Origin={{ matrix_client_element_location_sharing_map_style_access_control_allow_origin }} + +traefik.http.routers.matrix-client-element-map-style.rule={{ matrix_client_element_container_labels_traefik_rule }} && Path(`{{ (matrix_client_element_container_labels_traefik_path_prefix ~ '/map_style.json') | regex_replace('^//', '/') }}`) +traefik.http.routers.matrix-client-element-map-style.service=matrix-client-element +traefik.http.routers.matrix-client-element-map-style.middlewares={{ (middlewares + ['matrix-client-element-map-style-add-headers']) | join(',') }} +traefik.http.routers.matrix-client-element-map-style.entrypoints={{ matrix_client_element_container_labels_traefik_entrypoints }} +traefik.http.routers.matrix-client-element-map-style.tls={{ matrix_client_element_container_labels_traefik_tls | to_json }} +{% if matrix_client_element_container_labels_traefik_tls %} +traefik.http.routers.matrix-client-element-map-style.tls.certResolver={{ matrix_client_element_container_labels_traefik_tls_certResolver }} +{% endif %} +{% endif %} + {% endif %} {{ matrix_client_element_container_labels_additional_labels }} diff --git a/roles/custom/matrix-client-element/templates/systemd/matrix-client-element.service.j2 b/roles/custom/matrix-client-element/templates/systemd/matrix-client-element.service.j2 index 77ffe3e03..74726330e 100644 --- a/roles/custom/matrix-client-element/templates/systemd/matrix-client-element.service.j2 +++ b/roles/custom/matrix-client-element/templates/systemd/matrix-client-element.service.j2 @@ -43,7 +43,6 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% if matrix_client_element_embedded_pages_home_path is not none %} --mount type=bind,src={{ matrix_client_element_data_path }}/home.html,dst=/app/home.html,ro \ {% endif %} - --mount type=bind,src={{ matrix_client_element_data_path }}/welcome.html,dst=/app/welcome.html,ro \ {% if matrix_client_element_container_healthcheck_cmd %} --health-cmd="{{ matrix_client_element_container_healthcheck_cmd }}" \ {% endif %} @@ -52,9 +51,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_client_element_container_image }} +{% if matrix_client_element_container_network != 'host' %} {% for network in matrix_client_element_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-client-element {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-client-element diff --git a/roles/custom/matrix-client-element/templates/welcome.html.j2 b/roles/custom/matrix-client-element/templates/welcome.html.j2 deleted file mode 100644 index d505e2fa2..000000000 --- a/roles/custom/matrix-client-element/templates/welcome.html.j2 +++ /dev/null @@ -1,205 +0,0 @@ -#jinja2: lstrip_blocks: True -<style type="text/css"> - -/* we deliberately inline style here to avoid flash-of-CSS problems, and to avoid - * voodoo where we have to set display: none by default - */ - -h1::after { - content: "!"; -} - -.mx_Parent { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - text-align: center; - padding: 25px 35px; - color: #2e2f32; -} - -.mx_Logo { - height: 54px; - margin-top: 2px; -} - -.mx_ButtonGroup { - margin-top: 10px; -} - -.mx_ButtonRow { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - justify-content: space-between; - box-sizing: border-box; - margin: 12px 0 0; -} - -.mx_ButtonRow > * { - margin: 0 10px; -} - -.mx_ButtonRow > *:first-child { - margin-left: 0; -} - -.mx_ButtonRow > *:last-child { - margin-right: 0; -} - -.mx_ButtonParent { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - padding: 10px 20px; - -webkit-box-orient: horizontal; - -webkit-box-direction: normal; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-box-align: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - border-radius: 4px; - width: 150px; - background-repeat: no-repeat; - background-position: 10px center; - text-decoration: none; - color: #2e2f32 !important; -} - -.mx_ButtonLabel { - margin-left: 20px; -} - -.mx_Header_title { - font-size: 24px; - font-weight: 600; - margin: 20px 0 0; -} - -.mx_Header_subtitle { - font-size: 12px; - font-weight: normal; - margin: 8px 0 0; -} - -.mx_ButtonSignIn { - background-color: #368BD6; - color: white !important; -} - -.mx_ButtonCreateAccount { - background-color: #0DBD8B; - color: white !important; -} - -.mx_SecondaryButton { - background-color: #FFFFFF; - color: #2E2F32; -} - -.mx_Button_iconSignIn { - background-image: url('welcome/images/icon-sign-in.svg'); -} -.mx_Button_iconCreateAccount { - background-image: url('welcome/images/icon-create-account.svg'); -} -.mx_Button_iconHelp { - background-image: url('welcome/images/icon-help.svg'); -} -.mx_Button_iconRoomDirectory { - background-image: url('welcome/images/icon-room-directory.svg'); -} - -/* -.mx_WelcomePage_loggedIn is applied by EmbeddedPage from the Welcome component -If it is set on the page, we should show the buttons. Otherwise, we have to assume -we don't have an account and should hide them. No account == no guest account either. - */ -.mx_WelcomePage:not(.mx_WelcomePage_loggedIn) .mx_WelcomePage_guestFunctions { - display: none; -} - -.mx_ButtonRow.mx_WelcomePage_guestFunctions { - margin-top: 20px; -} -.mx_ButtonRow.mx_WelcomePage_guestFunctions > div { - margin: 0 auto; -} - -@media only screen and (max-width: 480px) { - .mx_ButtonRow { - flex-direction: column; - } - - .mx_ButtonRow > * { - margin: 0 0 10px 0; - } -} - -</style> - -<div class="mx_Parent"> - <a href="{{ matrix_client_element_welcome_logo_link }}" target="_blank" rel="noopener"> - <img src="{{ matrix_client_element_welcome_logo }}" alt="" class="mx_Logo"/> - </a> - <h1 class="mx_Header_title">{{ matrix_client_element_welcome_headline }}</h1> - <h4 class="mx_Header_subtitle">{{ matrix_client_element_welcome_text }}</h4> - <div class="mx_ButtonGroup"> - <div class="mx_ButtonRow"> - <a href="#/login" class="mx_ButtonParent mx_ButtonSignIn mx_Button_iconSignIn"> - <div class="mx_ButtonLabel">_t("action|sign_in")</div> - </a> -{% if matrix_client_element_registration_enabled %} - <a href="#/register" class="mx_ButtonParent mx_ButtonCreateAccount mx_Button_iconCreateAccount"> - <div class="mx_ButtonLabel">_t("action|create_account")</div> - </a> -{% endif %} - </div> -{% if matrix_client_element_disable_guests != true %} - <!-- The comments below are meant to be used by Ansible as a quick way - to strip out the marked content when desired. - See https://github.com/element-hq/riot-web/issues/8622. - TODO: Convert to config option if possible. --> - <!-- BEGIN Ansible: Remove these lines when guest access is disabled --> - <div class="mx_ButtonRow mx_WelcomePage_guestFunctions"> - <div> - <a href="#/directory" class="mx_ButtonParent mx_SecondaryButton mx_Button_iconRoomDirectory"> - <div class="mx_ButtonLabel">_t("action|explore_rooms")</div> - </a> - </div> - </div> - <!-- END Ansible: Remove these lines when guest access is disabled --> -{% endif %} - </div> -</div> diff --git a/roles/custom/matrix-client-element/templates/welcome.html.j2.license b/roles/custom/matrix-client-element/templates/welcome.html.j2.license deleted file mode 100644 index 8338f12af..000000000 --- a/roles/custom/matrix-client-element/templates/welcome.html.j2.license +++ /dev/null @@ -1,9 +0,0 @@ -SPDX-FileCopyrightText: 2019 Daniel Hoffend -SPDX-FileCopyrightText: 2019 Hugues De Keyzer -SPDX-FileCopyrightText: 2020 - 2022 Slavi Pantaleev -SPDX-FileCopyrightText: 2020 Clement Renaud -SPDX-FileCopyrightText: 2020 Stefan Warnat -SPDX-FileCopyrightText: 2023 Pierre 'McFly' Marty -SPDX-FileCopyrightText: 2024 MDAD project contributors - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-client-fluffychat/defaults/main.yml b/roles/custom/matrix-client-fluffychat/defaults/main.yml index c1a8e511f..ad51321b8 100644 --- a/roles/custom/matrix-client-fluffychat/defaults/main.yml +++ b/roles/custom/matrix-client-fluffychat/defaults/main.yml @@ -13,12 +13,11 @@ matrix_client_fluffychat_container_image_self_build_repo: "https://github.com/et matrix_client_fluffychat_container_image_self_build_version: "{{ 'main' if matrix_client_fluffychat_version == 'latest' else matrix_client_fluffychat_version }}" # renovate: datasource=docker depName=ghcr.io/etkecc/fluffychat-web -matrix_client_fluffychat_version: v2.5.1 +matrix_client_fluffychat_version: v2.9.1 matrix_client_fluffychat_container_image: "{{ matrix_client_fluffychat_container_image_registry_prefix }}etkecc/fluffychat-web:{{ matrix_client_fluffychat_version }}" matrix_client_fluffychat_container_image_registry_prefix: "{{ 'localhost/' if matrix_client_fluffychat_container_image_self_build else matrix_client_fluffychat_container_image_registry_prefix_upstream }}" matrix_client_fluffychat_container_image_registry_prefix_upstream: "{{ matrix_client_fluffychat_container_image_registry_prefix_upstream_default }}" matrix_client_fluffychat_container_image_registry_prefix_upstream_default: ghcr.io/ -matrix_client_fluffychat_container_image_force_pull: "{{ matrix_client_fluffychat_container_image.endswith(':latest') }}" matrix_client_fluffychat_base_path: "{{ matrix_base_data_path }}/client-fluffychat" matrix_client_fluffychat_config_path: "{{ matrix_client_fluffychat_base_path }}/config" @@ -37,7 +36,7 @@ matrix_client_fluffychat_container_additional_networks_custom: [] # Configures the port number used inside the container image. matrix_client_fluffychat_container_http_port: 8080 -# Controls whether the matrix-client-fluffychat container exposes its HTTP port (tcp/8080 in the container). +# Controls whether the matrix-client-fluffychat container exposes its configured HTTP port (tcp/8080 by default). # # Takes an "<ip>:<port>" or "<port>" value (e.g. "127.0.0.1:8080"), or empty string to not expose. # diff --git a/roles/custom/matrix-client-fluffychat/molecule/default/converge.yml b/roles/custom/matrix-client-fluffychat/molecule/default/converge.yml new file mode 100644 index 000000000..67710e140 --- /dev/null +++ b/roles/custom/matrix-client-fluffychat/molecule/default/converge.yml @@ -0,0 +1,50 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-client-fluffychat Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include base roles for matrix-client-fluffychat Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + loop_control: + loop_var: role_name + + # main.yml also invokes the separately-tagged public self-check. In the full + # playbook that runs only after systemd_service_manager has started services. + - name: Include matrix-client-fluffychat setup task files + ansible.builtin.include_role: + name: "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + public: true + tasks_from: "{{ role_task_file }}" + loop: + - validate_config.yml + - setup_install.yml + loop_control: + loop_var: role_task_file + +# The component role installs the unit; the full playbook's systemd service manager +# starts it. Keep the role-scoped scenario at the same boundary and start it directly. +- name: Ensure matrix-client-fluffychat is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the matrix-client-fluffychat systemd service is started + ansible.builtin.systemd_service: + name: matrix-client-fluffychat.service + state: started diff --git a/roles/custom/matrix-client-fluffychat/molecule/default/molecule.yml b/roles/custom/matrix-client-fluffychat/molecule/default/molecule.yml new file mode 100644 index 000000000..8d28f756c --- /dev/null +++ b/roles/custom/matrix-client-fluffychat/molecule/default/molecule.yml @@ -0,0 +1,79 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-client-fluffychat-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + # Keep all support files outside the path derived from matrix_base_data_path, + # proving that the role consistently uses its configured storage contract. + matrix_client_fluffychat_base_path: /matrix/molecule-client-fluffychat + matrix_client_fluffychat_config_path: /matrix/molecule-client-fluffychat/browser-config + + matrix_client_fluffychat_container_network: matrix-client-fluffychat-molecule + + # The image defaults to 8080, so this proves the role configures the listener itself. + matrix_client_fluffychat_container_http_port: 8765 + + # The live /config.json response is the weight-bearing proof that this + # non-default setting reached the browser client through the role's mount. + matrix_client_fluffychat_config_defaultHomeserver: homeserver.fluffy.molecule.local + + # Exercise non-default public routing and generated response-header labels. + matrix_client_fluffychat_hostname: chat.fluffy.molecule.local + matrix_client_fluffychat_path_prefix: /fluffy + matrix_client_fluffychat_container_labels_traefik_enabled: true + matrix_client_fluffychat_container_labels_traefik_priority: 731 + matrix_client_fluffychat_container_labels_traefik_entrypoints: web + matrix_client_fluffychat_container_labels_traefik_tls: false + matrix_client_fluffychat_http_header_xss_protection: "0" + matrix_client_fluffychat_http_header_content_type_options: molecule-nosniff + matrix_client_fluffychat_http_header_content_security_policy: "frame-ancestors https://embed.molecule.local" + matrix_client_fluffychat_http_header_content_permission_policy: "camera=(self)" + matrix_client_fluffychat_container_labels_additional_labels: | + molecule.fluffychat.coverage=enabled + + # Make the generic escape hatch observable in the running container. + matrix_client_fluffychat_container_extra_arguments: + - --hostname=fluffychat-molecule-runtime + - --label=molecule.fluffychat.extra-argument=reached + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-client-fluffychat/molecule/default/prepare.yml b/roles/custom/matrix-client-fluffychat/molecule/default/prepare.yml new file mode 100644 index 000000000..8fc4f73ae --- /dev/null +++ b/roles/custom/matrix-client-fluffychat/molecule/default/prepare.yml @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-client-fluffychat Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # matrix-base creates this identity in a full deployment. The role's file tasks + # resolve owner and group by name, so the role-scoped test provides it directly. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" diff --git a/roles/custom/matrix-client-fluffychat/molecule/default/requirements.yml b/roles/custom/matrix-client-fluffychat/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-client-fluffychat/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-client-fluffychat/molecule/default/verify.yml b/roles/custom/matrix-client-fluffychat/molecule/default/verify.yml new file mode 100644 index 000000000..d2e7eb40e --- /dev/null +++ b/roles/custom/matrix-client-fluffychat/molecule/default/verify.yml @@ -0,0 +1,382 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# FluffyChat Web is a static browser client. The live JSON configuration and a real +# application asset are the weight-bearing probes; no homeserver account is needed. +- name: Verify matrix-client-fluffychat + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + matrix_client_fluffychat_root_body: "{{ matrix_client_fluffychat_root_http.stdout_lines[:-1] | join('\n') }}" + matrix_client_fluffychat_runtime: "{{ (matrix_client_fluffychat_container_inspect.stdout | from_json) | first }}" + gather_facts: false + + tasks: + # Load the pin independently of the scenario so a role version bump advances + # the expected image instead of comparing two duplicated test values. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_client_fluffychat_role_defaults + + - name: Wait for the matrix-client-fluffychat service to become active + ansible.builtin.systemd_service: + name: matrix-client-fluffychat.service + register: matrix_client_fluffychat_service + until: matrix_client_fluffychat_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes ActiveState alone green even during a crash loop. + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_client_fluffychat_service.status.ActiveState == 'active' + - matrix_client_fluffychat_service.status.NRestarts is defined + - matrix_client_fluffychat_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-client-fluffychat.service is + {{ matrix_client_fluffychat_service.status.ActiveState | default('unknown') }} after + {{ matrix_client_fluffychat_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-client-fluffychat.service is active and has not restarted" + + # Probe through the private container network, matching how Traefik reaches the + # service in a deployment without publishing an artificial host port. + - name: Wait for FluffyChat to serve its application root + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_client_fluffychat_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - "http://matrix-client-fluffychat:{{ matrix_client_fluffychat_container_http_port }}/" + register: matrix_client_fluffychat_root_http + changed_when: false + until: "'HTTP_STATUS=200' in matrix_client_fluffychat_root_http.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the application root is real FluffyChat HTML + ansible.builtin.assert: + that: + - matrix_client_fluffychat_root_http.rc == 0 + - matrix_client_fluffychat_root_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_client_fluffychat_root_body | trim | length > 500 + - "'<!doctype html' in matrix_client_fluffychat_root_body | lower" + - "'fluffychat' in matrix_client_fluffychat_root_body | lower" + fail_msg: "FluffyChat did not return its real application HTML over the container network" + success_msg: "FluffyChat serves its real application root over HTTP" + + - name: Fetch FluffyChat's live browser configuration + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_client_fluffychat_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}\nCONTENT_TYPE=%{content_type}" + - "http://matrix-client-fluffychat:{{ matrix_client_fluffychat_container_http_port }}/config.json" + register: matrix_client_fluffychat_config_http + changed_when: false + failed_when: false + + - name: Assert the live browser configuration is served as JSON + ansible.builtin.assert: + that: + - matrix_client_fluffychat_config_http.rc == 0 + - "'HTTP_STATUS=200' in matrix_client_fluffychat_config_http.stdout_lines" + - matrix_client_fluffychat_config_http.stdout | regex_search('(?m)^CONTENT_TYPE=application/json(?:;|$)') is not none + fail_msg: "FluffyChat did not serve its live browser configuration as JSON" + success_msg: "FluffyChat serves its live browser configuration as JSON" + + - name: Parse the live browser configuration + ansible.builtin.set_fact: + matrix_client_fluffychat_live_config: >- + {{ matrix_client_fluffychat_config_http.stdout | regex_replace('\nHTTP_STATUS=[0-9]+\nCONTENT_TYPE=.*$', '') | from_json }} + + - name: Assert the live configuration carries the configured homeserver + ansible.builtin.assert: + that: + - matrix_client_fluffychat_live_config is mapping + - matrix_client_fluffychat_live_config.keys() | list == ['defaultHomeserver'] + - matrix_client_fluffychat_live_config.defaultHomeserver == matrix_client_fluffychat_config_defaultHomeserver + fail_msg: "The live config.json does not carry the non-default homeserver rendered by the role" + success_msg: "The live config.json carries the configured homeserver" + + # Fetch a browser bundle referenced by the live HTML rather than assuming the + # container is useful just because nginx answered at its root. + - name: Extract a live FluffyChat application asset path + ansible.builtin.set_fact: + matrix_client_fluffychat_application_asset_path: >- + {{ matrix_client_fluffychat_root_body | regex_search('(?<=src=")[^"]+[.]js(?=")') }} + + - name: Fetch the live FluffyChat application asset + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_client_fluffychat_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}\nCONTENT_TYPE=%{content_type}\nSIZE=%{size_download}" + - "http://matrix-client-fluffychat:{{ matrix_client_fluffychat_container_http_port }}/{{ matrix_client_fluffychat_application_asset_path }}" + register: matrix_client_fluffychat_asset_http + changed_when: false + failed_when: false + + - name: Assert a real FluffyChat application asset is served + ansible.builtin.assert: + that: + - matrix_client_fluffychat_asset_http.rc == 0 + - "'HTTP_STATUS=200' in matrix_client_fluffychat_asset_http.stdout_lines" + - matrix_client_fluffychat_asset_http.stdout | regex_search('(?m)^CONTENT_TYPE=(?:application|text)/javascript(?:;|$)') is not none + - matrix_client_fluffychat_asset_http.stdout | regex_search('(?m)^SIZE=([1-9][0-9]{3,})$') is not none + fail_msg: "FluffyChat did not serve the JavaScript asset referenced by its live HTML" + success_msg: "FluffyChat serves a substantial live application asset" + + - name: Read the configuration file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_client_fluffychat_config_path }}/config.json" + register: matrix_client_fluffychat_rendered_config_file + + - name: Assert the served and rendered structured configurations are identical + ansible.builtin.assert: + that: + - matrix_client_fluffychat_rendered_config == matrix_client_fluffychat_live_config + fail_msg: "The live configuration differs from the parsed file the role rendered" + success_msg: "The running service exposes the exact structured configuration the role rendered" + vars: + matrix_client_fluffychat_rendered_config: >- + {{ matrix_client_fluffychat_rendered_config_file.content | b64decode | from_json }} + + - name: Read the labels file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_client_fluffychat_base_path }}/labels" + register: matrix_client_fluffychat_labels_file + + - name: Initialize the parsed labels + ansible.builtin.set_fact: + matrix_client_fluffychat_labels_parsed: {} + + - name: Parse the rendered labels + ansible.builtin.set_fact: + matrix_client_fluffychat_labels_parsed: >- + {{ matrix_client_fluffychat_labels_parsed | combine({item.split('=', 1)[0]: item.split('=', 1)[1]}) }} + loop: "{{ (matrix_client_fluffychat_labels_file.content | b64decode).splitlines() | reject('equalto', '') }}" + when: "'=' in item" + no_log: true + + - name: Assert the rendered labels carry the public routing contract + ansible.builtin.assert: + that: + - matrix_client_fluffychat_labels_parsed['traefik.enable'] == 'true' + - matrix_client_fluffychat_labels_parsed['traefik.docker.network'] == matrix_client_fluffychat_container_network + - matrix_client_fluffychat_labels_parsed['traefik.http.services.matrix-client-fluffychat.loadbalancer.server.port'] == (matrix_client_fluffychat_container_http_port | string) + - matrix_client_fluffychat_labels_parsed['traefik.http.routers.matrix-client-fluffychat.rule'] == 'Host(`chat.fluffy.molecule.local`) && PathPrefix(`/fluffy`)' + - matrix_client_fluffychat_labels_parsed['traefik.http.routers.matrix-client-fluffychat.priority'] == '731' + - matrix_client_fluffychat_labels_parsed['traefik.http.routers.matrix-client-fluffychat.entrypoints'] == 'web' + - matrix_client_fluffychat_labels_parsed['traefik.http.routers.matrix-client-fluffychat.tls'] == 'false' + - matrix_client_fluffychat_labels_parsed['traefik.http.routers.matrix-client-fluffychat.middlewares'] == 'matrix-client-fluffychat-slashless-redirect,matrix-client-fluffychat-strip-prefix,matrix-client-fluffychat-add-headers' + - matrix_client_fluffychat_labels_parsed['molecule.fluffychat.coverage'] == 'enabled' + fail_msg: "The parsed labels do not carry the scenario's routing contract" + success_msg: "The parsed labels carry the scenario's routing contract" + + - name: Assert the rendered labels carry the configured response headers + ansible.builtin.assert: + that: + - matrix_client_fluffychat_labels_parsed['traefik.http.middlewares.matrix-client-fluffychat-add-headers.headers.customresponseheaders.X-XSS-Protection'] == '0' + - matrix_client_fluffychat_labels_parsed['traefik.http.middlewares.matrix-client-fluffychat-add-headers.headers.customresponseheaders.X-Content-Type-Options'] == 'molecule-nosniff' + - matrix_client_fluffychat_labels_parsed['traefik.http.middlewares.matrix-client-fluffychat-add-headers.headers.customresponseheaders.Content-Security-Policy'] == 'frame-ancestors https://embed.molecule.local' + - matrix_client_fluffychat_labels_parsed['traefik.http.middlewares.matrix-client-fluffychat-add-headers.headers.customresponseheaders.Permission-Policy'] == 'camera=(self)' + - "'traefik.http.middlewares.matrix-client-fluffychat-add-headers.headers.customresponseheaders.Strict-Transport-Security' not in matrix_client_fluffychat_labels_parsed" + fail_msg: "The parsed labels lost response headers or incorrectly enable HSTS without TLS" + success_msg: "The parsed labels carry the configured response-header contract" + + - name: Inspect the running FluffyChat container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-client-fluffychat + register: matrix_client_fluffychat_container_inspect + changed_when: false + + - name: Assert the rendered labels reached the running container + ansible.builtin.assert: + that: + - matrix_client_fluffychat_runtime.Config.Labels['traefik.enable'] == 'true' + - matrix_client_fluffychat_runtime.Config.Labels['traefik.docker.network'] == matrix_client_fluffychat_container_network + - matrix_client_fluffychat_runtime.Config.Labels['traefik.http.services.matrix-client-fluffychat.loadbalancer.server.port'] == (matrix_client_fluffychat_container_http_port | string) + - matrix_client_fluffychat_runtime.Config.Labels['traefik.http.routers.matrix-client-fluffychat.priority'] == '731' + - matrix_client_fluffychat_runtime.Config.Labels['molecule.fluffychat.coverage'] == 'enabled' + - matrix_client_fluffychat_runtime.Config.Labels['molecule.fluffychat.extra-argument'] == 'reached' + fail_msg: "The running container does not carry the labels the role rendered and passed" + success_msg: "The configured labels reached the running container" + + - name: Assert the configured internal port reached the running container + ansible.builtin.assert: + that: + - "('SERVER_PORT=' ~ (matrix_client_fluffychat_container_http_port | string)) in matrix_client_fluffychat_runtime.Config.Env" + fail_msg: "The running container did not receive its configured internal HTTP port" + success_msg: "The configured internal HTTP port reached the running container" + + - name: Assert the running container uses the exact image and version the role pins + ansible.builtin.assert: + that: + - matrix_client_fluffychat_runtime.Config.Image == matrix_client_fluffychat_expected_image + fail_msg: >- + The running container uses {{ matrix_client_fluffychat_runtime.Config.Image }}, + expected {{ matrix_client_fluffychat_expected_image }} + success_msg: "The running container uses the exact image and version defaults/main.yml pins" + vars: + matrix_client_fluffychat_expected_image: >- + {{ matrix_client_fluffychat_role_defaults.matrix_client_fluffychat_container_image_registry_prefix_upstream_default }}etkecc/fluffychat-web:{{ matrix_client_fluffychat_role_defaults.matrix_client_fluffychat_version }} + + - name: Assert the running container uses the configured UID and GID + ansible.builtin.assert: + that: + - matrix_client_fluffychat_runtime.Config.User == (matrix_user_uid | string) ~ ':' ~ (matrix_user_gid | string) + fail_msg: >- + The running container uses {{ matrix_client_fluffychat_runtime.Config.User }}, + expected {{ matrix_user_uid }}:{{ matrix_user_gid }} + success_msg: "The running container uses the configured UID and GID" + + - name: Assert the running container keeps the image command contract + ansible.builtin.assert: + that: + - matrix_client_fluffychat_runtime.Config.Entrypoint == ['/usr/local/bin/entrypoint.sh'] + - matrix_client_fluffychat_runtime.Config.Cmd == ['static-web-server'] + - matrix_client_fluffychat_runtime.HostConfig.RestartPolicy.Name == 'no' + - matrix_client_fluffychat_runtime.HostConfig.AutoRemove is sameas true + - matrix_client_fluffychat_runtime.HostConfig.LogConfig.Type == 'none' + fail_msg: >- + FluffyChat has unexpected command or Docker lifecycle values: + entrypoint={{ matrix_client_fluffychat_runtime.Config.Entrypoint }}, + command={{ matrix_client_fluffychat_runtime.Config.Cmd }}, + restart={{ matrix_client_fluffychat_runtime.HostConfig.RestartPolicy.Name }}, + auto-remove={{ matrix_client_fluffychat_runtime.HostConfig.AutoRemove }}, + log-driver={{ matrix_client_fluffychat_runtime.HostConfig.LogConfig.Type }} + success_msg: "The role preserves the image command and exact Docker lifecycle contract" + + - name: Assert the running container security contract + ansible.builtin.assert: + that: + - matrix_client_fluffychat_runtime.HostConfig.ReadonlyRootfs is sameas true + - matrix_client_fluffychat_runtime.HostConfig.Privileged is sameas false + - matrix_client_fluffychat_runtime.HostConfig.CapAdd | default([], true) | length == 0 + - matrix_client_fluffychat_runtime.HostConfig.CapDrop == ['ALL'] + fail_msg: "The FluffyChat container is missing its read-only root or dropped capabilities" + success_msg: "The FluffyChat container has a read-only root and all capabilities dropped" + + - name: Assert the intended writable path is a constrained tmpfs mount + ansible.builtin.assert: + that: + - matrix_client_fluffychat_runtime.HostConfig.Tmpfs.keys() | list == ['/tmp'] + - matrix_client_fluffychat_runtime.HostConfig.Tmpfs['/tmp'] == 'rw,noexec,nosuid,size=10m' + fail_msg: "The running container does not have the role's exact /tmp tmpfs contract" + success_msg: "The running container has the exact constrained /tmp tmpfs mount" + + - name: Assert the role's configuration is mounted read-only at the image path + ansible.builtin.assert: + that: + - matrix_client_fluffychat_runtime.Mounts | length == 1 + - matrix_client_fluffychat_runtime.Mounts[0].Type == 'bind' + - matrix_client_fluffychat_runtime.Mounts[0].Source == matrix_client_fluffychat_config_path ~ '/config.json' + - matrix_client_fluffychat_runtime.Mounts[0].Destination == '/var/public/config.json' + - matrix_client_fluffychat_runtime.Mounts[0].RW is sameas false + fail_msg: "The role-rendered config.json is not the container's sole read-only bind mount" + success_msg: "The role-rendered config.json is mounted read-only at the image's live path" + + - name: Assert the running container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_client_fluffychat_runtime.HostConfig.NetworkMode == matrix_client_fluffychat_container_network + - matrix_client_fluffychat_runtime.NetworkSettings.Networks is mapping + - matrix_client_fluffychat_runtime.NetworkSettings.Networks | length == 1 + - matrix_client_fluffychat_container_network in matrix_client_fluffychat_runtime.NetworkSettings.Networks + fail_msg: >- + FluffyChat has unexpected network attachments: + {{ matrix_client_fluffychat_runtime.NetworkSettings.Networks.keys() | list }} + success_msg: "The running container is attached only to its dedicated network" + + - name: Assert the observable extra runtime argument reached Docker + ansible.builtin.assert: + that: + - matrix_client_fluffychat_runtime.Config.Hostname == 'fluffychat-molecule-runtime' + fail_msg: "The configured container hostname extra argument did not reach Docker" + success_msg: "The configured container extra argument reached Docker" + + - name: Probe the image's default HTTP port + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_client_fluffychat_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --connect-timeout + - "2" + - --max-time + - "3" + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-client-fluffychat:8080/ + register: matrix_client_fluffychat_default_port_http + changed_when: false + failed_when: false + + - name: Assert the image's default HTTP port is closed + ansible.builtin.assert: + that: + - matrix_client_fluffychat_default_port_http.rc != 0 + - matrix_client_fluffychat_default_port_http.stdout != 'HTTP_STATUS=200' + fail_msg: "FluffyChat still listens on the image's default port instead of only the configured port" + success_msg: "FluffyChat no longer listens on the image's default HTTP port" + + - name: Ask Docker for FluffyChat's published ports + ansible.builtin.command: + argv: + - docker + - container + - port + - matrix-client-fluffychat + register: matrix_client_fluffychat_published_ports + changed_when: false + failed_when: false + + - name: Assert the role publishes no host ports + ansible.builtin.assert: + that: + - matrix_client_fluffychat_runtime.HostConfig.PortBindings | default({}, true) | length == 0 + - matrix_client_fluffychat_published_ports.rc == 0 + - matrix_client_fluffychat_published_ports.stdout | trim | length == 0 + fail_msg: >- + FluffyChat unexpectedly publishes a host port: + {{ matrix_client_fluffychat_published_ports.stdout | default('unknown') }} + success_msg: "The role leaves FluffyChat's HTTP port unpublished" diff --git a/roles/custom/matrix-client-fluffychat/tasks/setup_install.yml b/roles/custom/matrix-client-fluffychat/tasks/setup_install.yml index a0ceb199d..851d94a03 100644 --- a/roles/custom/matrix-client-fluffychat/tasks/setup_install.yml +++ b/roles/custom/matrix-client-fluffychat/tasks/setup_install.yml @@ -18,11 +18,9 @@ when: "item.when | bool" - name: Ensure FluffyChat Web container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_client_fluffychat_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_client_fluffychat_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_client_fluffychat_container_image_force_pull }}" + pull: always when: "not matrix_client_fluffychat_container_image_self_build | bool" register: matrix_client_fluffychat_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -31,6 +29,15 @@ - when: "matrix_client_fluffychat_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure FluffyChat Web repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_client_fluffychat_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure FluffyChat Web repository is present on self-build ansible.builtin.git: repo: "{{ matrix_client_fluffychat_container_image_self_build_repo }}" @@ -64,6 +71,7 @@ register: matrix_client_fluffychat_config_result - name: Ensure FluffyChat Web container network is created + when: matrix_client_fluffychat_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_client_fluffychat_container_network }}" diff --git a/roles/custom/matrix-client-fluffychat/tasks/validate_config.yml b/roles/custom/matrix-client-fluffychat/tasks/validate_config.yml index 9cd10120e..f847e3343 100644 --- a/roles/custom/matrix-client-fluffychat/tasks/validate_config.yml +++ b/roles/custom/matrix-client-fluffychat/tasks/validate_config.yml @@ -17,6 +17,7 @@ - {'old': 'matrix_client_fluffychat_docker_image_registry_prefix', 'new': 'matrix_client_fluffychat_container_image_registry_prefix'} - {'old': 'matrix_client_fluffychat_docker_image_registry_prefix_upstream', 'new': 'matrix_client_fluffychat_container_image_registry_prefix_upstream'} - {'old': 'matrix_client_fluffychat_docker_image_registry_prefix_upstream_default', 'new': 'matrix_client_fluffychat_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_client_fluffychat_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required FluffyChat Web settings not defined ansible.builtin.fail: diff --git a/roles/custom/matrix-client-fluffychat/templates/systemd/matrix-client-fluffychat.service.j2 b/roles/custom/matrix-client-fluffychat/templates/systemd/matrix-client-fluffychat.service.j2 index 0dcb3126d..6e7b23cce 100644 --- a/roles/custom/matrix-client-fluffychat/templates/systemd/matrix-client-fluffychat.service.j2 +++ b/roles/custom/matrix-client-fluffychat/templates/systemd/matrix-client-fluffychat.service.j2 @@ -18,6 +18,7 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --name=matrix-client-fluffychat \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --env=SERVER_PORT={{ matrix_client_fluffychat_container_http_port }} \ --cap-drop=ALL \ --read-only \ --network={{ matrix_client_fluffychat_container_network }} \ @@ -32,9 +33,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_client_fluffychat_container_image }} +{% if matrix_client_fluffychat_container_network != 'host' %} {% for network in matrix_client_fluffychat_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-client-fluffychat {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-client-fluffychat diff --git a/roles/custom/matrix-client-schildichat/defaults/main.yml b/roles/custom/matrix-client-schildichat/defaults/main.yml index 180df38c8..ec160ff40 100644 --- a/roles/custom/matrix-client-schildichat/defaults/main.yml +++ b/roles/custom/matrix-client-schildichat/defaults/main.yml @@ -24,7 +24,6 @@ matrix_client_schildichat_container_image: "{{ matrix_client_schildichat_contain matrix_client_schildichat_container_image_registry_prefix: "{{ 'localhost/' if matrix_client_schildichat_container_image_self_build else matrix_client_schildichat_container_image_registry_prefix_upstream }}" matrix_client_schildichat_container_image_registry_prefix_upstream: "{{ matrix_client_schildichat_container_image_registry_prefix_upstream_default }}" matrix_client_schildichat_container_image_registry_prefix_upstream_default: ghcr.io/ -matrix_client_schildichat_container_image_force_pull: "{{ matrix_client_schildichat_container_image.endswith(':latest') }}" matrix_client_schildichat_data_path: "{{ matrix_base_data_path }}/client-schildichat" matrix_client_schildichat_container_src_files_path: "{{ matrix_client_schildichat_data_path }}/docker-src" diff --git a/roles/custom/matrix-client-schildichat/tasks/prepare_themes.yml b/roles/custom/matrix-client-schildichat/tasks/prepare_themes.yml index 4c2167bcd..0402e4bba 100644 --- a/roles/custom/matrix-client-schildichat/tasks/prepare_themes.yml +++ b/roles/custom/matrix-client-schildichat/tasks/prepare_themes.yml @@ -14,11 +14,17 @@ delegate_to: 127.0.0.1 become: false block: + # This checkout lives on the Ansible controller, so we cannot correct its ownership like we do for checkouts on the server. + # Marking it as a safe directory keeps git's dubious-ownership protection from failing the task when the playbook directory belongs to another user. - name: Ensure SchildiChat Web themes repository is pulled ansible.builtin.git: repo: "{{ matrix_client_schildichat_themes_repository_url }}" version: "{{ matrix_client_schildichat_themes_repository_version }}" dest: "{{ role_path }}/files/scratchpad/themes" + environment: + GIT_CONFIG_COUNT: "1" + GIT_CONFIG_KEY_0: safe.directory + GIT_CONFIG_VALUE_0: "{{ role_path }}/files/scratchpad/themes" - name: Find all SchildiChat Web theme files ansible.builtin.find: diff --git a/roles/custom/matrix-client-schildichat/tasks/setup_install.yml b/roles/custom/matrix-client-schildichat/tasks/setup_install.yml index 19b07ff75..e421fdb0c 100644 --- a/roles/custom/matrix-client-schildichat/tasks/setup_install.yml +++ b/roles/custom/matrix-client-schildichat/tasks/setup_install.yml @@ -21,11 +21,9 @@ when: "item.when | bool" - name: Ensure SchildiChat Web container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_client_schildichat_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_client_schildichat_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_client_schildichat_container_image_force_pull }}" + pull: always when: "not matrix_client_schildichat_container_image_self_build | bool" register: matrix_client_schildichat_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -34,6 +32,15 @@ - when: "matrix_client_schildichat_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure SchildiChat Web repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_client_schildichat_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure SchildiChat Web repository is present on self-build ansible.builtin.git: repo: "{{ matrix_client_schildichat_container_image_self_build_repo }}" @@ -109,6 +116,7 @@ when: "item.src is none" - name: Ensure SchildiChat Web container network is created + when: matrix_client_schildichat_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_client_schildichat_container_network }}" diff --git a/roles/custom/matrix-client-schildichat/tasks/validate_config.yml b/roles/custom/matrix-client-schildichat/tasks/validate_config.yml index 8189e3880..9ec6303d0 100644 --- a/roles/custom/matrix-client-schildichat/tasks/validate_config.yml +++ b/roles/custom/matrix-client-schildichat/tasks/validate_config.yml @@ -20,6 +20,7 @@ - {'old': 'matrix_client_schildichat_docker_image_registry_prefix', 'new': 'matrix_client_schildichat_container_image_registry_prefix'} - {'old': 'matrix_client_schildichat_docker_image_registry_prefix_upstream', 'new': 'matrix_client_schildichat_container_image_registry_prefix_upstream'} - {'old': 'matrix_client_schildichat_docker_image_registry_prefix_upstream_default', 'new': 'matrix_client_schildichat_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_client_schildichat_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required SchildiChat Web settings not defined ansible.builtin.fail: diff --git a/roles/custom/matrix-client-schildichat/templates/systemd/matrix-client-schildichat.service.j2 b/roles/custom/matrix-client-schildichat/templates/systemd/matrix-client-schildichat.service.j2 index 7afc7ac89..fdfefa8a4 100644 --- a/roles/custom/matrix-client-schildichat/templates/systemd/matrix-client-schildichat.service.j2 +++ b/roles/custom/matrix-client-schildichat/templates/systemd/matrix-client-schildichat.service.j2 @@ -40,9 +40,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_client_schildichat_container_image }} +{% if matrix_client_schildichat_container_network != 'host' %} {% for network in matrix_client_schildichat_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-client-schildichat {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-client-schildichat diff --git a/roles/custom/matrix-conduit/defaults/main.yml b/roles/custom/matrix-conduit/defaults/main.yml index 0cd42b1dd..f06b606c9 100644 --- a/roles/custom/matrix-conduit/defaults/main.yml +++ b/roles/custom/matrix-conduit/defaults/main.yml @@ -19,8 +19,7 @@ matrix_conduit_container_image_registry_prefix: "{{ matrix_conduit_container_ima matrix_conduit_container_image_registry_prefix_upstream: "{{ matrix_conduit_container_image_registry_prefix_upstream_default }}" matrix_conduit_container_image_registry_prefix_upstream_default: docker.io/ # renovate: datasource=docker depName=matrixconduit/matrix-conduit -matrix_conduit_container_image_tag: "v0.10.12" -matrix_conduit_container_image_force_pull: "{{ matrix_conduit_container_image.endswith(':latest') }}" +matrix_conduit_container_image_tag: "v0.10.13" matrix_conduit_base_path: "{{ matrix_base_data_path }}/conduit" matrix_conduit_config_path: "{{ matrix_conduit_base_path }}/config" diff --git a/roles/custom/matrix-conduit/tasks/setup_install.yml b/roles/custom/matrix-conduit/tasks/setup_install.yml index fc58f7e1b..c204fbe59 100644 --- a/roles/custom/matrix-conduit/tasks/setup_install.yml +++ b/roles/custom/matrix-conduit/tasks/setup_install.yml @@ -45,6 +45,7 @@ register: matrix_conduit_support_files_result - name: Ensure Conduit container network is created + when: matrix_conduit_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_conduit_container_network }}" @@ -52,11 +53,9 @@ driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - name: Ensure Conduit container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_conduit_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_conduit_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_conduit_container_image_force_pull }}" + pull: always register: matrix_conduit_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" diff --git a/roles/custom/matrix-conduit/tasks/validate_config.yml b/roles/custom/matrix-conduit/tasks/validate_config.yml index 236b2f463..c619cea5e 100644 --- a/roles/custom/matrix-conduit/tasks/validate_config.yml +++ b/roles/custom/matrix-conduit/tasks/validate_config.yml @@ -17,6 +17,7 @@ - {'old': 'matrix_conduit_docker_image_registry_prefix_upstream', 'new': 'matrix_conduit_container_image_registry_prefix_upstream'} - {'old': 'matrix_conduit_docker_image_registry_prefix_upstream_default', 'new': 'matrix_conduit_container_image_registry_prefix_upstream_default'} - {'old': 'matrix_conduit_docker_image_tag', 'new': 'matrix_conduit_container_image_tag'} + - {'old': 'matrix_conduit_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required Conduit settings not defined ansible.builtin.fail: diff --git a/roles/custom/matrix-conduit/templates/systemd/matrix-conduit.service.j2 b/roles/custom/matrix-conduit/templates/systemd/matrix-conduit.service.j2 index 26df0065a..a8b76d610 100644 --- a/roles/custom/matrix-conduit/templates/systemd/matrix-conduit.service.j2 +++ b/roles/custom/matrix-conduit/templates/systemd/matrix-conduit.service.j2 @@ -30,9 +30,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_conduit_container_image }} +{% if matrix_conduit_container_network != 'host' %} {% for network in matrix_conduit_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-conduit {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-conduit diff --git a/roles/custom/matrix-continuwuity/defaults/main.yml b/roles/custom/matrix-continuwuity/defaults/main.yml index 8e02f7238..6385bf365 100644 --- a/roles/custom/matrix-continuwuity/defaults/main.yml +++ b/roles/custom/matrix-continuwuity/defaults/main.yml @@ -1,5 +1,6 @@ # SPDX-FileCopyrightText: 2025 MDAD project contributors # SPDX-FileCopyrightText: 2025 Slavi Pantaleev +# SPDX-FileCopyrightText: 2026 Catalan Lover <catalanlover@protonmail.com> # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -13,11 +14,10 @@ matrix_continuwuity_enabled: true matrix_continuwuity_hostname: '' # renovate: datasource=docker depName=forgejo.ellis.link/continuwuation/continuwuity -matrix_continuwuity_version: v0.5.6 +matrix_continuwuity_version: v26.8.1 matrix_continuwuity_container_image: "{{ matrix_continuwuity_container_image_registry_prefix }}/continuwuation/continuwuity:{{ matrix_continuwuity_container_image_tag }}" matrix_continuwuity_container_image_tag: "{{ matrix_continuwuity_version }}" -matrix_continuwuity_container_image_force_pull: "{{ matrix_continuwuity_container_image.endswith(':latest') }}" matrix_continuwuity_container_image_registry_prefix: "{{ matrix_continuwuity_container_image_registry_prefix_upstream }}" matrix_continuwuity_container_image_registry_prefix_upstream: "{{ matrix_continuwuity_container_image_registry_prefix_upstream_default }}" matrix_continuwuity_container_image_registry_prefix_upstream_default: forgejo.ellis.link @@ -37,7 +37,10 @@ matrix_continuwuity_systemd_required_services_list_auto: [] matrix_continuwuity_systemd_required_services_list_custom: [] # List of systemd services that matrix-continuwuity.service wants -matrix_continuwuity_systemd_wanted_services_list: [] +matrix_continuwuity_systemd_wanted_services_list: "{{ matrix_continuwuity_systemd_wanted_services_list_default + matrix_continuwuity_systemd_wanted_services_list_auto + matrix_continuwuity_systemd_wanted_services_list_custom }}" +matrix_continuwuity_systemd_wanted_services_list_default: [] +matrix_continuwuity_systemd_wanted_services_list_auto: [] +matrix_continuwuity_systemd_wanted_services_list_custom: [] # Controls how long to sleep for after starting the matrix-synapse container. # @@ -165,8 +168,8 @@ matrix_continuwuity_config_registration_token: '' # Upstream defaults this to "🏳️‍⚧️", but we keep this consistent across all homeserver implementations and do not enable a suffix. matrix_continuwuity_config_new_user_displayname_suffix: "" -# Controls the `allow_check_for_updates` setting. -matrix_continuwuity_config_allow_check_for_updates: false +# Controls the `allow_announcements_check` setting. +matrix_continuwuity_config_allow_announcements_check: true # Controls the `emergency_password` setting. matrix_continuwuity_config_emergency_password: '' @@ -188,6 +191,35 @@ matrix_continuwuity_config_turn_password: '' # Controls whether the self-check feature should validate SSL certificates. matrix_continuwuity_self_check_validate_certificates: true +# Configuring both of these settings makes registration require Google ReCAPTCHA verification. +# Both must be set together (or both left empty). Setting only one of them is a configuration error. +# When both are set, ReCAPTCHA gets enabled automatically (see `matrix_continuwuity_recaptcha_enabled` in `vars/main.yml`). +matrix_continuwuity_config_recaptcha_site_key: '' +matrix_continuwuity_config_recaptcha_private_site_key: '' + +# Controls whether encrypted rooms and events are allowed. +matrix_continuwuity_config_allow_encryption: true + +# Controls whether standard users can create new rooms. +# Appservices and admins are always allowed to create new rooms. +matrix_continuwuity_config_allow_room_creation: true + +# Controls the default room version continuwuity will create rooms with. +# Per spec, room version '12' is the default (According to spec release 1.18). +matrix_continuwuity_config_default_room_version: '12' + +# List/vector of room IDs or room aliases that continuwuity will make +# newly registered users join. The rooms specified must be rooms that you +# have joined at least once on the server, and must be public. +# +# example: ["#continuwuity:continuwuity.org", +# "!main-1:continuwuity.org"] +# +matrix_continuwuity_config_auto_join_rooms: [] + +# Forces users to always forget rooms they have left (MSC4267). +matrix_continuwuity_config_forget_forced_upon_leave: false + # Controls server (de)federation settings. matrix_continuwuity_config_allow_federation: true matrix_continuwuity_config_allowed_remote_server_names: [] @@ -196,6 +228,40 @@ matrix_continuwuity_config_forbidden_remote_room_directory_server_names: [] matrix_continuwuity_config_prevent_media_downloads_from: [] matrix_continuwuity_config_ignore_messages_from_server_names: [] +# Allow outgoing presence updates/requests. +# +# Note that outgoing presence is very heavy on the CPU and network, and +# will typically cause extreme strain and slowdowns for no real benefit. +# There are only a few clients that even implement presence, so you +# probably don't want to enable this. +matrix_continuwuity_config_allow_outgoing_presence: false + +# Controls MatrixRTC foci served via `/_matrix/client/v1/rtc/transports` +# and `/_matrix/client/unstable/org.matrix.msc4143/rtc/transports` (MSC4143) +matrix_continuwuity_config_rtc_foci: "{{ matrix_continuwuity_config_rtc_foci_default + matrix_continuwuity_config_rtc_foci_auto + matrix_continuwuity_config_rtc_foci_custom }}" + +# Holds the default MatrixRTC foci list, driven by `matrix_continuwuity_config_rtc_foci_livekit_url`. +matrix_continuwuity_config_rtc_foci_default: |- + {{ + ( + [{'type': 'livekit', 'livekit_service_url': matrix_continuwuity_config_rtc_foci_livekit_url}] if matrix_continuwuity_config_rtc_foci_livekit_url != '' else [] + ) + }} + +# Holds MatrixRTC foci entries that a playbook may inject automatically, based on the state of other services. +# +# This variable is not meant to be redefined by users. +# To inject your own entries, use `matrix_continuwuity_config_rtc_foci_custom`. +matrix_continuwuity_config_rtc_foci_auto: [] + +# Holds additional MatrixRTC foci entries that you may wish to inject. +matrix_continuwuity_config_rtc_foci_custom: [] + +# Controls MatrixRTC Livekit URL auto-added to `matrix_continuwuity_config_rtc_foci`. +# +# This is set automatically if you are using the playbook MatrixRTC stack. +matrix_continuwuity_config_rtc_foci_livekit_url: '' + # Controls the `url_preview_domain_contains_allowlist` setting. matrix_continuwuity_config_url_preview_domain_contains_allowlist: [] @@ -205,6 +271,31 @@ matrix_continuwuity_config_url_preview_domain_explicit_allowlist: [] # Controls the `url_preview_check_root_domain` setting. matrix_continuwuity_config_url_preview_check_root_domain: false +# Controls the value of `global.well_known.client`. +matrix_continuwuity_config_well_known_client: '' + +# Controls whether SMTP features will be enabled +# (such as setting the server's SMTP connection URL, +# enabling self-service password resets via email, +# requiring email for registration, etc.) +matrix_continuwuity_config_smtp_enabled: false + +# Controls the value of `global.smtp.connection_uri` (if any). +# Must be set to a non-empty value +# together with `matrix_continuwuity_config_smtp_sender` to have effect. +matrix_continuwuity_config_smtp_connection_uri: '' + +# Controls the value of `global.smtp.sender` (if any). +# Must be set to a non-empty value +# together with `matrix_continuwuity_config_smtp_connection_uri` to have effect. +matrix_continuwuity_config_smtp_sender: '' + +# Controls the `global.smtp.require_email_for_registration` setting. +matrix_continuwuity_config_smtp_require_email_for_registration: false + +# Controls the `global.smtp.require_email_for_token_registration ` setting. +matrix_continuwuity_config_smtp_require_email_for_token_registration: false + # Additional environment variables to pass to the container. # # Environment variables take priority over settings in the configuration file. diff --git a/roles/custom/matrix-continuwuity/tasks/install.yml b/roles/custom/matrix-continuwuity/tasks/install.yml index e373b5b93..8d5d6f04c 100644 --- a/roles/custom/matrix-continuwuity/tasks/install.yml +++ b/roles/custom/matrix-continuwuity/tasks/install.yml @@ -42,6 +42,7 @@ register: matrix_continuwuity_support_files_result - name: Ensure continuwuity container network is created + when: matrix_continuwuity_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_continuwuity_container_network }}" @@ -49,11 +50,9 @@ driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - name: Ensure continuwuity container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_continuwuity_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_continuwuity_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_continuwuity_container_image_force_pull }}" + pull: always register: matrix_continuwuity_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" diff --git a/roles/custom/matrix-continuwuity/tasks/setup_install.yml b/roles/custom/matrix-continuwuity/tasks/setup_install.yml index 500f3196e..539ab5ce1 100644 --- a/roles/custom/matrix-continuwuity/tasks/setup_install.yml +++ b/roles/custom/matrix-continuwuity/tasks/setup_install.yml @@ -39,6 +39,7 @@ - labels - name: Ensure continuwuity container network is created + when: matrix_continuwuity_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_continuwuity_container_network }}" @@ -46,11 +47,9 @@ driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - name: Ensure continuwuity container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_continuwuity_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_continuwuity_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_continuwuity_container_image_force_pull }}" + pull: always register: result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" diff --git a/roles/custom/matrix-continuwuity/tasks/validate_config.yml b/roles/custom/matrix-continuwuity/tasks/validate_config.yml index 139fbb03e..777f12387 100644 --- a/roles/custom/matrix-continuwuity/tasks/validate_config.yml +++ b/roles/custom/matrix-continuwuity/tasks/validate_config.yml @@ -1,4 +1,5 @@ # SPDX-FileCopyrightText: 2025 MDAD project contributors +# SPDX-FileCopyrightText: 2026 Catalan Lover <catalanlover@protonmail.com> # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -22,6 +23,7 @@ when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - {'old': 'matrix_continuwuity_allowed_remote_server_names', 'new': 'matrix_continuwuity_config_allowed_remote_server_names'} + - {'old': 'matrix_continuwuity_config_allow_check_for_updates', 'new': 'matrix_continuwuity_config_allow_announcements_check'} - {'old': 'matrix_continuwuity_forbidden_remote_room_directory_server_names', 'new': 'matrix_continuwuity_config_forbidden_remote_room_directory_server_names'} - {'old': 'matrix_continuwuity_forbidden_remote_server_names', 'new': 'matrix_continuwuity_config_forbidden_remote_server_names'} - {'old': 'matrix_continuwuity_ignore_messages_from_server_names', 'new': 'matrix_continuwuity_config_ignore_messages_from_server_names'} @@ -30,7 +32,16 @@ - {'old': 'matrix_continuwuity_url_preview_domain_contains_allowlist', 'new': 'matrix_continuwuity_config_url_preview_domain_contains_allowlist'} - {'old': 'matrix_continuwuity_docker_image', 'new': 'matrix_continuwuity_container_image'} - {'old': 'matrix_continuwuity_docker_image_tag', 'new': 'matrix_continuwuity_container_image_tag'} - - {'old': 'matrix_continuwuity_docker_image_force_pull', 'new': 'matrix_continuwuity_container_image_force_pull'} + - {'old': 'matrix_continuwuity_docker_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - {'old': 'matrix_continuwuity_docker_image_registry_prefix', 'new': 'matrix_continuwuity_container_image_registry_prefix'} - {'old': 'matrix_continuwuity_docker_image_registry_prefix_upstream', 'new': 'matrix_continuwuity_container_image_registry_prefix_upstream'} - {'old': 'matrix_continuwuity_docker_image_registry_prefix_upstream_default', 'new': 'matrix_continuwuity_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_continuwuity_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} + +- name: Fail if Continuwuity ReCAPTCHA is only partially configured + ansible.builtin.fail: + msg: >- + You have configured only one of `matrix_continuwuity_config_recaptcha_site_key` and + `matrix_continuwuity_config_recaptcha_private_site_key`. Configure both to enable ReCAPTCHA + registration, or leave both empty to disable it. + when: "(matrix_continuwuity_config_recaptcha_site_key | string | length > 0) != (matrix_continuwuity_config_recaptcha_private_site_key | string | length > 0)" diff --git a/roles/custom/matrix-continuwuity/templates/continuwuity.toml.j2 b/roles/custom/matrix-continuwuity/templates/continuwuity.toml.j2 index 7bf1fc5ef..50f1df78e 100644 --- a/roles/custom/matrix-continuwuity/templates/continuwuity.toml.j2 +++ b/roles/custom/matrix-continuwuity/templates/continuwuity.toml.j2 @@ -2,6 +2,7 @@ SPDX-FileCopyrightText: 2025 MDAD project contributors SPDX-FileCopyrightText: 2025 Slavi Pantaleev SPDX-FileCopyrightText: 2025 Suguru Hirahara +SPDX-FileCopyrightText: 2026 Catalan Lover <catalanlover@protonmail.com> SPDX-License-Identifier: AGPL-3.0-or-later #} @@ -21,8 +22,8 @@ SPDX-License-Identifier: AGPL-3.0-or-later # Also see the `[global.well_known]` config section at the very bottom. # # Examples of delegation: -# - https://puppygock.gay/.well-known/matrix/server -# - https://puppygock.gay/.well-known/matrix/client +# - https://continuwuity.org/.well-known/matrix/server +# - https://continuwuity.org/.well-known/matrix/client # # YOU NEED TO EDIT THIS. THIS CANNOT BE CHANGED AFTER WITHOUT A DATABASE # WIPE. @@ -112,7 +113,7 @@ new_user_displayname_suffix = {{ matrix_continuwuity_config_new_user_displayname # `https://continuwuity.org/.well-known/continuwuity/announcements` for any new # announcements or major updates. This is not an update check endpoint. # -allow_check_for_updates = {{ matrix_continuwuity_config_allow_check_for_updates | to_json }} +allow_announcements_check = {{ matrix_continuwuity_config_allow_announcements_check | to_json }} # Set this to any float value to multiply continuwuity's in-memory LRU # caches with such as "auth_chain_cache_capacity". @@ -275,13 +276,54 @@ allow_check_for_updates = {{ matrix_continuwuity_config_allow_check_for_updates # #ip_lookup_strategy = 5 +# The source to use for discovering the real connecting client IP. +# +# Takes any of the following options: +# +# "cf_connecting_ip" - `Cf-Connecting-Ip` header +# "cloudfront_viewer_address" - `CloudFront-Viewer-Address` header +# "fly_client_ip" - `Fly-Client-IP` header +# "x_forwarded_for" - rightmost value of the `X-Forwarded-For` header +# "true_client_ip" - `True-Client-Ip` header +# "x_envoy_external_address" - `X-Envoy-External-Address` header +# "x_real_ip" - `X-Real-Ip` header +# +# Only set this if you are certain only your reverse proxy +# will send the expected header. There is no "is the connecting IP allowed +# to set this header" check; if the header selected is present, it is +# used. +# +# Defaults to the IP address actually making the connection. +# +#request_ip_source = false + # Max request size for file uploads in bytes. Defaults to 20MB. +# Also limits incoming federated media. # max_request_size = {{ matrix_continuwuity_config_max_request_size }} # This item is undocumented. Please contribute documentation for it. # -#max_fetch_prev_events = 192 +#max_fetch_prev_events = 1024 + +# How many incoming federation transactions the server is willing to be +# processing at any given time before it becomes overloaded and starts +# rejecting further transactions until some slots become available. +# +# Setting this value too low or too high may result in unstable +# federation, and setting it too high may cause runaway resource usage. +# +#max_concurrent_inbound_transactions = 150 + +# Maximum age (in seconds) for cached federation transaction responses. +# Entries older than this will be removed during cleanup. +# +#transaction_id_cache_max_age_secs = 7200 (2 hours) + +# Maximum number of cached federation transaction responses. +# When the cache exceeds this limit, older entries will be removed. +# +#transaction_id_cache_max_entries = 8192 # Default/base connection timeout (seconds). This is used only by URL # previews and update/news endpoint checks. @@ -320,11 +362,35 @@ max_request_size = {{ matrix_continuwuity_config_max_request_size }} # #well_known_timeout = 10 +# Federation client connection timeout (seconds). You should not set this +# to high values, as dead homeservers can significantly slow down +# federation, specifically key retrieval, which will take roughly the +# amount of time you configure here given that a homeserver doesn't +# respond. This will cause most clients to time out /keys/query, causing +# E2EE and device verification to fail. +# +#federation_conn_timeout = 10 + # Federation client request timeout (seconds). You most definitely want # this to be high to account for extremely large room joins, slow # homeservers, your own resources etc. # -#federation_timeout = 300 +# Joins have 6x the timeout. +# +#federation_timeout = 60 + +# Policy server request timeout (seconds). Generally policy +# servers should respond near instantly, however may slow down under +# load. If a policy server doesn't respond in a short amount of time, the +# room it is configured in may become unusable if this limit is set too +# high. 30 seconds is a good default, however lower values may be +# acceptable if temporary send failures are an okay trade-off. +# +# +# About policy servers: https://matrix.org/blog/2025/04/introducing-policy-servers/ +# (Stabilized in Matrix v1.18) +# +#policy_server_request_timeout = 30 # Federation client idle connection pool timeout (seconds). # @@ -357,7 +423,15 @@ max_request_size = {{ matrix_continuwuity_config_max_request_size }} # #appservice_idle_timeout = 300 -# Notification gateway pusher idle connection pool timeout. +# Notification gateway pusher request connection timeout (seconds). +# +#pusher_conn_timeout = 15 + +# Notification gateway pusher total request timeout (seconds). +# +#pusher_timeout = 60 + +# Notification gateway pusher idle connection pool timeout (seconds). # #pusher_idle_timeout = 15 @@ -389,7 +463,7 @@ max_request_size = {{ matrix_continuwuity_config_max_request_size }} # `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse` # # If you would like registration only via token reg, please configure -# `registration_token` or `registration_token_file`. +# `registration_token`. # allow_registration = {{ matrix_continuwuity_config_allow_registration | to_json }} @@ -402,6 +476,11 @@ allow_registration = {{ matrix_continuwuity_config_allow_registration | to_json # invites, or create/join or otherwise modify rooms. # They are effectively read-only. # +# If you want to use this to screen people who register on your server, +# you should add a room to `auto_join_rooms` that is public, and contains +# information that new users can read (since they won't be able to DM +# anyone, or send a message, and may be confused). +# suspend_on_register = {{ matrix_continuwuity_config_suspend_on_register | to_json }} # Enabling this setting opens registration to anyone without restrictions. @@ -410,30 +489,62 @@ suspend_on_register = {{ matrix_continuwuity_config_suspend_on_register | to_jso yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = {{ matrix_continuwuity_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse | to_json }} # A static registration token that new users will have to provide when -# creating an account. If unset and `allow_registration` is true, -# you must set -# `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse` -# to true to allow open registration without any conditions. -# -# YOU NEED TO EDIT THIS OR USE registration_token_file. +# creating an account. This token does not supersede tokens from other +# sources, such as the `!admin token` command or the +# `registration_token_file` configuration option. # # example: "o&^uCtes4HPf0Vu@F20jQeeWE7" # +{% if matrix_continuwuity_config_registration_token != '' %} registration_token = {{ matrix_continuwuity_config_registration_token | to_json }} +{% endif %} -# Path to a file on the system that gets read for additional registration -# tokens. Multiple tokens can be added if you separate them with -# whitespace +# A path to a file containing static registration tokens, one per line. +# Tokens in this file do not supersede tokens from other sources, such as +# the `!admin token` command or the `registration_token` configuration +# option. # -# continuwuity must be able to access the file, and it must not be empty -# -# example: "/etc/continuwuity/.reg_token" +# The file will be read once, when Continuwuity starts. It is not +# currently reread when the server configuration is reloaded. If the file +# cannot be read, Continuwuity will fail to start. # #registration_token_file = +{% if matrix_continuwuity_recaptcha_enabled %} +# The public site key for reCaptcha. If this is provided, reCaptcha +# becomes required during registration. If both captcha *and* +# registration token are enabled, both will be required during +# registration. +# +# IMPORTANT: "Verify the origin of reCAPTCHA solutions" **MUST** BE +# DISABLED IF YOU WANT THE CAPTCHA TO WORK IN 3RD PARTY CLIENTS, OR +# CLIENTS HOSTED ON DOMAINS OTHER THAN YOUR OWN! +# +# Registration must be enabled (`allow_registration` must be true) for +# this to have any effect. +# +recaptcha_site_key = {{ matrix_continuwuity_config_recaptcha_site_key | to_json }} + +# The private site key for reCaptcha. +# If this is omitted, captcha registration will not work, +# even if `recaptcha_site_key` is set. +# +recaptcha_private_site_key = {{ matrix_continuwuity_config_recaptcha_private_site_key | to_json }} +{% endif %} + +# Controls whether users are allowed to deactivate their own accounts +# through the account management panel or their Matrix clients. Server +# admins can always deactivate users using the relevant admin commands. +# +# Note that, in some jurisdictions, you may be legally required to honor +# users who request to deactivate their accounts if you set this option +# to `false`. +# +#allow_deactivation = true + # Controls whether encrypted rooms and events are allowed. # -#allow_encryption = true +allow_encryption = {{ matrix_continuwuity_config_allow_encryption | to_json }} # Controls whether federation is allowed or not. It is not recommended to # disable this after the fact due to potential federation breakage. @@ -451,7 +562,7 @@ allow_federation = {{ matrix_continuwuity_config_allow_federation | to_json }} # Always calls /forget on behalf of the user if leaving a room. This is a # part of MSC4267 "Automatically forgetting rooms on leave" # -#forget_forced_upon_leave = false +forget_forced_upon_leave = {{ matrix_continuwuity_config_forget_forced_upon_leave | to_json }} # Set this to true to require authentication on the normally # unauthenticated profile retrieval endpoints (GET) @@ -469,24 +580,6 @@ allow_federation = {{ matrix_continuwuity_config_allow_federation | to_json }} # #allow_public_room_directory_over_federation = false -# Set this to true to allow your server's public room directory to be -# queried without client authentication (access token) through the Client -# APIs. Set this to false to protect against /publicRooms spiders. -# -#allow_public_room_directory_without_auth = false - -# Allow guests/unauthenticated users to access TURN credentials. -# -# This is the equivalent of Synapse's `turn_allow_guests` config option. -# This allows any unauthenticated user to call the endpoint -# `/_matrix/client/v3/voip/turnServer`. -# -# It is unlikely you need to enable this as all major clients support -# authentication for this endpoint and prevents misuse of your TURN server -# from potential bots. -# -#turn_allow_guests = false - # Set this to true to lock down your server's public room directory and # only allow admins to publish rooms to the room directory. Unpublishing # is still allowed by all users with this enabled. @@ -516,12 +609,12 @@ allow_federation = {{ matrix_continuwuity_config_allow_federation | to_json }} # Allow standard users to create rooms. Appservices and admins are always # allowed to create rooms # -#allow_room_creation = true +allow_room_creation = {{ matrix_continuwuity_config_allow_room_creation | to_json }} # Set to false to disable users from joining or creating room versions # that aren't officially supported by continuwuity. # -# continuwuity officially supports room versions 6 - 11. +# continuwuity officially supports room versions 6 - 12. # # continuwuity has slightly experimental (though works fine in practice) # support for versions 3 - 5. @@ -529,18 +622,64 @@ allow_federation = {{ matrix_continuwuity_config_allow_federation | to_json }} #allow_unstable_room_versions = true # Default room version continuwuity will create rooms with. +# Note that this has to be a string since the room version is a string +# rather than an integer. Forgetting the quotes will make the server fail +# to start! # -# Per spec, room version 11 is the default. +# Per spec, room version "12" is the default. # -#default_room_version = 11 +default_room_version = {{ matrix_continuwuity_config_default_room_version | to_json }} -# This item is undocumented. Please contribute documentation for it. +# A default allow value for the Access Control List when creating a room. +# +# If a list is provided, new rooms will be created with +# a m.room.server_acl event. Only servers which match one of the patterns +# in the list will be permitted to participate in the room. +# +# ACLs in existing rooms will not be updated automatically. This is not +# a substitute for moderation bots. # -#allow_jaeger = false +#default_room_acl_allow = -# This item is undocumented. Please contribute documentation for it. +# A default deny value for the Access Control List when creating a room. +# +# If a list is provided, new rooms will be created with +# a m.room.server_acl event. Servers which match one of the patterns +# in the list will be NOT permitted to participate in the room. +# +# This config cannot be used if the default_room_acl_allow config is used. +# +# ACLs in existing rooms will not be updated automatically. This is not +# a substitute for moderation bots. +# +#default_room_acl_deny = + +# The number of forward extremities to tolerate in a room before +# attempting to manually squash them with a "dummy event". Setting this +# above 20 will hinder its efficacy, and setting it below 5 will cause +# more dummy events to be sent than necessary (which increases federation +# traffic). +# +#dummy_event_threshold = 10 + +# Enable OpenTelemetry OTLP tracing export. This replaces the deprecated +# Jaeger exporter. Traces will be sent via OTLP to a collector (such as +# Jaeger) that supports the OpenTelemetry Protocol. +# +# Configure your OTLP endpoint using the OTEL_EXPORTER_OTLP_ENDPOINT +# environment variable (defaults to http://localhost:4318). +# +#allow_otlp = false + +# Filter for OTLP tracing spans. This controls which spans are exported +# to the OTLP collector. +# +#otlp_filter = "info" + +# Protocol to use for OTLP tracing export. Options are "http" or "grpc". +# The HTTP protocol uses port 4318 by default, while gRPC uses port 4317. # -#jaeger_filter = "info" +#otlp_protocol = "http" # If the 'perf_measurements' compile-time feature is enabled, enables # collecting folded stack trace profile of tracing spans using @@ -666,6 +805,21 @@ log = {{ matrix_continuwuity_config_log | to_json }} # #log_thread_ids = false +# Enable journald logging on Unix platforms +# +# When enabled, log output will be sent to the systemd journal +# This is only supported on Unix platforms +# +#log_to_journald = false + +# The syslog identifier to use with journald logging +# +# Only used when journald logging is enabled +# +# Defaults to the binary name +# +#journald_identifier = + # OpenID token expiration/TTL in seconds. # # These are the OpenID tokens that are primarily used for Matrix account @@ -694,7 +848,7 @@ log = {{ matrix_continuwuity_config_log | to_json }} # ("turn_secret"), It is recommended to use a shared secret over static # credentials. # -{% if matrix_continuwuity_config_turn_username != '' %} +{% if matrix_continuwuity_config_turn_username != '' %} turn_username = {{ matrix_continuwuity_config_turn_username | to_json }} {% endif %} @@ -747,7 +901,7 @@ turn_secret = {{ matrix_continuwuity_config_turn_secret | to_json }} # example: ["#continuwuity:continuwuity.org", # "!main-1:continuwuity.org"] # -#auto_join_rooms = [] +auto_join_rooms = {{ matrix_continuwuity_config_auto_join_rooms | to_json }} # Config option to automatically deactivate the account of any user who # attempts to join a: @@ -885,6 +1039,21 @@ turn_secret = {{ matrix_continuwuity_config_turn_secret | to_json }} # #rocksdb_bottommost_compression = true +# Compression algorithm for RocksDB's Write-Ahead-Log (WAL). +# +# At present, only ZSTD compression is supported by RocksDB for WAL +# compression. Enabling this can reduce WAL size at the expense of some +# CPU usage during writes. +# +# The options are: +# - "none" = No compression +# - "zstd" = ZSTD compression +# +# For more information on WAL compression, see: +# https://github.com/facebook/rocksdb/wiki/WAL-Compression +# +#rocksdb_wal_compression = "zstd" + # Database recovery mode (for RocksDB WAL corruption). # # Use this option when the server reports corruption and refuses to start. @@ -960,14 +1129,6 @@ turn_secret = {{ matrix_continuwuity_config_turn_secret | to_json }} # #rocksdb_repair = false -# This item is undocumented. Please contribute documentation for it. -# -#rocksdb_read_only = false - -# This item is undocumented. Please contribute documentation for it. -# -#rocksdb_secondary = false - # Enables idle CPU priority for compaction thread. This is not enabled by # default to prevent compaction from falling too far behind on busy # systems. @@ -1026,27 +1187,34 @@ emergency_password = {{ matrix_continuwuity_config_emergency_password | to_json # Allow local (your server only) presence updates/requests. # -# Note that presence on continuwuity is very fast unlike Synapse's. If -# using outgoing presence, this MUST be enabled. +# Local presence must be enabled for outgoing presence to function. +# +# Note that local presence is not as heavy on the CPU as federated +# presence, but will still become more expensive the more local users you +# have. # #allow_local_presence = true -# Allow incoming federated presence updates/requests. +# Allow incoming federated presence updates. # -# This option receives presence updates from other servers, but does not -# send any unless `allow_outgoing_presence` is true. Note that presence on -# continuwuity is very fast unlike Synapse's. +# This option enables processing inbound presence updates from other +# servers. Without it, remote users will appear as if they are always +# offline to your local users. This does not affect typing indicators or +# read receipts. # #allow_incoming_presence = true # Allow outgoing presence updates/requests. # -# This option sends presence updates to other servers, but does not -# receive any unless `allow_incoming_presence` is true. Note that presence -# on continuwuity is very fast unlike Synapse's. If using outgoing -# presence, you MUST enable `allow_local_presence` as well. +# This option sends presence updates to other servers, and requires that +# `allow_local_presence` is also enabled. +# +# Note that outgoing presence is very heavy on the CPU and network, and +# will typically cause extreme strain and slowdowns for no real benefit. +# There are only a few clients that even implement presence, so you +# probably don't want to enable this. # -#allow_outgoing_presence = true +allow_outgoing_presence = {{ matrix_continuwuity_config_allow_outgoing_presence | to_json }} # How many seconds without presence updates before you become idle. # Defaults to 5 minutes. @@ -1067,16 +1235,38 @@ emergency_password = {{ matrix_continuwuity_config_emergency_password | to_json # #presence_timeout_remote_users = true +# Allow local read receipts. +# +# Disabling this will effectively also disable outgoing federated read +# receipts. +# +#allow_local_read_receipts = true + # Allow receiving incoming read receipts from remote servers. # #allow_incoming_read_receipts = true # Allow sending read receipts to remote servers. # +# Note that sending read receipts to remote servers in large rooms with +# lots of other homeservers may cause additional strain on the CPU and +# network. +# #allow_outgoing_read_receipts = true +# Allow local typing updates. +# +# Disabling this will effectively also disable outgoing federated typing +# updates. +# +#allow_local_typing = true + # Allow outgoing typing updates to federation. # +# Note that sending typing indicators to remote servers in large rooms +# with lots of other homeservers may cause additional strain on the CPU +# and network. +# #allow_outgoing_typing = true # Allow incoming typing updates from federation. @@ -1127,21 +1317,6 @@ emergency_password = {{ matrix_continuwuity_config_emergency_password | to_json # #brotli_compression = false -# Set to true to allow user type "guest" registrations. Some clients like -# Element attempt to register guest users automatically. -# -#allow_guest_registration = false - -# Set to true to log guest registrations in the admin room. Note that -# these may be noisy or unnecessary if you're a public homeserver. -# -#log_guest_registrations = false - -# Set to true to allow guest registrations/users to auto join any rooms -# specified in `auto_join_rooms`. -# -#allow_guests_auto_join_rooms = false - # Enable the legacy unauthenticated Matrix media repository endpoints. # These endpoints consist of: # - /_matrix/media/*/config @@ -1210,7 +1385,7 @@ emergency_password = {{ matrix_continuwuity_config_emergency_password | to_json # sender user's server name, inbound federation X-Matrix origin, and # outbound federation handler. # -# You can set this to ["*"] to block all servers by default, and then +# You can set this to [".*"] to block all servers by default, and then # use `allowed_remote_server_names` to allow only specific servers. # # example: ["badserver\\.tld$", "badphrase", "19dollarfortnitecards"] @@ -1254,6 +1429,20 @@ forbidden_remote_room_directory_server_names = {{ matrix_continuwuity_config_for # ignore_messages_from_server_names = {{ matrix_continuwuity_config_ignore_messages_from_server_names | to_json }} +# List of server names that continuwuity will deprioritize (try last) when +# a client requests to join a room. +# +# This can be used to potentially speed up room join requests, by +# deprioritizing sending join requests through servers that are known to +# be large or slow. +# +# continuwuity will still send join requests to servers in this list if +# the room couldn't be joined via other servers it federates with. +# +# example: ["example.com"] +# +#deprioritize_joins_through_servers = [] + # Send messages from users that the user has ignored to the client. # # There is no way for clients to receive messages sent while a user was @@ -1264,6 +1453,11 @@ ignore_messages_from_server_names = {{ matrix_continuwuity_config_ignore_message # #send_messages_from_ignored_users_to_client = false +# Send "org.matrix.dummy_event" events to the client. This is a debugging +# option. +# +#send_dummy_events_to_clients = false + # Vector list of IPv4 and IPv6 CIDR ranges / subnets *in quotes* that you # do not want continuwuity to send outbound requests to. Defaults to # RFC1918, unroutable, loopback, multicast, and testnet addresses for @@ -1348,6 +1542,11 @@ url_preview_domain_explicit_allowlist = {{ matrix_continuwuity_config_url_previe # #url_preview_max_spider_size = 256000 +# Total request timeout for URL previews (seconds). This includes +# connection, request, and response body reading time. +# +#url_preview_timeout = 120 + # Option to decide whether you would like to run the domain allowlist # checks (contains and explicit) on the root domain or not. Does not apply # to URL contains allowlist. Defaults to false. @@ -1361,6 +1560,15 @@ url_preview_domain_explicit_allowlist = {{ matrix_continuwuity_config_url_previe # url_preview_check_root_domain = {{ matrix_continuwuity_config_url_preview_check_root_domain | to_json }} +# User agent that is used specifically when fetching url previews. +# +#url_preview_user_agent = "continuwuity/<version> (bot; +https://continuwuity.org)" + +# Determines whether audio and video files will be downloaded for URL +# previews. +# +#url_preview_allow_audio_video = false + # List of forbidden room aliases and room IDs as strings of regex # patterns. # @@ -1418,7 +1626,7 @@ url_preview_check_root_domain = {{ matrix_continuwuity_config_url_preview_check_ # a normal continuwuity admin command. The reply will be publicly visible # to the room, originating from the sender. # -# example: \\!admin debug ping puppygock.gay +# example: \\!admin debug ping continuwuity.org # #admin_escape_commands = true @@ -1436,7 +1644,8 @@ url_preview_check_root_domain = {{ matrix_continuwuity_config_url_preview_check_ # For example: `./continuwuity --execute "server admin-notice continuwuity # has started up at $(date)"` # -# example: admin_execute = ["debug ping puppygock.gay", "debug echo hi"]` +# example: admin_execute = ["debug ping continuwuity.org", "debug echo +# hi"]` # #admin_execute = [] @@ -1469,6 +1678,18 @@ url_preview_check_root_domain = {{ matrix_continuwuity_config_url_preview_check_ # #admin_room_tag = "m.server_notice" +# A list of Matrix IDs that are qualified as server admins. +# +# Any Matrix IDs within this list are regarded as an admin +# regardless of whether they are in the admin room or not +# +#admins_list = [] + +# Defines whether those within the admin room are added to the +# admins_list. +# +#admins_from_room = true + # Sentry.io crash/panic reporting, performance monitoring/metrics, etc. # This is NOT enabled by default. # @@ -1514,7 +1735,7 @@ url_preview_check_root_domain = {{ matrix_continuwuity_config_url_preview_check_ # Enable the tokio-console. This option is only relevant to developers. # -# For more information, see: +# For more information, see: # https://continuwuity.org/development.html#debugging-with-tokio-console # #tokio_console = false @@ -1620,6 +1841,11 @@ url_preview_check_root_domain = {{ matrix_continuwuity_config_url_preview_check_ # #config_reload_signal = true +# Allow search engines and crawlers to index Continuwuity's built-in +# webpages served under the `/_continuwuity/` prefix. +# +#allow_web_indexing = false + [global.tls] # Path to a valid TLS certificate file. @@ -1645,7 +1871,7 @@ url_preview_check_root_domain = {{ matrix_continuwuity_config_url_preview_check_ # # example: "https://matrix.example.com" # -#client = +client = {{ matrix_continuwuity_config_well_known_client | to_json }} # The server base domain of the URL with a specific port that the server # well-known file will serve. This should contain a port at the end, and @@ -1661,6 +1887,11 @@ url_preview_check_root_domain = {{ matrix_continuwuity_config_url_preview_check_ # #support_page = +# The ed25519 public key for the policy server available at this server's +# name. Must be unpadded base64. +# +#policy_server_public_key = + # Role string for server support contacts, to be served as part of the # MSC1929 server support endpoint at /.well-known/matrix/support. # @@ -1681,20 +1912,245 @@ url_preview_check_root_domain = {{ matrix_continuwuity_config_url_preview_check_ # #support_mxid = -[global.blurhashing] +# PGP key URI for server support contacts, to be served as part of the +# MSC1929 server support endpoint. +# +#support_pgp_key = + +[global.matrix_rtc] -# blurhashing x component, 4 is recommended by https://blurha.sh/ +# A list of MatrixRTC foci (transports) which will be served via the +# MSC4143 RTC transports endpoint at +# `/_matrix/client/v1/rtc/transports`. If you're setting up livekit, +# you'd want something like: +# ```toml +# [global.matrix_rtc] +# foci = [ +# { type = "livekit", livekit_service_url = "https://livekit.example.com" }, +# ] +# ``` # -#components_x = 4 +# To disable, set this to an empty list (`[]`). +# +foci = [ +{% for focus in matrix_continuwuity_config_rtc_foci %} + { {% for key, value in focus.items() %}{{ key }} = {{ value | to_json }}{% if not loop.last %}, {% endif %}{% endfor %} }{% if not loop.last %}, {% endif %} +{% endfor %} +] + +#[global.antispam] + +#[global.antispam.meowlnir] + +# The base URL on which to contact Meowlnir (before /_meowlnir/antispam). +# +# Example: "http://127.0.0.1:29339" +# +#base_url = + +# The authentication secret defined in antispam->secret. Required for +# continuwuity to talk to Meowlnir. +# +#secret = + +# The management room for which to send requests +# +#management_room = + +# If enabled run all federated join attempts (both federated and local) +# through the Meowlnir anti-spam checks. +# +# By default, only join attempts for rooms with the `fi.mau.spam_checker` +# restricted join rule are checked. +# +#check_all_joins = false + +#[global.antispam.draupnir] + +# The base URL on which to contact Draupnir (before /api/). +# +# Example: "http://127.0.0.1:29339" +# +#base_url = + +# The authentication secret defined in +# web->synapseHTTPAntispam->authorization +# +#secret = + +{% if matrix_continuwuity_config_smtp_enabled %} +[global.smtp] -# blurhashing y component, 3 is recommended by https://blurha.sh/ +# A `smtp://`` URI which will be used to connect to a mail server. +# Uncommenting the [global.smtp] group and setting this option enables +# features which depend on the ability to send email, +# such as self-service password resets. +# +# For most modern mail servers, format the URI like this: +# `smtps://username:password@hostname:port` +# Note that you will need to URL-encode the username and password. If your +# username _is_ your email address, you will need to replace the `@` with +# `%40`. # -#components_y = 3 +# For a guide on the accepted URI syntax, consult Lettre's documentation: +# https://docs.rs/lettre/latest/lettre/transport/smtp/struct.AsyncSmtpTransport.html#method.from_url +# +{% if matrix_continuwuity_config_smtp_connection_uri != '' and matrix_continuwuity_config_smtp_sender != '' %} +connection_uri = {{ matrix_continuwuity_config_smtp_connection_uri | to_json }} +{% else %} +#connection_uri = +{% endif %} -# Max raw size that the server will blurhash, this is the size of the -# image after converting it to raw data, it should be higher than the -# upload limit but not too high. The higher it is the higher the -# potential load will be for clients requesting blurhashes. The default -# is 33.55MB. Setting it to 0 disables blurhashing. +# The outgoing address which will be used for sending emails. +# +# For a syntax guide, see https://datatracker.ietf.org/doc/html/rfc2822#section-3.4 +# +# ...or if you don't want to read the RFC, for some reason: +# - `Name <address@domain.org>` to specify a sender name +# - `address@domain.org` to not use a name +# +{% if matrix_continuwuity_config_smtp_connection_uri != '' and matrix_continuwuity_config_smtp_sender != '' %} +sender = {{ matrix_continuwuity_config_smtp_sender | to_json }} +{% else %} +#sender = +{% endif %} + +# Whether to allow public registration with an email address. +# +# Note that, if this option is enabled, anyone will be able to register an +# account with just an email address. +# +# If either this option or `require_email_for_token_registration` are set, +# users will not be allowed to remove their email address. +# +require_email_for_registration = {{ matrix_continuwuity_config_smtp_require_email_for_registration | to_json }} + +# Whether to require that users who register with a registration token +# provide an email address. This option is independent of +# `require_email_for_registration`. +# +require_email_for_token_registration = {{ matrix_continuwuity_config_smtp_require_email_for_token_registration | to_json }} +{% endif %} + +#[global.registration_terms] + +# The language code to provide to clients along with the policy documents. +# +#language = "en" + +# Policy documents, such as terms and conditions or a privacy policy, +# which users must agree to when registering an account. +# +# Example: +# ```ignore +# [global.registration_terms.documents] +# privacy_policy = { name = "Privacy Policy", url = "https://homeserver.example/en/privacy_policy.html" } +# ``` +# +#documents = + +#[global.oauth] + +# The compatibility mode to use for OAuth. +# +# - "disabled": OAuth will be unavailable. Users will only be able to log +# in using legacy authentication. +# - "hybrid": OAuth and legacy authentication will both be available. Some +# clients may only use one or the other. +# - "exclusive": Only OAuth will be available. Clients which require +# legacy authentication will be unable to log in. +# +#compatibility_mode = "hybrid" + +#[global.oauth.oidc] +# Uncommenting this section will enable Continuwuity's support for +# authenticating users using an OpenID Connect-compatible identity provider. +# This is referred to as "delegated authentication". +# +# IMPORTANT NOTE: When delegated authentication is active, Continuwuity will behave as if +# the `global.oauth.compatibility_mode` setting is set to `exclusive`. +# Matrix clients which do not support OAuth login (also referred to as "next-gen auth") will NOT be able +# to log in while delegated authentication is active. + + +# The OIDC issuer URL. Continuwuity will use OpenID Connect Discovery to +# automatically fetch the identity provider's metadata from this URL. +# Generally you should set this to the base domain your identity provider +# runs on. +# +#discovery_url = + +# The OAuth client ID for Continuwuity to use when communicating with the +# identity provider. +# +#client_id = + +# The OAuth client secret for Continuwuity to use when communicating with +# the identity provider. +# +#client_secret = + +# A path to a file which Continuwuity will read the client secret from. +# If this option is set, it will override `client_secret`. +# +# The server will fail to start if the file cannot be read. +# +#client_secret_file = + +# Additional scopes Continuwuity should request from the IDP. This may be +# necessary to access certain claims. Continuwuity always requests the +# `openid` scope. +# +#additional_scopes = [] + +# Whether the user should be prompted to choose a localpart +# when signing in for the first time. If this is `false`, Continuwuity +# will attempt to use the value of the `preferred_username_claim` +# (see below) as the user's localpart. Authentication will +# fail if this claim is missing or is not a valid localpart. +# +#prompt_for_localpart = true + +# The claim to use for the user's localpart, if `prompt_for_localpart` is +# false. +# +#preferred_username_claim = "preferred_username" + +# The claim which will be used to set the user's email address, +# either on initial registration or on every login depending on +# the value of `profile_key_import_mode`. Continuwuity assumes that +# the IDP has taken care of verifying that the user controls the email +# address it provides. +# +# This option does nothing if SMTP is not configured. +# +# If this option is set, and `profile_key_import_mode` is `on_login`, +# users will not be able to change their email addresses themselves. +# +#email_claim = "email" + +# Defines how claims returned from the IDP should be mapped to a user's +# profile data. The profile field named in each key will be set from the +# claim named in the corresponding value when the user first registers, +# and possibly on subsequent logins as well, depending on the value of +# `profile_key_import_mode` (see below). +# +# Per-room overrides to the user's display name or avatar will be +# preserved by the import process. +# +# SECURITY NOTE: If the `avatar_url` field is set, Continuwuity will +# perform a HTTP GET to the URL in the mapped claim and use the returned +# file as the user's profile picture. Make sure your users are not able +# to set the value of the mapped claim to an arbitrary URL. +# +#profile_key_map = { displayname = "name" } + +# When profile keys should be imported from the IDP's claims. +# +# - "on_registration": Listed keys will be imported once, when the user +# logs in for the first time and their shadow account is created. +# - "on_login": Listed keys will be imported every time the user logs in. +# Additionally, users will not be able to manually edit any listed keys +# through their Matrix client. # -#blurhash_max_raw_size = 33554432 +#profile_key_import_mode = "on_registration" diff --git a/roles/custom/matrix-continuwuity/templates/systemd/matrix-continuwuity.service.j2 b/roles/custom/matrix-continuwuity/templates/systemd/matrix-continuwuity.service.j2 index 155861fdc..da53c33be 100644 --- a/roles/custom/matrix-continuwuity/templates/systemd/matrix-continuwuity.service.j2 +++ b/roles/custom/matrix-continuwuity/templates/systemd/matrix-continuwuity.service.j2 @@ -5,6 +5,9 @@ Description=continuwuity Matrix homeserver Requires={{ service }} After={{ service }} {% endfor %} +{% for service in matrix_continuwuity_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} [Service] Type=simple @@ -31,9 +34,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_continuwuity_container_image }} +{% if matrix_continuwuity_container_network != 'host' %} {% for network in matrix_continuwuity_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-continuwuity {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-continuwuity diff --git a/roles/custom/matrix-continuwuity/vars/main.yml b/roles/custom/matrix-continuwuity/vars/main.yml index d51a37c72..900935924 100644 --- a/roles/custom/matrix-continuwuity/vars/main.yml +++ b/roles/custom/matrix-continuwuity/vars/main.yml @@ -1,9 +1,15 @@ # SPDX-FileCopyrightText: 2025 MDAD project contributors # SPDX-FileCopyrightText: 2025 Slavi Pantaleev +# SPDX-FileCopyrightText: 2026 Catalan Lover <catalanlover@protonmail.com> # # SPDX-License-Identifier: AGPL-3.0-or-later --- +# Continuwuity has no dedicated "enable ReCAPTCHA" setting. It enables ReCAPTCHA registration based on the +# presence of a recaptcha private site key, so we only render the keys when both have been configured. +# This avoids rendering empty keys, which would otherwise enable a broken ReCAPTCHA flow. +matrix_continuwuity_recaptcha_enabled: "{{ matrix_continuwuity_config_recaptcha_site_key | string | length > 0 and matrix_continuwuity_config_recaptcha_private_site_key | string | length > 0 }}" + matrix_continuwuity_client_api_url_endpoint_public: "{{ 'https' if matrix_playbook_ssl_enabled else 'http' }}://{{ matrix_continuwuity_hostname }}/_matrix/client/versions" matrix_continuwuity_federation_api_url_endpoint_public: "{{ 'https' if matrix_playbook_ssl_enabled else 'http' }}://{{ matrix_continuwuity_hostname }}:{{ matrix_federation_public_port }}/_matrix/federation/v1/version" diff --git a/roles/custom/matrix-corporal/defaults/main.yml b/roles/custom/matrix-corporal/defaults/main.yml index e9804bfc9..e33c02cbf 100644 --- a/roles/custom/matrix-corporal/defaults/main.yml +++ b/roles/custom/matrix-corporal/defaults/main.yml @@ -97,7 +97,6 @@ matrix_corporal_container_image_registry_prefix: "{{ 'localhost/' if matrix_corp matrix_corporal_container_image_registry_prefix_upstream: "{{ matrix_corporal_container_image_registry_prefix_upstream_default }}" matrix_corporal_container_image_registry_prefix_upstream_default: ghcr.io/ matrix_corporal_container_image_tag: "{{ matrix_corporal_version }}" # for backward-compatibility -matrix_corporal_container_image_force_pull: "{{ matrix_corporal_container_image.endswith(':latest') }}" matrix_corporal_base_path: "{{ matrix_base_data_path }}/corporal" matrix_corporal_container_src_files_path: "{{ matrix_corporal_base_path }}/container-src" diff --git a/roles/custom/matrix-corporal/tasks/setup_install.yml b/roles/custom/matrix-corporal/tasks/setup_install.yml index 59ed9c44a..ede0b2b7a 100644 --- a/roles/custom/matrix-corporal/tasks/setup_install.yml +++ b/roles/custom/matrix-corporal/tasks/setup_install.yml @@ -24,6 +24,16 @@ - "{{ matrix_corporal_cache_dir_path }}" - "{{ matrix_corporal_var_dir_path }}" +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Matrix Corporal repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_corporal_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: matrix_corporal_container_image_self_build | bool + - name: Ensure Matrix Corporal repository is present on self-build ansible.builtin.git: repo: "{{ matrix_corporal_container_image_self_build_repo }}" @@ -36,23 +46,19 @@ when: matrix_corporal_container_image_self_build | bool - name: Ensure Matrix Corporal Docker image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_corporal_container_image }}" - source: build - force_source: "{{ matrix_corporal_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_corporal_git_pull_results.changed }}" - build: - dockerfile: etc/docker/Dockerfile - path: "{{ matrix_corporal_container_src_files_path }}" - pull: true + dockerfile: etc/docker/Dockerfile + path: "{{ matrix_corporal_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_corporal_git_pull_results.changed | bool else 'never' }}" when: matrix_corporal_container_image_self_build | bool + register: matrix_corporal_container_image_build_result - name: Ensure Matrix Corporal Docker image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_corporal_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_corporal_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_corporal_container_image_force_pull }}" + pull: always when: not matrix_corporal_container_image_self_build | bool register: matrix_corporal_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -80,6 +86,7 @@ register: matrix_corporal_support_files_result - name: Ensure Matrix Corporal container network is created + when: matrix_corporal_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_corporal_container_network }}" @@ -101,4 +108,5 @@ or matrix_corporal_support_files_result.changed | default(false) or matrix_corporal_systemd_service_result.changed | default(false) or matrix_corporal_container_image_pull_result.changed | default(false) + or matrix_corporal_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-corporal/tasks/validate_config.yml b/roles/custom/matrix-corporal/tasks/validate_config.yml index 86a60252d..774e2b8e0 100644 --- a/roles/custom/matrix-corporal/tasks/validate_config.yml +++ b/roles/custom/matrix-corporal/tasks/validate_config.yml @@ -18,6 +18,7 @@ - {'old': 'matrix_corporal_container_image_name_prefix', 'new': 'matrix_corporal_container_image_registry_prefix'} - {'old': 'matrix_corporal_docker_image', 'new': 'matrix_corporal_container_image'} - {'old': 'matrix_corporal_docker_image_force_pull', 'new': 'matrix_corporal_container_image_force_pull'} + - {'old': 'matrix_corporal_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - {'old': 'matrix_corporal_docker_image_registry_prefix', 'new': 'matrix_corporal_container_image_registry_prefix'} - {'old': 'matrix_corporal_docker_image_registry_prefix_upstream', 'new': 'matrix_corporal_container_image_registry_prefix_upstream'} - {'old': 'matrix_corporal_docker_image_registry_prefix_upstream_default', 'new': 'matrix_corporal_container_image_registry_prefix_upstream_default'} diff --git a/roles/custom/matrix-corporal/templates/systemd/matrix-corporal.service.j2 b/roles/custom/matrix-corporal/templates/systemd/matrix-corporal.service.j2 index f9d2eeff7..73cec888e 100644 --- a/roles/custom/matrix-corporal/templates/systemd/matrix-corporal.service.j2 +++ b/roles/custom/matrix-corporal/templates/systemd/matrix-corporal.service.j2 @@ -37,9 +37,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {{ matrix_corporal_container_image }} \ /matrix-corporal -config=/etc/matrix-corporal/config.json +{% if matrix_corporal_container_network != 'host' %} {% for network in matrix_corporal_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-corporal {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-corporal diff --git a/roles/custom/matrix-dendrite/defaults/main.yml b/roles/custom/matrix-dendrite/defaults/main.yml index 4eb4c7f5f..35debaae4 100644 --- a/roles/custom/matrix-dendrite/defaults/main.yml +++ b/roles/custom/matrix-dendrite/defaults/main.yml @@ -30,7 +30,6 @@ matrix_dendrite_container_image_registry_prefix_upstream: "{{ matrix_dendrite_co matrix_dendrite_container_image_registry_prefix_upstream_default: docker.io/ # renovate: datasource=docker depName=matrixdotorg/dendrite-monolith matrix_dendrite_container_image_tag: "v0.15.2" -matrix_dendrite_container_image_force_pull: "{{ matrix_dendrite_container_image.endswith(':latest') }}" matrix_dendrite_base_path: "{{ matrix_base_data_path }}/dendrite" matrix_dendrite_config_dir_path: "{{ matrix_dendrite_base_path }}/config" diff --git a/roles/custom/matrix-dendrite/tasks/setup_install.yml b/roles/custom/matrix-dendrite/tasks/setup_install.yml index 117e715ff..ef5735254 100644 --- a/roles/custom/matrix-dendrite/tasks/setup_install.yml +++ b/roles/custom/matrix-dendrite/tasks/setup_install.yml @@ -49,11 +49,9 @@ when: "not local_path_media_store_stat.failed and not local_path_media_store_stat.stat.exists" - name: Ensure Dendrite Docker image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_dendrite_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_dendrite_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_dendrite_container_image_force_pull }}" + pull: always when: "not matrix_dendrite_container_image_self_build | bool" register: matrix_dendrite_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -93,6 +91,15 @@ - when: "matrix_dendrite_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure Dendrite repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_dendrite_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure Dendrite repository is present on self-build ansible.builtin.git: repo: "{{ matrix_dendrite_container_image_self_build_repo }}" @@ -120,6 +127,7 @@ when: "matrix_dendrite_git_pull_results.changed | bool or matrix_dendrite_container_image_check_result.stdout == ''" - name: Ensure Dendrite container network is created + when: matrix_dendrite_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_dendrite_container_network }}" diff --git a/roles/custom/matrix-dendrite/tasks/validate_config.yml b/roles/custom/matrix-dendrite/tasks/validate_config.yml index 5a8f8756a..1a2f4828d 100644 --- a/roles/custom/matrix-dendrite/tasks/validate_config.yml +++ b/roles/custom/matrix-dendrite/tasks/validate_config.yml @@ -43,6 +43,7 @@ - {'old': 'matrix_dendrite_docker_image_registry_prefix_upstream_default', 'new': 'matrix_dendrite_container_image_registry_prefix_upstream_default'} - {'old': 'matrix_dendrite_docker_image_tag', 'new': 'matrix_dendrite_container_image_tag'} - {'old': 'matrix_dendrite_docker_src_files_path', 'new': 'matrix_dendrite_container_src_files_path'} + - {'old': 'matrix_dendrite_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required Dendrite settings not defined ansible.builtin.fail: diff --git a/roles/custom/matrix-dendrite/templates/systemd/matrix-dendrite.service.j2 b/roles/custom/matrix-dendrite/templates/systemd/matrix-dendrite.service.j2 index 31e485150..698ae0835 100644 --- a/roles/custom/matrix-dendrite/templates/systemd/matrix-dendrite.service.j2 +++ b/roles/custom/matrix-dendrite/templates/systemd/matrix-dendrite.service.j2 @@ -57,9 +57,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ -https-bind-address {{ matrix_dendrite_https_bind_address }} {% endif %} +{% if matrix_dendrite_container_network != 'host' %} {% for network in matrix_dendrite_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-dendrite {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-dendrite diff --git a/roles/custom/matrix-element-admin/defaults/main.yml b/roles/custom/matrix-element-admin/defaults/main.yml index 6cfff7df1..f6650473f 100644 --- a/roles/custom/matrix-element-admin/defaults/main.yml +++ b/roles/custom/matrix-element-admin/defaults/main.yml @@ -11,7 +11,7 @@ matrix_element_admin_enabled: true # renovate: datasource=docker depName=oci.element.io/element-admin -matrix_element_admin_version: 0.1.11 +matrix_element_admin_version: 0.1.13 matrix_element_admin_scheme: https @@ -31,7 +31,6 @@ matrix_element_admin_container_src_path: "{{ matrix_element_admin_base_path }}/c matrix_element_admin_container_image: "{{ matrix_element_admin_container_image_registry_prefix }}element-admin:{{ matrix_element_admin_container_image_tag }}" matrix_element_admin_container_image_tag: "{{ matrix_element_admin_version }}" -matrix_element_admin_container_image_force_pull: "{{ matrix_element_admin_container_image.endswith(':main') }}" matrix_element_admin_container_image_registry_prefix: "{{ matrix_element_admin_container_image_registry_prefix_upstream }}" matrix_element_admin_container_image_registry_prefix_upstream: "{{ matrix_element_admin_container_image_registry_prefix_upstream_default }}" matrix_element_admin_container_image_registry_prefix_upstream_default: "oci.element.io/" diff --git a/roles/custom/matrix-element-admin/molecule/default/converge.yml b/roles/custom/matrix-element-admin/molecule/default/converge.yml new file mode 100644 index 000000000..da304cc84 --- /dev/null +++ b/roles/custom/matrix-element-admin/molecule/default/converge.yml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-element-admin Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-element-admin Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +# The component role installs the unit; the full playbook's systemd service manager +# starts it. Keep the role-scoped scenario at the same boundary and start it directly. +- name: Ensure matrix-element-admin is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the matrix-element-admin systemd service is started + ansible.builtin.systemd_service: + name: matrix-element-admin.service + state: started diff --git a/roles/custom/matrix-element-admin/molecule/default/molecule.yml b/roles/custom/matrix-element-admin/molecule/default/molecule.yml new file mode 100644 index 000000000..792528069 --- /dev/null +++ b/roles/custom/matrix-element-admin/molecule/default/molecule.yml @@ -0,0 +1,74 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-element-admin-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + # verify.yml is a separate play where the role's defaults are out of scope. + # Use a deliberately non-default storage path, not merely the value the role + # derives from matrix_base_data_path, so its rendered support-file locations + # and the systemd unit's --env-file/--label-file contract are exercised. + matrix_element_admin_base_path: /matrix/molecule-element-admin + + matrix_element_admin_container_network: matrix-element-admin-molecule + + # Element Admin currently hardcodes browser asset paths to `/`, so the role + # correctly rejects a non-root public prefix. Exercise non-default public + # routing through the hostname, priority and plain-HTTP entrypoint instead. + matrix_element_admin_hostname: element-admin-console.molecule.local + matrix_element_admin_path_prefix: / + matrix_element_admin_container_labels_traefik_enabled: true + matrix_element_admin_container_labels_traefik_priority: 619 + matrix_element_admin_container_labels_traefik_entrypoints: web + matrix_element_admin_container_labels_traefik_tls: false + matrix_element_admin_container_labels_additional_labels: | + molecule.element-admin.coverage=enabled + + # The image's entrypoint embeds its browser configuration into index.html + # from SERVER_NAME. + # This differs from the role and application's defaults, making the live HTTP + # response evidence that the rendered env file reached the process. + matrix_element_admin_environment_variable_server_name: matrix-backend.molecule.local + matrix_element_admin_environment_variables_additional_variables: | + MOLECULE_ELEMENT_ADMIN_MARKER=environment-reached + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-element-admin/molecule/default/prepare.yml b/roles/custom/matrix-element-admin/molecule/default/prepare.yml new file mode 100644 index 000000000..daae41462 --- /dev/null +++ b/roles/custom/matrix-element-admin/molecule/default/prepare.yml @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-element-admin Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # matrix-base creates this identity in a full deployment. The role's file tasks + # resolve owner and group by name, so the role-scoped test provides it directly. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" diff --git a/roles/custom/matrix-element-admin/molecule/default/requirements.yml b/roles/custom/matrix-element-admin/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-element-admin/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-element-admin/molecule/default/verify.yml b/roles/custom/matrix-element-admin/molecule/default/verify.yml new file mode 100644 index 000000000..f3d4705fb --- /dev/null +++ b/roles/custom/matrix-element-admin/molecule/default/verify.yml @@ -0,0 +1,307 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Element Admin is a static browser client. Its real application root and the live +# configuration embedded from the role's env file are the weight-bearing checks; no +# homeserver or third-party credentials are needed for the process to start. +- name: Verify matrix-element-admin + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + matrix_element_admin_root_body: "{{ matrix_element_admin_root_http.stdout_lines[:-1] | join('\n') }}" + matrix_element_admin_runtime: "{{ (matrix_element_admin_container_inspect.stdout | from_json) | first }}" + gather_facts: false + + tasks: + # Loading the pin from the role keeps this scenario coupled to the shipped image + # without duplicating a version which could silently drift. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_element_admin_role_defaults + + - name: Wait for the matrix-element-admin service to become active + ansible.builtin.systemd_service: + name: matrix-element-admin.service + register: matrix_element_admin_service + until: matrix_element_admin_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always means ActiveState alone can be green while the container crash-loops. + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_element_admin_service.status.ActiveState == 'active' + - matrix_element_admin_service.status.NRestarts is defined + - matrix_element_admin_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-element-admin.service is + {{ matrix_element_admin_service.status.ActiveState | default('unknown') }} after + {{ matrix_element_admin_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-element-admin.service is active and has not restarted" + + # Probe over the dedicated container network. Publishing a host port only for the + # test would diverge from how Traefik reaches the service in real installations. + - name: Wait for Element Admin to serve its application root + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_element_admin_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-element-admin:8080/ + register: matrix_element_admin_root_http + changed_when: false + until: "'HTTP_STATUS=200' in matrix_element_admin_root_http.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the application root is real Element Admin HTML + ansible.builtin.assert: + that: + - matrix_element_admin_root_http.rc == 0 + - matrix_element_admin_root_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_element_admin_root_body | trim | length > 100 + - "'<!doctype html' in matrix_element_admin_root_body | lower" + - "'element admin' in matrix_element_admin_root_body | lower" + fail_msg: >- + Element Admin did not return its application HTML from the container network + (rc={{ matrix_element_admin_root_http.rc }}, status={{ matrix_element_admin_root_http.stdout_lines[-1] | default('missing') }}) + success_msg: "Element Admin serves its real application root over HTTP" + + # The image entrypoint base64-embeds JSON in index.html from SERVER_NAME. Decode + # that exact live value instead of trusting that the environment merely exists. + - name: Extract the live configuration and application asset path + ansible.builtin.set_fact: + matrix_element_admin_embedded_config_base64: >- + {{ matrix_element_admin_root_body | regex_search('(?<=window.APP_CONFIG_BASE64 = ")[^"]+(?=";)') }} + matrix_element_admin_application_asset_path: >- + {{ matrix_element_admin_root_body | regex_search('(?<=src=")[/]assets[/][^"]+(?=")') }} + + - name: Decode the live Element Admin configuration + ansible.builtin.set_fact: + matrix_element_admin_embedded_config: >- + {{ matrix_element_admin_embedded_config_base64 | b64decode | from_json }} + + - name: Assert the live configuration carries the configured homeserver name + ansible.builtin.assert: + that: + - matrix_element_admin_embedded_config is mapping + - matrix_element_admin_embedded_config.keys() | list == ['serverName'] + - matrix_element_admin_embedded_config.serverName == matrix_element_admin_environment_variable_server_name + fail_msg: >- + Element Admin's live embedded configuration does not carry the SERVER_NAME value rendered by the role + success_msg: "The live application configuration carries the configured homeserver name" + + # Fetch a hashed application bundle referenced by the live HTML. This exercises a + # real non-root HTTP path without claiming support for an invalid public subpath. + - name: Fetch a live Element Admin application asset + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_element_admin_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}\nCONTENT_TYPE=%{content_type}\nSIZE=%{size_download}" + - "http://matrix-element-admin:8080{{ matrix_element_admin_application_asset_path }}" + register: matrix_element_admin_asset_http + changed_when: false + failed_when: false + + - name: Assert the non-root application asset is served + ansible.builtin.assert: + that: + - matrix_element_admin_asset_http.rc == 0 + - "'HTTP_STATUS=200' in matrix_element_admin_asset_http.stdout_lines" + - matrix_element_admin_asset_http.stdout | regex_search('(?m)^CONTENT_TYPE=application/javascript(?:;|$)') is not none + - matrix_element_admin_asset_http.stdout | regex_search('SIZE=([1-9][0-9]{2,})') is not none + fail_msg: "Element Admin did not serve the application bundle referenced by its live HTML" + success_msg: "Element Admin serves a real non-root application asset" + + - name: Read the environment file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_element_admin_base_path }}/env" + register: matrix_element_admin_env_file + + - name: Initialize the parsed environment + ansible.builtin.set_fact: + matrix_element_admin_env_parsed: {} + + - name: Parse the rendered environment + ansible.builtin.set_fact: + matrix_element_admin_env_parsed: >- + {{ matrix_element_admin_env_parsed | combine({item.split('=', 1)[0]: item.split('=', 1)[1]}) }} + loop: "{{ (matrix_element_admin_env_file.content | b64decode).splitlines() | reject('equalto', '') }}" + when: "'=' in item" + no_log: true + + - name: Assert the rendered environment carries the scenario settings + ansible.builtin.assert: + that: + - matrix_element_admin_env_parsed.SERVER_NAME == matrix_element_admin_environment_variable_server_name + - matrix_element_admin_env_parsed.MOLECULE_ELEMENT_ADMIN_MARKER == 'environment-reached' + fail_msg: "The parsed environment does not carry the scenario's values" + success_msg: "The parsed environment carries the scenario's values" + + - name: Read the labels file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_element_admin_base_path }}/labels" + register: matrix_element_admin_labels_file + + - name: Initialize the parsed labels + ansible.builtin.set_fact: + matrix_element_admin_labels_parsed: {} + + - name: Parse the rendered labels + ansible.builtin.set_fact: + matrix_element_admin_labels_parsed: >- + {{ matrix_element_admin_labels_parsed | combine({item.split('=', 1)[0]: item.split('=', 1)[1]}) }} + loop: "{{ (matrix_element_admin_labels_file.content | b64decode).splitlines() | reject('equalto', '') }}" + when: "'=' in item" + no_log: true + + - name: Assert the rendered labels carry the public routing contract + ansible.builtin.assert: + that: + - matrix_element_admin_labels_parsed['traefik.enable'] == 'true' + - matrix_element_admin_labels_parsed['traefik.docker.network'] == matrix_element_admin_container_network + - matrix_element_admin_labels_parsed['traefik.http.services.matrix-element-admin.loadbalancer.server.port'] == '8080' + - matrix_element_admin_labels_parsed['traefik.http.routers.matrix-element-admin.rule'] == 'Host(`element-admin-console.molecule.local`)' + - matrix_element_admin_labels_parsed['traefik.http.routers.matrix-element-admin.priority'] == '619' + - matrix_element_admin_labels_parsed['traefik.http.routers.matrix-element-admin.entrypoints'] == 'web' + - matrix_element_admin_labels_parsed['traefik.http.routers.matrix-element-admin.tls'] == 'false' + - matrix_element_admin_labels_parsed['molecule.element-admin.coverage'] == 'enabled' + fail_msg: "The rendered labels do not carry the scenario's routing values" + success_msg: "The rendered labels carry the scenario's routing values" + + - name: Inspect the running Element Admin container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-element-admin + register: matrix_element_admin_container_inspect + changed_when: false + + - name: Assert the configured environment reached the running container + ansible.builtin.assert: + that: + - "('SERVER_NAME=' ~ matrix_element_admin_environment_variable_server_name) in matrix_element_admin_runtime.Config.Env" + - "'MOLECULE_ELEMENT_ADMIN_MARKER=environment-reached' in matrix_element_admin_runtime.Config.Env" + fail_msg: "The running container environment does not carry the scenario's settings" + success_msg: "The configured environment reached the running container" + + - name: Assert the rendered labels reached the running container + ansible.builtin.assert: + that: + - matrix_element_admin_runtime.Config.Labels['traefik.enable'] == 'true' + - matrix_element_admin_runtime.Config.Labels['traefik.docker.network'] == matrix_element_admin_container_network + - matrix_element_admin_runtime.Config.Labels['traefik.http.routers.matrix-element-admin.priority'] == '619' + - matrix_element_admin_runtime.Config.Labels['molecule.element-admin.coverage'] == 'enabled' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The rendered labels reached the running container" + + - name: Assert the running container uses the exact image and version the role pins + ansible.builtin.assert: + that: + - matrix_element_admin_runtime.Config.Image == matrix_element_admin_expected_image + fail_msg: >- + The running container uses {{ matrix_element_admin_runtime.Config.Image }}, + expected {{ matrix_element_admin_expected_image }} + success_msg: "The running container uses the exact image and version defaults/main.yml pins" + vars: + matrix_element_admin_expected_image: >- + {{ matrix_element_admin_role_defaults.matrix_element_admin_container_image_registry_prefix_upstream_default }}element-admin:{{ matrix_element_admin_role_defaults.matrix_element_admin_version }} + + - name: Assert the running container uses the configured UID and GID + ansible.builtin.assert: + that: + - matrix_element_admin_runtime.Config.User == (matrix_user_uid | string) ~ ':' ~ (matrix_user_gid | string) + fail_msg: >- + The running container uses {{ matrix_element_admin_runtime.Config.User }}, + expected {{ matrix_user_uid }}:{{ matrix_user_gid }} + success_msg: "The running container uses the configured UID and GID" + + - name: Assert the running container command contract + ansible.builtin.assert: + that: + - matrix_element_admin_runtime.Config.Entrypoint == ['/docker-entrypoint.sh'] + - matrix_element_admin_runtime.Config.Cmd == ['nginx', '-g', 'daemon off;'] + fail_msg: >- + The running container has unexpected entrypoint/command values: + {{ matrix_element_admin_runtime.Config.Entrypoint }} {{ matrix_element_admin_runtime.Config.Cmd }} + success_msg: "The role preserves the image's Element Admin entrypoint and command" + + - name: Assert the running container security contract + ansible.builtin.assert: + that: + - matrix_element_admin_runtime.HostConfig.ReadonlyRootfs is sameas true + - matrix_element_admin_runtime.HostConfig.Privileged is sameas false + - matrix_element_admin_runtime.HostConfig.CapAdd | default([], true) | length == 0 + - matrix_element_admin_runtime.HostConfig.CapDrop == ['ALL'] + fail_msg: "The Element Admin container is missing its read-only root or dropped capabilities" + success_msg: "The Element Admin container has a read-only root and all capabilities dropped" + + - name: Assert the intended writable path is a constrained tmpfs mount + ansible.builtin.assert: + that: + - matrix_element_admin_runtime.Mounts | length == 0 + - matrix_element_admin_runtime.HostConfig.Binds | default([], true) | length == 0 + - matrix_element_admin_runtime.HostConfig.Tmpfs.keys() | list == ['/tmp'] + - matrix_element_admin_runtime.HostConfig.Tmpfs['/tmp'] == 'rw,noexec,nosuid,size=1024m' + fail_msg: "The running container does not have the role's exact /tmp tmpfs contract" + success_msg: "The running container has the exact constrained /tmp tmpfs mount" + + - name: Assert the running container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_element_admin_runtime.NetworkSettings.Networks is mapping + - matrix_element_admin_runtime.NetworkSettings.Networks | length == 1 + - matrix_element_admin_container_network in matrix_element_admin_runtime.NetworkSettings.Networks + fail_msg: >- + Element Admin has unexpected network attachments: + {{ matrix_element_admin_runtime.NetworkSettings.Networks.keys() | list }} + success_msg: "The running container is attached only to its dedicated network" + + - name: Ask Docker for Element Admin's published ports + ansible.builtin.command: + argv: + - docker + - container + - port + - matrix-element-admin + register: matrix_element_admin_published_ports + changed_when: false + failed_when: false + + - name: Assert the role publishes no host ports + ansible.builtin.assert: + that: + - matrix_element_admin_runtime.Config.ExposedPorts.keys() | list == ['8080/tcp'] + - matrix_element_admin_runtime.HostConfig.PortBindings | default({}, true) | length == 0 + - matrix_element_admin_published_ports.rc == 0 + - matrix_element_admin_published_ports.stdout | trim | length == 0 + fail_msg: >- + Element Admin unexpectedly publishes a host port: + {{ matrix_element_admin_published_ports.stdout | default('unknown') }} + success_msg: "The role leaves Element Admin's HTTP port unpublished" diff --git a/roles/custom/matrix-element-admin/tasks/install.yml b/roles/custom/matrix-element-admin/tasks/install.yml index 5cf94471a..c54ac9c8d 100644 --- a/roles/custom/matrix-element-admin/tasks/install.yml +++ b/roles/custom/matrix-element-admin/tasks/install.yml @@ -32,11 +32,9 @@ register: matrix_element_admin_support_files_result - name: Ensure Element Admin container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_element_admin_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_element_admin_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_element_admin_container_image_force_pull }}" + pull: always when: "not matrix_element_admin_container_image_self_build | bool" register: matrix_element_admin_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -45,6 +43,15 @@ - when: matrix_element_admin_container_image_self_build | bool block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure Element Admin repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_element_admin_container_src_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure Element Admin repository is present on self-build ansible.builtin.git: repo: "{{ matrix_element_admin_container_image_self_build_repo }}" @@ -65,6 +72,7 @@ changed_when: true - name: Ensure Element Admin container network is created + when: matrix_element_admin_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_element_admin_container_network }}" diff --git a/roles/custom/matrix-element-admin/tasks/validate_config.yml b/roles/custom/matrix-element-admin/tasks/validate_config.yml index 72f01e1af..60ca49d11 100644 --- a/roles/custom/matrix-element-admin/tasks/validate_config.yml +++ b/roles/custom/matrix-element-admin/tasks/validate_config.yml @@ -24,3 +24,11 @@ Element Admin with a path prefix other than '/' is not supported yet. You have configured matrix_element_admin_path_prefix to '{{ matrix_element_admin_path_prefix }}'. when: "matrix_element_admin_path_prefix != '/'" + +- name: (Deprecation) Catch and report renamed Element Admin variables + ansible.builtin.fail: + msg: >- + The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_element_admin_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-element-admin/templates/systemd/matrix-element-admin.service.j2 b/roles/custom/matrix-element-admin/templates/systemd/matrix-element-admin.service.j2 index 35e64d9e6..03511f8f5 100644 --- a/roles/custom/matrix-element-admin/templates/systemd/matrix-element-admin.service.j2 +++ b/roles/custom/matrix-element-admin/templates/systemd/matrix-element-admin.service.j2 @@ -35,9 +35,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_element_admin_container_image }} {{ matrix_element_admin_container_process_extra_arguments | join(' ') }} +{% if matrix_element_admin_container_network != 'host' %} {% for network in matrix_element_admin_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-element-admin {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-element-admin diff --git a/roles/custom/matrix-element-call/defaults/main.yml b/roles/custom/matrix-element-call/defaults/main.yml index 4c9519f2a..994c1d161 100644 --- a/roles/custom/matrix-element-call/defaults/main.yml +++ b/roles/custom/matrix-element-call/defaults/main.yml @@ -21,7 +21,7 @@ matrix_element_call_enabled: false matrix_rtc_enabled: "{{ matrix_element_call_enabled }}" # renovate: datasource=docker depName=ghcr.io/element-hq/element-call -matrix_element_call_version: v0.18.0 +matrix_element_call_version: v0.25.0 matrix_element_call_scheme: https @@ -39,7 +39,6 @@ matrix_element_call_container_image_registry_prefix: "{{ matrix_element_call_con matrix_element_call_container_image_registry_prefix_upstream: "{{ matrix_element_call_container_image_registry_prefix_upstream_default }}" matrix_element_call_container_image_registry_prefix_upstream_default: ghcr.io/ matrix_element_call_container_image_tag: "{{ matrix_element_call_version }}" -matrix_element_call_container_image_force_pull: "{{ matrix_element_call_container_image.endswith(':latest') }}" matrix_element_call_container_network: matrix-element-call diff --git a/roles/custom/matrix-element-call/molecule/default/converge.yml b/roles/custom/matrix-element-call/molecule/default/converge.yml new file mode 100644 index 000000000..cd2e221c7 --- /dev/null +++ b/roles/custom/matrix-element-call/molecule/default/converge.yml @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-element-call Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include base roles for matrix-element-call Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + loop_control: + loop_var: role_name + + - name: Include matrix-element-call + ansible.builtin.include_role: + name: "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + public: true + +# The role installs the unit; the full playbook's systemd service manager starts it. +- name: Ensure matrix-element-call is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the matrix-element-call systemd service is started + ansible.builtin.systemd_service: + name: matrix-element-call.service + state: started diff --git a/roles/custom/matrix-element-call/molecule/default/molecule.yml b/roles/custom/matrix-element-call/molecule/default/molecule.yml new file mode 100644 index 000000000..af291bc22 --- /dev/null +++ b/roles/custom/matrix-element-call/molecule/default/molecule.yml @@ -0,0 +1,79 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-element-call-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_element_call_enabled: true + matrix_element_call_architecture: amd64 + + # Keep the role's files away from its matrix_base_data_path-derived default, + # proving that both the renderer and the systemd unit honor this contract. + matrix_element_call_base_path: /matrix/molecule-element-call + + matrix_element_call_container_network: matrix-element-call-molecule + + # Both values differ from the role and application defaults. The live + # /config.json response proves they reached the browser application. + matrix_element_call_config_default_server_config_m_homeserver_base_url: https://homeserver.call.molecule.local + matrix_element_call_config_default_server_config_m_homeserver_server_name: call-molecule.local + matrix_element_call_config_livekit_livekit_service_url: https://livekit-jwt.call.molecule.local + + # Exercise the generated public routing and response-header labels. + matrix_element_call_hostname: call.molecule.local + matrix_element_call_container_labels_traefik_enabled: true + matrix_element_call_container_labels_traefik_priority: 827 + matrix_element_call_container_labels_traefik_entrypoints: web + matrix_element_call_container_labels_traefik_tls: false + matrix_element_call_http_header_xss_protection: "0" + matrix_element_call_http_header_content_type_options: molecule-nosniff + matrix_element_call_http_header_content_security_policy: "frame-ancestors https://embed.call.molecule.local" + matrix_element_call_http_header_content_permission_policy: "camera=(self), microphone=(self)" + matrix_element_call_container_labels_additional_labels: | + molecule.element-call.coverage=enabled + + # Make the generic Docker-argument escape hatch observable. + matrix_element_call_container_extra_arguments: + - --hostname=element-call-molecule-runtime + - --label=molecule.element-call.extra-argument=reached + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-element-call/molecule/default/prepare.yml b/roles/custom/matrix-element-call/molecule/default/prepare.yml new file mode 100644 index 000000000..adb7e2bdd --- /dev/null +++ b/roles/custom/matrix-element-call/molecule/default/prepare.yml @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-element-call Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # matrix-base creates this identity in a full deployment. The role's file tasks + # resolve owner and group by name, so the role-scoped test provides it directly. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" diff --git a/roles/custom/matrix-element-call/molecule/default/requirements.yml b/roles/custom/matrix-element-call/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-element-call/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-element-call/molecule/default/verify.yml b/roles/custom/matrix-element-call/molecule/default/verify.yml new file mode 100644 index 000000000..cd520eb12 --- /dev/null +++ b/roles/custom/matrix-element-call/molecule/default/verify.yml @@ -0,0 +1,318 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Element Call is a static browser application. Its live JSON configuration and +# a browser bundle are the weight-bearing probes; no Matrix or LiveKit account is needed. +- name: Verify matrix-element-call + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + matrix_element_call_root_body: "{{ matrix_element_call_root_http.stdout_lines[:-1] | join('\n') }}" + matrix_element_call_runtime: "{{ (matrix_element_call_container_inspect.stdout | from_json) | first }}" + gather_facts: false + + tasks: + # A Renovate bump changes this source of truth and therefore the image expectation. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_element_call_role_defaults + + - name: Wait for the matrix-element-call service to become active + ansible.builtin.systemd_service: + name: matrix-element-call.service + register: matrix_element_call_service + until: matrix_element_call_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes ActiveState insufficient for detecting a crash loop. + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_element_call_service.status.ActiveState == 'active' + - matrix_element_call_service.status.NRestarts is defined + - matrix_element_call_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-element-call.service is + {{ matrix_element_call_service.status.ActiveState | default('unknown') }} after + {{ matrix_element_call_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-element-call.service is active and has not restarted" + + # Probe through the private container network, matching the deployment path from Traefik. + - name: Wait for Element Call to serve its application root + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_element_call_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-element-call:8080/ + register: matrix_element_call_root_http + changed_when: false + until: "'HTTP_STATUS=200' in matrix_element_call_root_http.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the application root is real Element Call HTML + ansible.builtin.assert: + that: + - matrix_element_call_root_http.rc == 0 + - matrix_element_call_root_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_element_call_root_body | trim | length > 500 + - "'<!doctype html' in matrix_element_call_root_body | lower" + - "'element call' in matrix_element_call_root_body | lower" + fail_msg: "Element Call did not return its real application HTML over the container network" + success_msg: "Element Call serves its real application root over HTTP" + + - name: Fetch Element Call's live browser configuration + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_element_call_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}\nCONTENT_TYPE=%{content_type}" + - http://matrix-element-call:8080/config.json + register: matrix_element_call_config_http + changed_when: false + failed_when: false + + - name: Assert the live browser configuration is served as JSON + ansible.builtin.assert: + that: + - matrix_element_call_config_http.rc == 0 + - "'HTTP_STATUS=200' in matrix_element_call_config_http.stdout_lines" + - matrix_element_call_config_http.stdout | regex_search('(?m)^CONTENT_TYPE=application/json(?:;|$)') is not none + fail_msg: "Element Call did not serve its live browser configuration as JSON" + success_msg: "Element Call serves its live browser configuration as JSON" + + - name: Parse the live browser configuration + ansible.builtin.set_fact: + matrix_element_call_live_config: >- + {{ matrix_element_call_config_http.stdout | regex_replace('\nHTTP_STATUS=[0-9]+\nCONTENT_TYPE=.*$', '') | from_json }} + + - name: Assert the live configuration carries the configured homeserver and LiveKit service + ansible.builtin.assert: + that: + - matrix_element_call_live_config is mapping + - matrix_element_call_live_config.default_server_config['m.homeserver'].base_url == matrix_element_call_config_default_server_config_m_homeserver_base_url + - matrix_element_call_live_config.default_server_config['m.homeserver'].server_name == matrix_element_call_config_default_server_config_m_homeserver_server_name + - matrix_element_call_live_config.livekit.livekit_service_url == matrix_element_call_config_livekit_livekit_service_url + fail_msg: "The live config.json does not carry the non-default values rendered by the role" + success_msg: "The live config.json carries the configured homeserver and LiveKit service" + + - name: Read the configuration file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_element_call_base_path }}/config.json" + register: matrix_element_call_rendered_config_file + + - name: Assert the served and rendered structured configurations are identical + ansible.builtin.assert: + that: + - matrix_element_call_rendered_config == matrix_element_call_live_config + fail_msg: "The live configuration differs from the parsed file the role rendered" + success_msg: "The running service exposes the exact structured configuration the role rendered" + vars: + matrix_element_call_rendered_config: >- + {{ matrix_element_call_rendered_config_file.content | b64decode | from_json }} + + # Fetch a browser bundle named by the live HTML, proving the image contains the application. + - name: Extract a live Element Call JavaScript asset path + ansible.builtin.set_fact: + matrix_element_call_application_asset_path: >- + {{ matrix_element_call_root_body | regex_search('(?<=src=")[^"]+[.]js(?=")') }} + + - name: Fetch the live Element Call application asset + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_element_call_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}\nCONTENT_TYPE=%{content_type}\nSIZE=%{size_download}" + - "http://matrix-element-call:8080/{{ matrix_element_call_application_asset_path | regex_replace('^/', '') }}" + register: matrix_element_call_asset_http + changed_when: false + failed_when: false + + - name: Assert a real Element Call application asset is served + ansible.builtin.assert: + that: + - matrix_element_call_application_asset_path | length > 0 + - matrix_element_call_asset_http.rc == 0 + - "'HTTP_STATUS=200' in matrix_element_call_asset_http.stdout_lines" + - matrix_element_call_asset_http.stdout | regex_search('(?m)^CONTENT_TYPE=(?:application|text)/javascript(?:;|$)') is not none + - matrix_element_call_asset_http.stdout | regex_search('(?m)^SIZE=([1-9][0-9]{4,})$') is not none + fail_msg: "Element Call did not serve the substantial JavaScript asset referenced by its live HTML" + success_msg: "Element Call serves a substantial live application asset" + + - name: Read the labels file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_element_call_base_path }}/labels" + register: matrix_element_call_labels_file + + - name: Initialize the parsed labels + ansible.builtin.set_fact: + matrix_element_call_labels_parsed: {} + + - name: Parse the rendered labels + ansible.builtin.set_fact: + matrix_element_call_labels_parsed: >- + {{ matrix_element_call_labels_parsed | combine({item.split('=', 1)[0]: item.split('=', 1)[1]}) }} + loop: "{{ (matrix_element_call_labels_file.content | b64decode).splitlines() | reject('equalto', '') }}" + when: "'=' in item" + no_log: true + + - name: Assert the rendered labels carry the public routing contract + ansible.builtin.assert: + that: + - matrix_element_call_labels_parsed['traefik.enable'] == 'true' + - matrix_element_call_labels_parsed['traefik.docker.network'] == matrix_element_call_container_network + - matrix_element_call_labels_parsed['traefik.http.services.matrix-element-call.loadbalancer.server.port'] == '8080' + - matrix_element_call_labels_parsed['traefik.http.routers.matrix-element-call.rule'] == 'Host(`call.molecule.local`)' + - matrix_element_call_labels_parsed['traefik.http.routers.matrix-element-call.priority'] == '827' + - matrix_element_call_labels_parsed['traefik.http.routers.matrix-element-call.entrypoints'] == 'web' + - matrix_element_call_labels_parsed['traefik.http.routers.matrix-element-call.tls'] == 'false' + - matrix_element_call_labels_parsed['traefik.http.routers.matrix-element-call.middlewares'] == 'matrix-element-call-add-headers' + - matrix_element_call_labels_parsed['molecule.element-call.coverage'] == 'enabled' + fail_msg: "The parsed labels do not carry the scenario's routing contract" + success_msg: "The parsed labels carry the scenario's routing contract" + + - name: Assert the rendered labels carry the configured response headers + ansible.builtin.assert: + that: + - matrix_element_call_labels_parsed['traefik.http.middlewares.matrix-element-call-add-headers.headers.customresponseheaders.X-XSS-Protection'] == '0' + - matrix_element_call_labels_parsed['traefik.http.middlewares.matrix-element-call-add-headers.headers.customresponseheaders.X-Content-Type-Options'] == 'molecule-nosniff' + - matrix_element_call_labels_parsed['traefik.http.middlewares.matrix-element-call-add-headers.headers.customresponseheaders.Content-Security-Policy'] == 'frame-ancestors https://embed.call.molecule.local' + - matrix_element_call_labels_parsed['traefik.http.middlewares.matrix-element-call-add-headers.headers.customresponseheaders.Permission-Policy'] == 'camera=(self), microphone=(self)' + - "'traefik.http.middlewares.matrix-element-call-add-headers.headers.customresponseheaders.Strict-Transport-Security' not in matrix_element_call_labels_parsed" + fail_msg: "The parsed labels lost response headers or incorrectly enable HSTS without TLS" + success_msg: "The parsed labels carry the configured response-header contract" + + - name: Inspect the running Element Call container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-element-call + register: matrix_element_call_container_inspect + changed_when: false + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - matrix_element_call_runtime.Config.Image == matrix_element_call_expected_image + fail_msg: >- + The running container uses {{ matrix_element_call_runtime.Config.Image }}, expected + {{ matrix_element_call_expected_image }} + success_msg: "The running container uses the exact image pinned by the role" + vars: + matrix_element_call_expected_image: >- + {{ matrix_element_call_role_defaults.matrix_element_call_container_image_registry_prefix_upstream_default }}element-hq/element-call:{{ matrix_element_call_role_defaults.matrix_element_call_version }} + + - name: Assert the running container uses the playbook-supplied runtime + ansible.builtin.assert: + that: + - matrix_element_call_runtime.Config.User == (matrix_user_uid | string) ~ ':' ~ (matrix_user_gid | string) + - matrix_element_call_runtime.HostConfig.RestartPolicy.Name == 'no' + - matrix_element_call_runtime.HostConfig.AutoRemove is sameas true + - matrix_element_call_runtime.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container does not use the role's identity and Docker lifecycle contract" + success_msg: "The running container uses the role's identity and Docker lifecycle contract" + + - name: Assert the running container has the intended privilege isolation + ansible.builtin.assert: + that: + - matrix_element_call_runtime.HostConfig.Privileged is sameas false + - matrix_element_call_runtime.HostConfig.CapAdd | default([], true) | length == 0 + - matrix_element_call_runtime.HostConfig.CapDrop == ['ALL'] + fail_msg: "The running container does not have the intended privilege isolation" + success_msg: "The running container drops all capabilities and is unprivileged" + + - name: Assert the role's configuration is the sole read-only bind mount + ansible.builtin.assert: + that: + - matrix_element_call_runtime.Mounts | length == 1 + - matrix_element_call_runtime.Mounts[0].Type == 'bind' + - matrix_element_call_runtime.Mounts[0].Source == matrix_element_call_base_path ~ '/config.json' + - matrix_element_call_runtime.Mounts[0].Destination == '/app/config.json' + - matrix_element_call_runtime.Mounts[0].RW is sameas false + fail_msg: "The role-rendered config.json is not the container's sole read-only bind mount" + success_msg: "The role-rendered config.json is mounted read-only at the image's live path" + + - name: Assert the rendered and extra labels reached the running container + ansible.builtin.assert: + that: + - matrix_element_call_runtime.Config.Labels['traefik.enable'] == 'true' + - matrix_element_call_runtime.Config.Labels['traefik.docker.network'] == matrix_element_call_container_network + - matrix_element_call_runtime.Config.Labels['traefik.http.services.matrix-element-call.loadbalancer.server.port'] == '8080' + - matrix_element_call_runtime.Config.Labels['traefik.http.routers.matrix-element-call.priority'] == '827' + - matrix_element_call_runtime.Config.Labels['molecule.element-call.coverage'] == 'enabled' + - matrix_element_call_runtime.Config.Labels['molecule.element-call.extra-argument'] == 'reached' + fail_msg: "The running container does not carry the labels the role rendered and passed" + success_msg: "The configured labels reached the running container" + + - name: Assert the running container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_element_call_runtime.HostConfig.NetworkMode == matrix_element_call_container_network + - matrix_element_call_runtime.NetworkSettings.Networks is mapping + - matrix_element_call_runtime.NetworkSettings.Networks | length == 1 + - matrix_element_call_container_network in matrix_element_call_runtime.NetworkSettings.Networks + fail_msg: >- + Element Call has unexpected network attachments: + {{ matrix_element_call_runtime.NetworkSettings.Networks.keys() | list }} + success_msg: "The running container is attached only to its dedicated network" + + - name: Assert the observable extra runtime argument reached Docker + ansible.builtin.assert: + that: + - matrix_element_call_runtime.Config.Hostname == 'element-call-molecule-runtime' + fail_msg: "The configured container hostname extra argument did not reach Docker" + success_msg: "The configured container extra argument reached Docker" + + - name: Ask Docker for Element Call's published ports + ansible.builtin.command: + argv: + - docker + - container + - port + - matrix-element-call + register: matrix_element_call_published_ports + changed_when: false + failed_when: false + + - name: Assert the role publishes no host ports + ansible.builtin.assert: + that: + - matrix_element_call_runtime.HostConfig.PortBindings | default({}, true) | length == 0 + - matrix_element_call_published_ports.rc == 0 + - matrix_element_call_published_ports.stdout | trim | length == 0 + fail_msg: >- + Element Call unexpectedly publishes a host port: + {{ matrix_element_call_published_ports.stdout | default('unknown') }} + success_msg: "The role leaves Element Call's HTTP port unpublished" diff --git a/roles/custom/matrix-element-call/tasks/install.yml b/roles/custom/matrix-element-call/tasks/install.yml index 4cd587e35..53bb51aec 100644 --- a/roles/custom/matrix-element-call/tasks/install.yml +++ b/roles/custom/matrix-element-call/tasks/install.yml @@ -35,16 +35,16 @@ register: matrix_element_call_support_files_result - name: Ensure Element Call container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_element_call_container_image }}" - source: pull - force_source: "{{ matrix_element_call_container_image_force_pull }}" + pull: always register: matrix_element_call_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_element_call_container_image_pull_result is not failed - name: Ensure Element Call container network is created + when: matrix_element_call_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_element_call_container_network }}" diff --git a/roles/custom/matrix-element-call/tasks/validate_config.yml b/roles/custom/matrix-element-call/tasks/validate_config.yml index dec4027dd..cd1245883 100644 --- a/roles/custom/matrix-element-call/tasks/validate_config.yml +++ b/roles/custom/matrix-element-call/tasks/validate_config.yml @@ -32,3 +32,11 @@ Element Call with a path prefix other than '/' is not supported yet. You have configured matrix_element_call_path_prefix to '{{ matrix_element_call_path_prefix }}'. when: "matrix_element_call_path_prefix != '/'" + +- name: (Deprecation) Catch and report renamed Element Call variables + ansible.builtin.fail: + msg: >- + The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_element_call_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-element-call/templates/systemd/matrix-element-call.service.j2 b/roles/custom/matrix-element-call/templates/systemd/matrix-element-call.service.j2 index fbfe3b446..13794f7bb 100644 --- a/roles/custom/matrix-element-call/templates/systemd/matrix-element-call.service.j2 +++ b/roles/custom/matrix-element-call/templates/systemd/matrix-element-call.service.j2 @@ -30,9 +30,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_element_call_container_image }} +{% if matrix_element_call_container_network != 'host' %} {% for network in matrix_element_call_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-element-call {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-element-call diff --git a/roles/custom/matrix-ketesa/defaults/main.yml b/roles/custom/matrix-ketesa/defaults/main.yml new file mode 100644 index 000000000..354ddf739 --- /dev/null +++ b/roles/custom/matrix-ketesa/defaults/main.yml @@ -0,0 +1,265 @@ +# SPDX-FileCopyrightText: 2020 - 2021 Aaron Raimist +# SPDX-FileCopyrightText: 2020 - 2025 Slavi Pantaleev +# SPDX-FileCopyrightText: 2020 Dennis Ciba +# SPDX-FileCopyrightText: 2021 - 2025 MDAD project contributors +# SPDX-FileCopyrightText: 2021 Ahmad Haghighi +# SPDX-FileCopyrightText: 2022 - 2026 Nikita Chernyi +# SPDX-FileCopyrightText: 2022 Marko Weltzer +# SPDX-FileCopyrightText: 2023 Samuel Meenzen +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# matrix-ketesa is Ketesa — a fully-featured, mobile-friendly admin interface for Matrix homeservers powered by Synapse. +# Project source code URL: https://github.com/etkecc/ketesa + +matrix_ketesa_enabled: true + +# A path on host where all related files will be saved +matrix_ketesa_base_path: "{{ matrix_base_data_path }}/ketesa" +matrix_ketesa_config_path: "{{ matrix_ketesa_base_path }}/config" +matrix_ketesa_container_src_files_path: "{{ matrix_ketesa_base_path }}/docker-src" + +matrix_ketesa_container_uid: '' +matrix_ketesa_container_gid: '' + +matrix_ketesa_container_image_self_build: false +matrix_ketesa_container_image_self_build_repo: "https://github.com/etkecc/ketesa.git" + +# renovate: datasource=docker depName=ghcr.io/etkecc/ketesa +matrix_ketesa_version: v1.5.0 +matrix_ketesa_container_image: "{{ matrix_ketesa_container_image_registry_prefix }}etkecc/ketesa:{{ matrix_ketesa_version }}" +matrix_ketesa_container_image_registry_prefix: "{{ 'localhost/' if matrix_ketesa_container_image_self_build else matrix_ketesa_container_image_registry_prefix_upstream }}" +matrix_ketesa_container_image_registry_prefix_upstream: "{{ matrix_ketesa_container_image_registry_prefix_upstream_default }}" +matrix_ketesa_container_image_registry_prefix_upstream_default: "ghcr.io/" + +# The base container network +matrix_ketesa_container_network: matrix-ketesa + +# A list of additional container networks that the container would be connected to. +# The role does not create these networks, so make sure they already exist. +# Use this to expose this container to a reverse proxy, which runs in a different container network. +matrix_ketesa_container_additional_networks: [] + +# Controls whether the matrix-ketesa container exposes its HTTP port (tcp/8080 in the container). +# +# Takes an "<ip>:<port>" or "<port>" value (e.g. "127.0.0.1:8766"), or empty string to not expose. +matrix_ketesa_container_http_host_bind_port: '' + +# A list of extra arguments to pass to the container +matrix_ketesa_container_extra_arguments: [] + +# matrix_ketesa_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# See `../templates/labels.j2` for details. +# +# To inject your own other container labels, see `matrix_ketesa_container_labels_additional_labels`. +matrix_ketesa_container_labels_traefik_enabled: true +matrix_ketesa_container_labels_traefik_docker_network: "{{ matrix_ketesa_container_network }}" +matrix_ketesa_container_labels_traefik_hostname: "{{ matrix_ketesa_hostname }}" +# The path prefix must either be `/` or not end with a slash (e.g. `/ketesa`). +matrix_ketesa_container_labels_traefik_path_prefix: "{{ matrix_ketesa_path_prefix }}" +matrix_ketesa_container_labels_traefik_rule: "Host(`{{ matrix_ketesa_container_labels_traefik_hostname }}`){% if matrix_ketesa_container_labels_traefik_path_prefix != '/' %} && PathPrefix(`{{ matrix_ketesa_container_labels_traefik_path_prefix }}`){% endif %}" +matrix_ketesa_container_labels_traefik_priority: 0 +matrix_ketesa_container_labels_traefik_entrypoints: web-secure +matrix_ketesa_container_labels_traefik_tls: "{{ matrix_ketesa_container_labels_traefik_entrypoints != 'web' }}" +matrix_ketesa_container_labels_traefik_tls_certResolver: default # noqa var-naming +# This setting is to define a list of IP addresses to allow access to Ketesa. +# Each IP address should be in CIDR format, e.g. xxx.xxx.xxx.xxx/xx. +# For more information, see: https://doc.traefik.io/traefik/middlewares/http/ipallowlist/ +# If the list is empty, all IP addresses are allowed. +matrix_ketesa_container_labels_traefik_ipallowlist_sourcerange: [] + +# Controls which additional headers to attach to all HTTP responses. +# To add your own headers, use `matrix_ketesa_container_labels_traefik_additional_response_headers_custom` +matrix_ketesa_container_labels_traefik_additional_response_headers: "{{ matrix_ketesa_container_labels_traefik_additional_response_headers_auto | combine(matrix_ketesa_container_labels_traefik_additional_response_headers_custom) }}" +matrix_ketesa_container_labels_traefik_additional_response_headers_auto: | + {{ + {} + | combine ({'X-XSS-Protection': matrix_ketesa_http_header_xss_protection} if matrix_ketesa_http_header_xss_protection else {}) + | combine ({'X-Content-Type-Options': matrix_ketesa_http_header_content_type_options} if matrix_ketesa_http_header_content_type_options else {}) + | combine ({'Content-Security-Policy': matrix_ketesa_http_header_content_security_policy} if matrix_ketesa_http_header_content_security_policy else {}) + | combine ({'Permission-Policy': matrix_ketesa_http_header_content_permission_policy} if matrix_ketesa_http_header_content_permission_policy else {}) + | combine ({'Strict-Transport-Security': matrix_ketesa_http_header_strict_transport_security} if matrix_ketesa_http_header_strict_transport_security and matrix_ketesa_container_labels_traefik_tls else {}) + }} +matrix_ketesa_container_labels_traefik_additional_response_headers_custom: {} + +# matrix_ketesa_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. +# See `../templates/labels.j2` for details. +# +# Example: +# matrix_ketesa_container_labels_additional_labels: | +# my.label=1 +# another.label="here" +matrix_ketesa_container_labels_additional_labels: '' + +# List of systemd services that matrix-ketesa.service depends on +matrix_ketesa_systemd_required_services_list: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" + +# List of systemd services that matrix-ketesa.service wants +matrix_ketesa_systemd_wanted_services_list: [] + +# Specifies the value of the `X-XSS-Protection` header +# Stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. +# +# Learn more about it is here: +# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection +# - https://portswigger.net/web-security/cross-site-scripting/reflected +matrix_ketesa_http_header_xss_protection: "1; mode=block" + +# Specifies the value of the `X-Content-Type-Options` header. +# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options +matrix_ketesa_http_header_content_type_options: nosniff + +# Specifies the value of the `Content-Security-Policy` header. +# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy +matrix_ketesa_http_header_content_security_policy: frame-ancestors 'self' + +# Specifies the value of the `Permission-Policy` header. +# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permission-Policy +matrix_ketesa_http_header_content_permission_policy: "{{ 'interest-cohort=()' if matrix_ketesa_floc_optout_enabled else '' }}" + +# Specifies the value of the `Strict-Transport-Security` header. +# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security +matrix_ketesa_http_header_strict_transport_security: "max-age=31536000; includeSubDomains{{ '; preload' if matrix_ketesa_hsts_preload_enabled else '' }}" + +# Controls whether to send a "Permissions-Policy interest-cohort=();" header along with all responses +# +# Learn more about what it is here: +# - https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea +# - https://paramdeo.com/blog/opting-your-website-out-of-googles-floc-network +# - https://amifloced.org/ +# +# Of course, a better solution is to just stop using browsers (like Chrome), which participate in such tracking practices. +# See: `matrix_ketesa_content_permission_policy` +matrix_ketesa_floc_optout_enabled: true + +# Controls if HSTS preloading is enabled +# +# In its strongest and recommended form, the [HSTS policy](https://www.chromium.org/hsts) includes all subdomains, and +# indicates a willingness to be "preloaded" into browsers: +# `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload` +# For more information visit: +# - https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security +# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security +# - https://hstspreload.org/#opt-in +# See: `matrix_ketesa_http_header_strict_transport_security` +matrix_ketesa_hsts_preload_enabled: false + +# The hostname at which Ketesa is served. +matrix_ketesa_hostname: "{{ matrix_server_fqn_matrix }}" + +# The path at which Ketesa is exposed. +# This value must either be `/` or not end with a slash (e.g. `/ketesa`). +matrix_ketesa_path_prefix: /synapse-admin + +# Default Ketesa configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_ketesa_configuration_extension_json`) +# or completely replace this variable with your own template. +# +# The side-effect of this lookup is that Ansible would even parse the JSON for us, returning a dict. +# This is unlike what it does when looking up YAML template files (no automatic parsing there). +matrix_ketesa_configuration_default: + restrictBaseUrl: "{{ matrix_ketesa_config_restrictBaseUrl }}" + externalAuthProvider: "{{ matrix_ketesa_config_externalAuthProvider }}" + wellKnownDiscovery: "{{ matrix_ketesa_config_wellKnownDiscovery }}" + corsCredentials: "{{ matrix_ketesa_config_corsCredentials }}" + asManagedUsers: "{{ matrix_ketesa_config_asManagedUsers }}" + menu: "{{ matrix_ketesa_config_menu }}" + +# Your custom JSON configuration for Ketesa should go to `matrix_ketesa_configuration_extension_json`. +# This configuration extends the default starting configuration (`matrix_ketesa_configuration_default`). +# +# You can override individual variables from the default configuration, or introduce new ones. +# +# If you need something more special, you can take full control by +# completely redefining `matrix_ketesa_configuration_default`. +# +# Example configuration extension follows: +# +# matrix_ketesa_configuration_extension_json: | +# { +# "some_setting": true, +# "another_setting": false +# } +matrix_ketesa_configuration_extension_json: '{}' + +# This is similar to `matrix_ketesa_configuration_extension_json`, but intended for use by playbook or group vars +matrix_ketesa_configuration_extension_json_auto: '{}' + +matrix_ketesa_configuration_extension: "{{ matrix_ketesa_configuration_extension_json_auto | from_json | combine(matrix_ketesa_configuration_extension_json | from_json if matrix_ketesa_configuration_extension_json | from_json is mapping else {}, recursive=True) }}" + +# Holds the final Ketesa configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_ketesa_configuration_default`. +matrix_ketesa_configuration: "{{ matrix_ketesa_configuration_default | combine(matrix_ketesa_configuration_extension, recursive=True) }}" + +# Controls the restrictBaseUrl configuration setting, which, if defined, +# restricts the homeserver(s), so that the user can no longer define a homeserver manually during login. +matrix_ketesa_config_restrictBaseUrl: "{{ matrix_homeserver_url }}" # noqa var-naming + +# Controls the externalAuthProvider configuration setting, which, if defined, +# enables a special compatibility mode that works better for external auth providers like LDAP, MAS, etc. +matrix_ketesa_config_externalAuthProvider: false # noqa var-naming + +# Control automatic URL canonicalization via /.well-known/matrix/client +# Default: true (discovery enabled, per Matrix spec). +# Set to false when the /_synapse/admin API is hosted on a separate domain not advertised in well-known (e.g. a VPN-only admin endpoint). +# When disabled, MXID-based URL auto-fill uses the domain portion of the MXID directly without a well-known lookup. +matrix_ketesa_config_wellKnownDiscovery: true # noqa var-naming + +# Controls the corsCredentials configuration setting, which, if defined, +# allows including credentials (cookies, authorization headers, or TLS client certificates) in requests +# ref: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#including_credentials +matrix_ketesa_config_corsCredentials: "same-origin" # noqa var-naming + +# Controls the menu configuration setting, which, if defined, adds new menu items to the Ketesa UI. +# The format is a list of objects, where each object has the following keys: +# - `label` (string, required): The label of the menu item. +# - `i18n` (dict, optional): Dictionary of translations for the label. The keys should be BCP 47 language tags (e.g., en, fr, de) supported by Ketesa (see src/i18n). +# - `icon` (string, optional): The icon of the menu item, one of the https://github.com/etkecc/ketesa/blob/main/src/components/icons.ts +# - `url` (string, required): The URL of the menu item. +# Example: +# [ +# { +# "label": "Contact support", +# "i18n": { +# "de": "Support kontaktieren", +# "fr": "Contacter le support", +# "zh": "联系支持" +# }, +# "icon": "SupportAgent", +# "url": "https://github.com/etkecc/ketesa/issues" +# } +# ] +matrix_ketesa_config_menu: [] + +# Controls the asManagedUsers configuration setting (managed by playbook), which, if defined, +# restricts modifications of the specified users (e.g., bridge-managed). +# You should use JS regex syntax to match the user IDs. +# Example for mautrix-telegram: ["^@telegram_[a-zA-Z0-9]+:example\\.com$"] +# WARNING: you want to use matrix_ketesa_config_asManagedUsers_custom instead of this variable. +matrix_ketesa_config_asManagedUsers_auto: [] # noqa var-naming + +# Controls the asManagedUsers configuration setting (managed per host), which, if defined, +# restricts modifications of the specified users (e.g., bridge-managed). +# You should use JS regex syntax to match the user IDs. +# Example for mautrix-telegram: ["^@telegram_[a-zA-Z0-9]+:example\\.com$"] +matrix_ketesa_config_asManagedUsers_custom: [] # noqa var-naming + +# Controls the asManagedUsers configuration setting, which, if defined, +# restricts modifications of the specified users (e.g., bridge-managed). +# You should use JS regex syntax to match the user IDs. +# Example for mautrix-telegram: ["^@telegram_[a-zA-Z0-9]+:example\\.com$"] +# WARNING: you want to use matrix_ketesa_config_asManagedUsers_custom instead of this variable. +matrix_ketesa_config_asManagedUsers: "{{ matrix_ketesa_config_asManagedUsers_auto + matrix_ketesa_config_asManagedUsers_custom }}" # noqa var-naming + +# matrix_ketesa_restart_necessary controls whether the service +# will be restarted (when true) or merely started (when false) by the +# systemd service manager role (when conditional restart is enabled). +# +# This value is automatically computed during installation based on whether +# any configuration files, the systemd service file, or the container image changed. +# The default of `false` means "no restart needed" — appropriate when the role's +# installation tasks haven't run (e.g., due to --tags skipping them). +matrix_ketesa_restart_necessary: false diff --git a/roles/custom/matrix-ketesa/molecule/default/converge.yml b/roles/custom/matrix-ketesa/molecule/default/converge.yml new file mode 100644 index 000000000..88359df21 --- /dev/null +++ b/roles/custom/matrix-ketesa/molecule/default/converge.yml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-ketesa Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-ketesa Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +# The component role installs the unit; the full playbook's systemd service manager starts +# it. Keep that boundary explicit here rather than pulling the manager role into the test. +- name: Ensure matrix-ketesa is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the matrix-ketesa systemd service is started + ansible.builtin.systemd_service: + name: matrix-ketesa.service + state: started diff --git a/roles/custom/matrix-ketesa/molecule/default/molecule.yml b/roles/custom/matrix-ketesa/molecule/default/molecule.yml new file mode 100644 index 000000000..81d267543 --- /dev/null +++ b/roles/custom/matrix-ketesa/molecule/default/molecule.yml @@ -0,0 +1,97 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-ketesa-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + # Ketesa is a Synapse administration client. The complete playbook supplies this + # selection before the role runs; a role-scoped scenario must do so directly. + matrix_homeserver_implementation: synapse + + # verify.yml is a separate play where the role's defaults are out of scope, so + # paths which it reads are pinned to the values the role derives during converge. + matrix_ketesa_base_path: /matrix/ketesa + matrix_ketesa_config_path: /matrix/ketesa/config + + # Use a scenario-specific network and a container identity unlike both the matrix + # user and the image defaults, so the runtime assertions cannot pass by coincidence. + matrix_ketesa_container_network: matrix-ketesa-molecule + matrix_ketesa_container_uid: 28080 + matrix_ketesa_container_gid: 28081 + matrix_ketesa_container_http_host_bind_port: '' + + # These values differ from both Ketesa and role defaults. No Synapse is expected at + # this URL: the static client only publishes it to the browser in config.json. + matrix_ketesa_config_restrictBaseUrl: https://admin-api.molecule.local # noqa var-naming + matrix_ketesa_config_externalAuthProvider: true # noqa var-naming + matrix_ketesa_config_wellKnownDiscovery: false # noqa var-naming + matrix_ketesa_config_corsCredentials: include # noqa var-naming + matrix_ketesa_config_asManagedUsers_custom: # noqa var-naming + # Molecule applies shell-style interpolation to this file, so `$$` becomes the + # single end-of-string anchor which reaches Ansible and the rendered JSON. + - '^@molecule_bridge_[a-z0-9]+:molecule\.local$$' + matrix_ketesa_config_menu: + - label: Molecule support + i18n: + de: Molekül-Support + fr: Assistance Molécule + icon: SupportAgent + url: https://support.molecule.local/ketesa + + # Traefik itself is not needed. The deliberately non-default exposure values make + # the label file a precise record of the public wiring the role would deploy. + matrix_ketesa_hostname: ketesa-admin.molecule.local + matrix_ketesa_path_prefix: /molecule-ketesa + matrix_ketesa_container_labels_traefik_enabled: true + matrix_ketesa_container_labels_traefik_docker_network: matrix-ketesa-molecule + matrix_ketesa_container_labels_traefik_priority: 731 + matrix_ketesa_container_labels_traefik_entrypoints: web + matrix_ketesa_container_labels_traefik_tls: false + matrix_ketesa_container_labels_traefik_ipallowlist_sourcerange: + - 192.0.2.0/24 + - 2001:db8::/32 + matrix_ketesa_container_labels_traefik_additional_response_headers_custom: + X-Molecule-Ketesa: role-scenario + matrix_ketesa_container_labels_additional_labels: | + molecule.ketesa.coverage=enabled + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-ketesa/molecule/default/prepare.yml b/roles/custom/matrix-ketesa/molecule/default/prepare.yml new file mode 100644 index 000000000..313f8a1eb --- /dev/null +++ b/roles/custom/matrix-ketesa/molecule/default/prepare.yml @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-ketesa Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks set owner/group by name. matrix-base creates these in a full + # playbook run; the role-scoped scenario provides only that necessary side effect. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" diff --git a/roles/custom/matrix-ketesa/molecule/default/requirements.yml b/roles/custom/matrix-ketesa/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-ketesa/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-ketesa/molecule/default/verify.yml b/roles/custom/matrix-ketesa/molecule/default/verify.yml new file mode 100644 index 000000000..4ee43577b --- /dev/null +++ b/roles/custom/matrix-ketesa/molecule/default/verify.yml @@ -0,0 +1,249 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Ketesa is a static client. The weight-bearing checks are its real HTTP root and the +# config.json served from the bind mount; no live Synapse or credentials are involved. +- name: Verify matrix-ketesa + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + matrix_ketesa_rendered_config: "{{ matrix_ketesa_config_file.content | b64decode | from_json }}" + matrix_ketesa_root_body: "{{ matrix_ketesa_root_http.stdout_lines[:-1] | join('\n') }}" + matrix_ketesa_served_config_body: "{{ matrix_ketesa_config_http.stdout_lines[:-1] | join('\n') }}" + matrix_ketesa_served_config: "{{ matrix_ketesa_served_config_body | from_json }}" + matrix_ketesa_labels_lines: "{{ (matrix_ketesa_labels_file.content | b64decode).splitlines() }}" + matrix_ketesa_runtime: "{{ (matrix_ketesa_container_inspect.stdout | from_json) | first }}" + matrix_ketesa_config_mounts: "{{ matrix_ketesa_runtime.Mounts | selectattr('Destination', 'equalto', '/var/public/config.json') | list }}" + gather_facts: false + + tasks: + # Read the pin from the role rather than defining it in the scenario, so an image bump + # changes the expected value and tests the image that the role actually ships. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_ketesa_role_defaults + + - name: Wait for the matrix-ketesa service to become active + ansible.builtin.systemd_service: + name: matrix-ketesa.service + register: matrix_ketesa_service + until: matrix_ketesa_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always makes ActiveState alone insufficient: a container can crash-loop while + # systemd continues to report its unit as active. + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_ketesa_service.status.ActiveState == 'active' + - matrix_ketesa_service.status.NRestarts is defined + - matrix_ketesa_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-ketesa.service is + {{ matrix_ketesa_service.status.ActiveState | default('unknown') }} after + {{ matrix_ketesa_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-ketesa.service is active and has not restarted" + + - name: Read the configuration file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_ketesa_config_path }}/config.json" + register: matrix_ketesa_config_file + + - name: Assert the rendered JSON carries the scenario's Ketesa configuration + ansible.builtin.assert: + that: + - matrix_ketesa_rendered_config.keys() | sort == ['asManagedUsers', 'corsCredentials', 'externalAuthProvider', 'menu', 'restrictBaseUrl', 'wellKnownDiscovery'] | sort + - matrix_ketesa_rendered_config.restrictBaseUrl == matrix_ketesa_config_restrictBaseUrl + - matrix_ketesa_rendered_config.externalAuthProvider is sameas true + - matrix_ketesa_rendered_config.wellKnownDiscovery is sameas false + - matrix_ketesa_rendered_config.corsCredentials == matrix_ketesa_config_corsCredentials + - matrix_ketesa_rendered_config.asManagedUsers == matrix_ketesa_config_asManagedUsers_custom + - matrix_ketesa_rendered_config.menu | length == 1 + - matrix_ketesa_rendered_config.menu[0].label == 'Molecule support' + - matrix_ketesa_rendered_config.menu[0].i18n.de == 'Molekül-Support' + - matrix_ketesa_rendered_config.menu[0].i18n.fr == 'Assistance Molécule' + - matrix_ketesa_rendered_config.menu[0].icon == 'SupportAgent' + - matrix_ketesa_rendered_config.menu[0].url == 'https://support.molecule.local/ketesa' + fail_msg: "The rendered JSON does not carry the scenario's non-default Ketesa settings" + success_msg: "The rendered JSON carries the scenario's non-default Ketesa settings" + + # Probe over the role's own network. Publishing a test-only host port would diverge from + # the deployment path and would collide when scenarios run concurrently. + - name: Wait for Ketesa to serve its application root + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_ketesa_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-ketesa:8080/ + register: matrix_ketesa_root_http + changed_when: false + until: "'HTTP_STATUS=200' in matrix_ketesa_root_http.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the application root is real Ketesa HTML + ansible.builtin.assert: + that: + - matrix_ketesa_root_http.rc == 0 + - matrix_ketesa_root_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_ketesa_root_body | trim | length > 100 + - "'<!doctype html' in matrix_ketesa_root_body | lower" + - "'ketesa' in matrix_ketesa_root_body | lower" + fail_msg: >- + Ketesa did not return its application HTML from the container network + (rc={{ matrix_ketesa_root_http.rc }}, status={{ matrix_ketesa_root_http.stdout_lines[-1] | default('missing') }}) + success_msg: "Ketesa serves its application root over HTTP" + + - name: Fetch the config.json that Ketesa serves + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_ketesa_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-ketesa:8080/config.json + register: matrix_ketesa_config_http + changed_when: false + until: "'HTTP_STATUS=200' in matrix_ketesa_config_http.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert Ketesa serves the parsed JSON that the role rendered + ansible.builtin.assert: + that: + - matrix_ketesa_config_http.rc == 0 + - matrix_ketesa_config_http.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_ketesa_served_config is mapping + - matrix_ketesa_served_config == matrix_ketesa_rendered_config + fail_msg: "The config.json served by Ketesa does not match the role's rendered JSON" + success_msg: "Ketesa serves the exact parsed JSON that the role rendered" + + - name: Read the labels the role rendered + ansible.builtin.slurp: + src: "{{ matrix_ketesa_base_path }}/labels" + register: matrix_ketesa_labels_file + + - name: Assert the labels carry the configured public exposure + ansible.builtin.assert: + that: + - "'traefik.enable=true' in matrix_ketesa_labels_lines" + - "'traefik.docker.network=matrix-ketesa-molecule' in matrix_ketesa_labels_lines" + - "'traefik.http.services.matrix-ketesa.loadbalancer.server.port=8080' in matrix_ketesa_labels_lines" + - "'traefik.http.middlewares.matrix-ketesa-ipallowlist.ipallowlist.sourcerange=192.0.2.0/24,2001:db8::/32' in matrix_ketesa_labels_lines" + - "'traefik.http.middlewares.matrix-ketesa-strip-prefix.stripprefix.prefixes=/molecule-ketesa' in matrix_ketesa_labels_lines" + - "'traefik.http.middlewares.matrix-ketesa-add-headers.headers.customresponseheaders.X-Molecule-Ketesa=role-scenario' in matrix_ketesa_labels_lines" + - "'traefik.http.routers.matrix-ketesa.rule=Host(`ketesa-admin.molecule.local`) && PathPrefix(`/molecule-ketesa`)' in matrix_ketesa_labels_lines" + - "'traefik.http.routers.matrix-ketesa.priority=731' in matrix_ketesa_labels_lines" + - "'traefik.http.routers.matrix-ketesa.middlewares=matrix-ketesa-ipallowlist,matrix-ketesa-slashless-redirect,matrix-ketesa-strip-prefix,matrix-ketesa-add-headers' in matrix_ketesa_labels_lines" + - "'traefik.http.routers.matrix-ketesa.entrypoints=web' in matrix_ketesa_labels_lines" + - "'traefik.http.routers.matrix-ketesa.tls=false' in matrix_ketesa_labels_lines" + - "'molecule.ketesa.coverage=enabled' in matrix_ketesa_labels_lines" + fail_msg: "The role's label file does not carry the scenario's exposure settings" + success_msg: "The role's label file carries the scenario's exposure settings" + + - name: Inspect the running Ketesa container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-ketesa + register: matrix_ketesa_container_inspect + changed_when: false + + - name: Assert the running container uses the exact image pinned by the role + ansible.builtin.assert: + that: + - matrix_ketesa_runtime.Config.Image == 'ghcr.io/etkecc/ketesa:' + matrix_ketesa_role_defaults.matrix_ketesa_version + fail_msg: >- + The running image {{ matrix_ketesa_runtime.Config.Image }} is not the exact + ghcr.io/etkecc/ketesa:{{ matrix_ketesa_role_defaults.matrix_ketesa_version }} pin + success_msg: "The running container uses the exact image pinned by the role" + + - name: Assert the running container uses the dedicated Ketesa identity + ansible.builtin.assert: + that: + - matrix_ketesa_runtime.Config.User.split(':')[0] == matrix_ketesa_container_uid | string + - matrix_ketesa_runtime.Config.User.split(':')[1] == matrix_ketesa_container_gid | string + fail_msg: >- + The running container uses {{ matrix_ketesa_runtime.Config.User }} instead of + {{ matrix_ketesa_container_uid }}:{{ matrix_ketesa_container_gid }} + success_msg: "The running container uses the dedicated Ketesa UID and GID" + + - name: Assert the container root filesystem is read-only + ansible.builtin.assert: + that: + - matrix_ketesa_runtime.HostConfig.ReadonlyRootfs is sameas true + fail_msg: "The Ketesa container root filesystem is writable" + success_msg: "The Ketesa container root filesystem is read-only" + + - name: Assert the configuration bind mount is read-only + ansible.builtin.assert: + that: + - matrix_ketesa_config_mounts | length == 1 + - matrix_ketesa_config_mounts[0].RW is sameas false + fail_msg: "The Ketesa configuration bind mount is missing or writable" + success_msg: "The Ketesa configuration bind mount is present and read-only" + + - name: Assert the container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_ketesa_runtime.NetworkSettings.Networks is mapping + - matrix_ketesa_runtime.NetworkSettings.Networks | length == 1 + - matrix_ketesa_container_network in matrix_ketesa_runtime.NetworkSettings.Networks + fail_msg: >- + Ketesa has unexpected network attachments: + {{ matrix_ketesa_runtime.NetworkSettings.Networks.keys() | list }} + success_msg: "The container is attached only to its dedicated network" + + - name: Ask Docker for Ketesa's published ports + ansible.builtin.command: + argv: + - docker + - container + - port + - matrix-ketesa + register: matrix_ketesa_published_ports + changed_when: false + failed_when: false + + - name: Assert the role did not publish a host port + ansible.builtin.assert: + that: + - matrix_ketesa_runtime.HostConfig.PortBindings | default({}, true) | length == 0 + - matrix_ketesa_published_ports.rc == 0 + - matrix_ketesa_published_ports.stdout | trim | length == 0 + fail_msg: >- + Ketesa unexpectedly publishes a host port: + {{ matrix_ketesa_published_ports.stdout | default('unknown') }} + success_msg: "The role leaves Ketesa's HTTP port unpublished" + + - name: Assert Docker accepted the role's custom label + ansible.builtin.assert: + that: + - matrix_ketesa_runtime.Config.Labels is mapping + - matrix_ketesa_runtime.Config.Labels['molecule.ketesa.coverage'] == 'enabled' + fail_msg: "Docker did not attach the custom label from the role's label file" + success_msg: "Docker accepted the custom label from the role's label file" diff --git a/roles/custom/matrix-synapse-admin/tasks/main.yml b/roles/custom/matrix-ketesa/tasks/main.yml similarity index 67% rename from roles/custom/matrix-synapse-admin/tasks/main.yml rename to roles/custom/matrix-ketesa/tasks/main.yml index c66e9998e..d7b40c124 100644 --- a/roles/custom/matrix-synapse-admin/tasks/main.yml +++ b/roles/custom/matrix-ketesa/tasks/main.yml @@ -1,5 +1,6 @@ # SPDX-FileCopyrightText: 2020 - 2024 Slavi Pantaleev # SPDX-FileCopyrightText: 2022 Marko Weltzer +# SPDX-FileCopyrightText: 2026 Nikita Chernyi # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -7,19 +8,19 @@ - tags: - setup-all - - setup-synapse-admin + - setup-ketesa - install-all - - install-synapse-admin + - install-ketesa block: - - when: matrix_synapse_admin_enabled | bool + - when: matrix_ketesa_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - when: matrix_synapse_admin_enabled | bool + - when: matrix_ketesa_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - tags: - setup-all - - setup-synapse-admin + - setup-ketesa block: - - when: not matrix_synapse_admin_enabled | bool + - when: not matrix_ketesa_enabled | bool ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-ketesa/tasks/setup_install.yml b/roles/custom/matrix-ketesa/tasks/setup_install.yml new file mode 100644 index 000000000..d0bec5633 --- /dev/null +++ b/roles/custom/matrix-ketesa/tasks/setup_install.yml @@ -0,0 +1,138 @@ +# SPDX-FileCopyrightText: 2020 - 2024 Slavi Pantaleev +# SPDX-FileCopyrightText: 2020 Dennis Ciba +# SPDX-FileCopyrightText: 2021 Aaron Raimist +# SPDX-FileCopyrightText: 2022 MDAD project contributors +# SPDX-FileCopyrightText: 2022 Marko Weltzer +# SPDX-FileCopyrightText: 2022 - 2026 Nikita Chernyi +# SPDX-FileCopyrightText: 2022 Sebastian Gumprich +# SPDX-FileCopyrightText: 2024 David Mehren +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# Migrate from the old matrix-synapse-admin role. +# The service was renamed to matrix-ketesa. Stop and remove the old one. + +- name: Check if matrix-synapse-admin.service exists + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-synapse-admin.service" + register: matrix_ketesa_legacy_synapse_admin_service_stat + +- name: Stop and remove legacy matrix-synapse-admin systemd service + when: matrix_ketesa_legacy_synapse_admin_service_stat.stat.exists | bool + block: + - name: Ensure legacy matrix-synapse-admin service is stopped + ansible.builtin.service: + name: matrix-synapse-admin + state: stopped + enabled: false + failed_when: false + + - name: Remove legacy matrix-synapse-admin service file + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-synapse-admin.service" + state: absent + + - name: Remove legacy matrix-synapse-admin data directory + ansible.builtin.file: + path: "{{ matrix_base_data_path }}/synapse-admin" + state: absent + +- name: Ensure matrix-ketesa paths exists + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + mode: '0750' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - {path: "{{ matrix_ketesa_base_path }}", when: true} + - {path: "{{ matrix_ketesa_config_path }}", when: true} + - {path: "{{ matrix_ketesa_container_src_files_path }}", when: "{{ matrix_ketesa_container_image_self_build }}"} + when: "item.when | bool" + +- name: Ensure matrix-ketesa labels file is created + ansible.builtin.template: + src: "{{ role_path }}/templates/labels.j2" + dest: "{{ matrix_ketesa_base_path }}/labels" + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: '0640' + register: matrix_ketesa_support_files_result + +- name: Ensure matrix-ketesa configuration installed + ansible.builtin.copy: + content: "{{ matrix_ketesa_configuration | to_nice_json }}" + dest: "{{ matrix_ketesa_config_path }}/config.json" + mode: '0644' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_ketesa_config_result + +- name: Ensure matrix-ketesa image is pulled + community.docker.docker_image_pull: + name: "{{ matrix_ketesa_container_image }}" + pull: always + when: not matrix_ketesa_container_image_self_build | bool + register: matrix_ketesa_container_image_pull_result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: matrix_ketesa_container_image_pull_result is not failed + +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure matrix-ketesa repository ownership is correct when self-building + ansible.builtin.file: + path: "{{ matrix_ketesa_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: matrix_ketesa_container_image_self_build | bool + +- name: Ensure matrix-ketesa repository is present when self-building + ansible.builtin.git: + repo: "{{ matrix_ketesa_container_image_self_build_repo }}" + dest: "{{ matrix_ketesa_container_src_files_path }}" + version: "{{ matrix_ketesa_container_image.split(':')[1] }}" + force: "yes" + become: true + become_user: "{{ matrix_user_name }}" + register: matrix_ketesa_git_pull_results + when: matrix_ketesa_container_image_self_build | bool + +- name: Ensure matrix-ketesa Docker image is built + community.docker.docker_image_build: + name: "{{ matrix_ketesa_container_image }}" + dockerfile: Dockerfile + path: "{{ matrix_ketesa_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_ketesa_git_pull_results.changed | bool else 'never' }}" + when: matrix_ketesa_container_image_self_build | bool + register: matrix_ketesa_container_image_build_result + +- name: Ensure matrix-ketesa container network is created + when: matrix_ketesa_container_network != 'host' + community.general.docker_network: + enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" + name: "{{ matrix_ketesa_container_network }}" + driver: bridge + driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" + +- name: Ensure matrix-ketesa.service installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-ketesa.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-ketesa.service" + mode: '0644' + register: matrix_ketesa_systemd_service_result + +- name: Determine whether Ketesa needs a restart + ansible.builtin.set_fact: + matrix_ketesa_restart_necessary: >- + {{ + matrix_ketesa_support_files_result.changed | default(false) + or matrix_ketesa_config_result.changed | default(false) + or matrix_ketesa_systemd_service_result.changed | default(false) + or matrix_ketesa_container_image_pull_result.changed | default(false) + or matrix_ketesa_container_image_build_result.changed | default(false) + }} diff --git a/roles/custom/matrix-ketesa/tasks/setup_uninstall.yml b/roles/custom/matrix-ketesa/tasks/setup_uninstall.yml new file mode 100644 index 000000000..7f3c4c26a --- /dev/null +++ b/roles/custom/matrix-ketesa/tasks/setup_uninstall.yml @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: 2022 - 2023 Slavi Pantaleev +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Check existence of matrix-ketesa service + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-ketesa.service" + register: matrix_ketesa_service_stat + +- when: matrix_ketesa_service_stat.stat.exists | bool + block: + - name: Ensure matrix-ketesa is stopped + ansible.builtin.service: + name: matrix-ketesa + state: stopped + enabled: false + daemon_reload: true + + - name: Ensure matrix-ketesa.service doesn't exist + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-ketesa.service" + state: absent + + - name: Ensure matrix-ketesa directory doesn't exist + ansible.builtin.file: + path: "{{ matrix_ketesa_base_path }}" + state: absent diff --git a/roles/custom/matrix-ketesa/tasks/validate_config.yml b/roles/custom/matrix-ketesa/tasks/validate_config.yml new file mode 100644 index 000000000..d4f12cd9e --- /dev/null +++ b/roles/custom/matrix-ketesa/tasks/validate_config.yml @@ -0,0 +1,59 @@ +# SPDX-FileCopyrightText: 2020 - 2025 Slavi Pantaleev +# SPDX-FileCopyrightText: 2022 MDAD project contributors +# SPDX-FileCopyrightText: 2025 Suguru Hirahara +# SPDX-FileCopyrightText: 2026 Nikita Chernyi +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Fail if matrix-ketesa is enabled for a non-Synapse homeserver + ansible.builtin.fail: + msg: >- + matrix-ketesa can only be used with the Synapse homeserver implementation. + Your configuration has `matrix_ketesa_enabled: true`, but `matrix_homeserver_implementation` is set to `{{ matrix_homeserver_implementation }}`. + Disable matrix-ketesa or switch to Synapse. + when: + - matrix_ketesa_enabled | bool + - matrix_homeserver_implementation != 'synapse' + +- name: (Deprecation) Catch and report renamed matrix-ketesa settings + ansible.builtin.fail: + msg: >- + Your configuration contains a variable, which now has a different name. + Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_synapse_admin_docker_repo', 'new': 'matrix_ketesa_container_image_self_build_repo'} + - {'old': 'matrix_synapse_admin_container_self_build', 'new': 'matrix_ketesa_container_image_self_build'} + - {'old': 'matrix_synapse_admin_container_self_build_repo', 'new': 'matrix_ketesa_container_image_self_build_repo'} + - {'old': 'matrix_synapse_admin_public_endpoint', 'new': 'matrix_ketesa_path_prefix'} + - {'old': 'matrix_synapse_admin_nginx_proxy_integration_enabled', 'new': '<removed>'} + - {'old': 'matrix_synapse_admin_docker_image_name_prefix', 'new': 'matrix_ketesa_container_image_registry_prefix'} + - {'old': 'matrix_synapse_admin_docker_image', 'new': 'matrix_ketesa_container_image'} + - {'old': 'matrix_synapse_admin_docker_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_synapse_admin_docker_image_registry_prefix', 'new': 'matrix_ketesa_container_image_registry_prefix'} + - {'old': 'matrix_synapse_admin_docker_image_registry_prefix_upstream', 'new': 'matrix_ketesa_container_image_registry_prefix_upstream'} + - {'old': 'matrix_synapse_admin_docker_image_registry_prefix_upstream_default', 'new': 'matrix_ketesa_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_synapse_admin_docker_src_files_path', 'new': 'matrix_ketesa_container_src_files_path'} + - {'old': 'matrix_ketesa_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} + +- when: matrix_ketesa_container_labels_traefik_enabled | bool + block: + - name: Fail if required matrix-ketesa Traefik settings not defined + ansible.builtin.fail: + msg: >- + You need to define a required configuration setting (`{{ item }}`). + when: "lookup('vars', item, default='') == ''" + with_items: + - matrix_ketesa_container_labels_traefik_hostname + - matrix_ketesa_container_labels_traefik_path_prefix + + # We ensure it doesn't end with a slash, because we handle both (slash and no-slash). + # Knowing that `matrix_ketesa_container_labels_traefik_path_prefix` does not end with a slash + # ensures we know how to set these routes up without having to do "does it end with a slash" checks elsewhere. + - name: Fail if matrix_ketesa_container_labels_traefik_path_prefix ends with a slash + ansible.builtin.fail: + msg: >- + matrix_ketesa_container_labels_traefik_path_prefix (`{{ matrix_ketesa_container_labels_traefik_path_prefix }}`) must either be `/` or not end with a slash (e.g. `/ketesa`). + when: "matrix_ketesa_container_labels_traefik_path_prefix != '/' and matrix_ketesa_container_labels_traefik_path_prefix[-1] == '/'" diff --git a/roles/custom/matrix-ketesa/templates/labels.j2 b/roles/custom/matrix-ketesa/templates/labels.j2 new file mode 100644 index 000000000..4fdec769a --- /dev/null +++ b/roles/custom/matrix-ketesa/templates/labels.j2 @@ -0,0 +1,59 @@ +{# +SPDX-FileCopyrightText: 2023 - 2024 Slavi Pantaleev +SPDX-FileCopyrightText: 2025 MDAD project contributors +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later +#} + +{% if matrix_ketesa_container_labels_traefik_enabled %} +traefik.enable=true + +{% if matrix_ketesa_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_ketesa_container_labels_traefik_docker_network }} +{% endif %} + +traefik.http.services.matrix-ketesa.loadbalancer.server.port=8080 + +{% set middlewares = [] %} + +{% if matrix_ketesa_container_labels_traefik_ipallowlist_sourcerange | length > 0 %} +traefik.http.middlewares.matrix-ketesa-ipallowlist.ipallowlist.sourcerange={{ matrix_ketesa_container_labels_traefik_ipallowlist_sourcerange | join(',') }} +{% set middlewares = middlewares + ['matrix-ketesa-ipallowlist'] %} +{% endif %} + +{% if matrix_ketesa_container_labels_traefik_path_prefix != '/' %} +traefik.http.middlewares.matrix-ketesa-slashless-redirect.redirectregex.regex=({{ matrix_ketesa_container_labels_traefik_path_prefix | quote }})$ +traefik.http.middlewares.matrix-ketesa-slashless-redirect.redirectregex.replacement=${1}/ +{% set middlewares = middlewares + ['matrix-ketesa-slashless-redirect'] %} +{% endif %} + +{% if matrix_ketesa_container_labels_traefik_path_prefix != '/' %} +traefik.http.middlewares.matrix-ketesa-strip-prefix.stripprefix.prefixes={{ matrix_ketesa_container_labels_traefik_path_prefix }} +{% set middlewares = middlewares + ['matrix-ketesa-strip-prefix'] %} +{% endif %} + +{% if matrix_ketesa_container_labels_traefik_additional_response_headers.keys() | length > 0 %} +{% for name, value in matrix_ketesa_container_labels_traefik_additional_response_headers.items() %} +traefik.http.middlewares.matrix-ketesa-add-headers.headers.customresponseheaders.{{ name }}={{ value }} +{% endfor %} +{% set middlewares = middlewares + ['matrix-ketesa-add-headers'] %} +{% endif %} + +traefik.http.routers.matrix-ketesa.rule={{ matrix_ketesa_container_labels_traefik_rule }} +{% if matrix_ketesa_container_labels_traefik_priority | int > 0 %} +traefik.http.routers.matrix-ketesa.priority={{ matrix_ketesa_container_labels_traefik_priority }} +{% endif %} +{% if middlewares | length > 0 %} +traefik.http.routers.matrix-ketesa.middlewares={{ middlewares | join(',') }} +{% endif %} +traefik.http.routers.matrix-ketesa.service=matrix-ketesa +traefik.http.routers.matrix-ketesa.entrypoints={{ matrix_ketesa_container_labels_traefik_entrypoints }} +traefik.http.routers.matrix-ketesa.tls={{ matrix_ketesa_container_labels_traefik_tls | to_json }} +{% if matrix_ketesa_container_labels_traefik_tls %} +traefik.http.routers.matrix-ketesa.tls.certResolver={{ matrix_ketesa_container_labels_traefik_tls_certResolver }} +{% endif %} + +{% endif %} + +{{ matrix_ketesa_container_labels_additional_labels }} diff --git a/roles/custom/matrix-synapse-admin/templates/systemd/matrix-synapse-admin.service.j2 b/roles/custom/matrix-ketesa/templates/systemd/matrix-ketesa.service.j2 similarity index 52% rename from roles/custom/matrix-synapse-admin/templates/systemd/matrix-synapse-admin.service.j2 rename to roles/custom/matrix-ketesa/templates/systemd/matrix-ketesa.service.j2 index 47eafe72f..809a7e1b7 100644 --- a/roles/custom/matrix-synapse-admin/templates/systemd/matrix-synapse-admin.service.j2 +++ b/roles/custom/matrix-ketesa/templates/systemd/matrix-ketesa.service.j2 @@ -1,11 +1,11 @@ #jinja2: lstrip_blocks: True [Unit] -Description=matrix-synapse-admin -{% for service in matrix_synapse_admin_systemd_required_services_list %} +Description=matrix-ketesa +{% for service in matrix_ketesa_systemd_required_services_list %} Requires={{ service }} After={{ service }} {% endfor %} -{% for service in matrix_synapse_admin_systemd_wanted_services_list %} +{% for service in matrix_ketesa_systemd_wanted_services_list %} Wants={{ service }} {% endfor %} DefaultDependencies=no @@ -13,39 +13,41 @@ DefaultDependencies=no [Service] Type=simple Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-synapse-admin 2>/dev/null || true' -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-synapse-admin 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-ketesa 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-ketesa 2>/dev/null || true' ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --rm \ - --name=matrix-synapse-admin \ + --name=matrix-ketesa \ --log-driver=none \ --cap-drop=ALL \ --read-only \ - --user={{ matrix_synapse_admin_container_uid }}:{{ matrix_synapse_admin_container_gid }} \ - --network={{ matrix_synapse_admin_container_network }} \ - {% if matrix_synapse_admin_container_http_host_bind_port %} - -p {{ matrix_synapse_admin_container_http_host_bind_port }}:8080 \ + --user={{ matrix_ketesa_container_uid }}:{{ matrix_ketesa_container_gid }} \ + --network={{ matrix_ketesa_container_network }} \ + {% if matrix_ketesa_container_http_host_bind_port %} + -p {{ matrix_ketesa_container_http_host_bind_port }}:8080 \ {% endif %} - --label-file={{ matrix_synapse_admin_base_path }}/labels \ - --mount type=bind,src={{ matrix_synapse_admin_config_path }}/config.json,dst=/var/public/config.json,ro \ - {% for arg in matrix_synapse_admin_container_extra_arguments %} + --label-file={{ matrix_ketesa_base_path }}/labels \ + --mount type=bind,src={{ matrix_ketesa_config_path }}/config.json,dst=/var/public/config.json,ro \ + {% for arg in matrix_ketesa_container_extra_arguments %} {{ arg }} \ {% endfor %} - {{ matrix_synapse_admin_container_image }} + {{ matrix_ketesa_container_image }} -{% for network in matrix_synapse_admin_container_additional_networks %} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-synapse-admin +{% if matrix_ketesa_container_network != 'host' %} +{% for network in matrix_ketesa_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-ketesa {% endfor %} +{% endif %} -ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-synapse-admin +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-ketesa -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-synapse-admin 2>/dev/null || true' -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-synapse-admin 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-ketesa 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-ketesa 2>/dev/null || true' Restart=always RestartSec=30 -SyslogIdentifier=matrix-synapse-admin +SyslogIdentifier=matrix-ketesa [Install] WantedBy=multi-user.target diff --git a/roles/custom/matrix-ketesa/templates/systemd/matrix-ketesa.service.j2.license b/roles/custom/matrix-ketesa/templates/systemd/matrix-ketesa.service.j2.license new file mode 100644 index 000000000..2215aa321 --- /dev/null +++ b/roles/custom/matrix-ketesa/templates/systemd/matrix-ketesa.service.j2.license @@ -0,0 +1,5 @@ +SPDX-FileCopyrightText: 2020 - 2026 Slavi Pantaleev +SPDX-FileCopyrightText: 2020 Dan Arnfield +SPDX-FileCopyrightText: 2026 Nikita Chernyi + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-ldap-registration-proxy/defaults/main.yml b/roles/custom/matrix-ldap-registration-proxy/defaults/main.yml deleted file mode 100644 index 96209563a..000000000 --- a/roles/custom/matrix-ldap-registration-proxy/defaults/main.yml +++ /dev/null @@ -1,112 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2025 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 Julian-Samuel Gebühr -# SPDX-FileCopyrightText: 2022 MDAD project contributors -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- -# matrix_ldap_registration_proxy - Want to build a large-scale Matrix server using external registration on LDAP? -# Project source code URL: https://gitlab.com/activism.international/matrix_ldap_registration_proxy - -matrix_ldap_registration_proxy_enabled: true - -matrix_ldap_registration_proxy_hostname: '' - -matrix_ldap_registration_proxy_container_image: "{{ matrix_ldap_registration_proxy_container_image_registry_prefix }}matrix_ldap_registration_proxy" -matrix_ldap_registration_proxy_container_image_registry_prefix: "{{ 'localhost/' if matrix_ldap_registration_proxy_container_image_self_build else matrix_ldap_registration_proxy_container_image_registry_prefix_upstream }}" -matrix_ldap_registration_proxy_container_image_registry_prefix_upstream: "{{ matrix_ldap_registration_proxy_container_image_registry_prefix_upstream_default }}" -matrix_ldap_registration_proxy_container_image_registry_prefix_upstream_default: "" - -matrix_ldap_registration_proxy_container_image_self_build: true -matrix_ldap_registration_proxy_container_image_self_build_repo: "https://gitlab.com/activism.international/matrix_ldap_registration_proxy.git" -matrix_ldap_registration_proxy_container_image_self_build_branch: "{{ matrix_ldap_registration_proxy_version }}" - -matrix_ldap_registration_proxy_version: "296246afc6a9b3105e67fcf6621cf05ebc74b873" - -matrix_ldap_registration_proxy_base_path: "{{ matrix_base_data_path }}/matrix_ldap_registration_proxy" -# We need the docker src directory to be named matrix_ldap_registration_proxy. -matrix_ldap_registration_proxy_container_src_files_path: "{{ matrix_ldap_registration_proxy_base_path }}/docker-src/matrix_ldap_registration_proxy" -matrix_ldap_registration_proxy_config_path: "{{ matrix_ldap_registration_proxy_base_path }}/config" - -matrix_ldap_registration_proxy_ldap_uri: "" -matrix_ldap_registration_proxy_ldap_base_dn: "" -matrix_ldap_registration_proxy_ldap_user: "" -matrix_ldap_registration_proxy_ldap_password: "" -matrix_ldap_registration_proxy_matrix_server_name: "{{ matrix_domain }}" -matrix_ldap_registration_proxy_matrix_server_url: "" - -# Controls whether the self-check feature should validate SSL certificates. -matrix_matrix_ldap_registration_proxy_self_check_validate_certificates: true - -matrix_ldap_registration_listen_port: 8080 - -# Controls whether the matrix_ldap_registration_proxy container exposes its HTTP port (tcp/{{ matrix_ldap_registration_listen_port }} in the container). -# -# Takes an "<ip>:<port>" or "<port>" value (e.g. "127.0.0.1:8080"), or empty string to not expose. -matrix_ldap_registration_proxy_container_http_host_bind_port: '' - -matrix_ldap_registration_proxy_container_network: "" - -matrix_ldap_registration_proxy_container_additional_networks: "{{ matrix_ldap_registration_proxy_container_additional_networks_auto + matrix_ldap_registration_proxy_container_additional_networks_custom }}" -matrix_ldap_registration_proxy_container_additional_networks_auto: [] -matrix_ldap_registration_proxy_container_additional_networks_custom: [] - -# matrix_ldap_registration_proxy_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. -# See `../templates/labels.j2` for details. -# -# To inject your own other container labels, see `matrix_ldap_registration_proxy_container_labels_additional_labels`. -matrix_ldap_registration_proxy_container_labels_traefik_enabled: true -matrix_ldap_registration_proxy_container_labels_traefik_docker_network: "{{ matrix_ldap_registration_proxy_container_network }}" -matrix_ldap_registration_proxy_container_labels_traefik_entrypoints: web-secure -matrix_ldap_registration_proxy_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose ldap-registration-proxy's registration endpoint (matrix_ldap_registration_proxy_container_labels_registration_endpoint_path) -matrix_ldap_registration_proxy_container_labels_registration_endpoint_enabled: true -matrix_ldap_registration_proxy_container_labels_registration_endpoint_hostname: "{{ matrix_ldap_registration_proxy_hostname }}" -matrix_ldap_registration_proxy_container_labels_registration_endpoint_path: "/_matrix/client/{version:(r0|v3)}/register" -matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_rule: "Host(`{{ matrix_ldap_registration_proxy_container_labels_registration_endpoint_hostname }}`) && Path(`{{ matrix_ldap_registration_proxy_container_labels_registration_endpoint_path }}`)" -matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_priority: 0 -matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_entrypoints: "{{ matrix_ldap_registration_proxy_container_labels_traefik_entrypoints }}" -matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_tls: "{{ matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_entrypoints != 'web' }}" -matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_tls_certResolver: "{{ matrix_ldap_registration_proxy_container_labels_traefik_tls_certResolver }}" # noqa var-naming - -# matrix_ldap_registration_proxy_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. -# See `../templates/labels.j2` for details. -# -# Example: -# matrix_ldap_registration_proxy_container_labels_additional_labels: | -# my.label=1 -# another.label="here" -matrix_ldap_registration_proxy_container_labels_additional_labels: '' - -# A list of extra arguments to pass to the container -matrix_ldap_registration_proxy_container_extra_arguments: [] - -# List of systemd services that matrix-ldap-registration-proxy.service depends on. -matrix_ldap_registration_proxy_systemd_required_services_list: "{{ matrix_ldap_registration_proxy_systemd_required_services_list_default + matrix_ldap_registration_proxy_systemd_required_services_list_auto + matrix_ldap_registration_proxy_systemd_required_services_list_custom }}" -matrix_ldap_registration_proxy_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_ldap_registration_proxy_systemd_required_services_list_auto: [] -matrix_ldap_registration_proxy_systemd_required_services_list_custom: [] - -# List of systemd services that matrix-ldap-registration-proxy.service wants -matrix_ldap_registration_proxy_systemd_wanted_services_list: "{{ matrix_ldap_registration_proxy_systemd_wanted_services_list_default + matrix_ldap_registration_proxy_systemd_wanted_services_list_auto + matrix_ldap_registration_proxy_systemd_wanted_services_list_custom }}" -matrix_ldap_registration_proxy_systemd_wanted_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_ldap_registration_proxy_systemd_wanted_services_list_auto: [] -matrix_ldap_registration_proxy_systemd_wanted_services_list_custom: [] - -# Additional environment variables to pass to the LDAP proxy environment variables. -# -# Example: -# matrix_ldap_registration_proxy_env_variables_extension: | -# KEY=value -matrix_ldap_registration_proxy_env_variables_extension: '' - -# matrix_ldap_registration_proxy_restart_necessary controls whether the service -# will be restarted (when true) or merely started (when false) by the -# systemd service manager role (when conditional restart is enabled). -# -# This value is automatically computed during installation based on whether -# any configuration files, the systemd service file, or the container image changed. -# The default of `false` means "no restart needed" — appropriate when the role's -# installation tasks haven't run (e.g., due to --tags skipping them). -matrix_ldap_registration_proxy_restart_necessary: false diff --git a/roles/custom/matrix-ldap-registration-proxy/tasks/main.yml b/roles/custom/matrix-ldap-registration-proxy/tasks/main.yml deleted file mode 100644 index 191a3538b..000000000 --- a/roles/custom/matrix-ldap-registration-proxy/tasks/main.yml +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Julian-Samuel Gebühr -# SPDX-FileCopyrightText: 2022 MDAD project contributors -# SPDX-FileCopyrightText: 2023 - 2024 Slavi Pantaleev -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- tags: - - setup-all - - setup-matrix-ldap-registration-proxy - - install-all - - install-matrix-ldap-registration-proxy - block: - - when: matrix_ldap_registration_proxy_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - - when: matrix_ldap_registration_proxy_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - -- tags: - - setup-all - - setup-matrix-ldap-registration-proxy - block: - - when: not matrix_ldap_registration_proxy_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" diff --git a/roles/custom/matrix-ldap-registration-proxy/tasks/setup_install.yml b/roles/custom/matrix-ldap-registration-proxy/tasks/setup_install.yml deleted file mode 100644 index ebf1212ff..000000000 --- a/roles/custom/matrix-ldap-registration-proxy/tasks/setup_install.yml +++ /dev/null @@ -1,87 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 Julian-Samuel Gebühr -# SPDX-FileCopyrightText: 2022 MDAD project contributors -# SPDX-FileCopyrightText: 2022 Sebastian Gumprich -# SPDX-FileCopyrightText: 2024 David Mehren -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Ensure matrix_ldap_registration_proxy paths exist - ansible.builtin.file: - path: "{{ item.path }}" - state: directory - mode: '0750' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - with_items: - - {path: "{{ matrix_ldap_registration_proxy_config_path }}", when: true} - - {path: "{{ matrix_ldap_registration_proxy_container_src_files_path }}", when: true} - when: "item.when | bool" - -- name: Ensure matrix_ldap_registration_proxy repository is present on self-build - ansible.builtin.git: - repo: "{{ matrix_ldap_registration_proxy_container_image_self_build_repo }}" - dest: "{{ matrix_ldap_registration_proxy_container_src_files_path }}" - version: "{{ matrix_ldap_registration_proxy_container_image_self_build_branch }}" - force: "yes" - become: true - become_user: "{{ matrix_user_name }}" - register: matrix_ldap_registration_proxy_git_pull_results - -- name: Ensure matrix_ldap_registration_proxy Docker image is built - community.docker.docker_image: - name: "{{ matrix_ldap_registration_proxy_container_image }}" - source: build - force_source: "{{ matrix_ldap_registration_proxy_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_ldap_registration_proxy_container_src_files_path }}" - pull: true - when: true - register: matrix_ldap_registration_proxy_container_image_build_result - -- name: Ensure matrix_ldap_registration_proxy config installed - ansible.builtin.template: - src: "{{ role_path }}/templates/ldap-registration-proxy.env.j2" - dest: "{{ matrix_ldap_registration_proxy_config_path }}/ldap-registration-proxy.env" - mode: '0644' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - register: matrix_ldap_registration_proxy_config_result - -- name: Ensure matrix-ldap-registration-proxy support files installed - ansible.builtin.template: - src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_ldap_registration_proxy_base_path }}/{{ item }}" - mode: '0640' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - with_items: - - labels - register: matrix_ldap_registration_proxy_support_files_result - -- name: Ensure matrix-ldap-registration-proxy container network is created - community.general.docker_network: - enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_ldap_registration_proxy_container_network }}" - driver: bridge - driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - -- name: Ensure matrix-ldap-registration-proxy.service installed - ansible.builtin.template: - src: "{{ role_path }}/templates/systemd/matrix-ldap-registration-proxy.service.j2" - dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-ldap-registration-proxy.service" - mode: '0644' - register: matrix_ldap_registration_proxy_systemd_service_result - -- name: Determine whether matrix-ldap-registration-proxy needs a restart - ansible.builtin.set_fact: - matrix_ldap_registration_proxy_restart_necessary: >- - {{ - matrix_ldap_registration_proxy_config_result.changed | default(false) - or matrix_ldap_registration_proxy_support_files_result.changed | default(false) - or matrix_ldap_registration_proxy_systemd_service_result.changed | default(false) - or matrix_ldap_registration_proxy_container_image_build_result.changed | default(false) - }} diff --git a/roles/custom/matrix-ldap-registration-proxy/tasks/setup_uninstall.yml b/roles/custom/matrix-ldap-registration-proxy/tasks/setup_uninstall.yml deleted file mode 100644 index 281488b18..000000000 --- a/roles/custom/matrix-ldap-registration-proxy/tasks/setup_uninstall.yml +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2023 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 MDAD project contributors -# SPDX-FileCopyrightText: 2022 Sebastian Gumprich -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Check existence of matrix-matrix_ldap_registration_proxy service - ansible.builtin.stat: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-ldap-registration-proxy.service" - register: matrix_ldap_registration_proxy_service_stat - -- when: matrix_ldap_registration_proxy_service_stat.stat.exists | bool - block: - - name: Ensure matrix-matrix_ldap_registration_proxy is stopped - ansible.builtin.service: - name: matrix-ldap-registration-proxy - state: stopped - enabled: false - daemon_reload: true - - - name: Ensure matrix-ldap-registration-proxy.service doesn't exist - ansible.builtin.file: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-ldap-registration-proxy.service" - state: absent - - - name: Ensure Matrix matrix_ldap_registration_proxy paths don't exist - ansible.builtin.file: - path: "{{ matrix_ldap_registration_proxy_base_path }}" - state: absent diff --git a/roles/custom/matrix-ldap-registration-proxy/tasks/validate_config.yml b/roles/custom/matrix-ldap-registration-proxy/tasks/validate_config.yml deleted file mode 100644 index 238801892..000000000 --- a/roles/custom/matrix-ldap-registration-proxy/tasks/validate_config.yml +++ /dev/null @@ -1,38 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 Julian-Samuel Gebühr -# SPDX-FileCopyrightText: 2022 MDAD project contributors -# SPDX-FileCopyrightText: 2025 Suguru Hirahara -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: (Deprecation) Catch and report renamed matrix-ldap-registration-proxy settings - ansible.builtin.fail: - msg: >- - Your configuration contains a variable, which now has a different name. - Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). - when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" - with_items: - - {'old': 'matrix_ldap_registration_proxy_registration_addr_with_container', 'new': '<removed>'} - - {'old': 'matrix_ldap_registration_proxy_registration_addr_sans_container', 'new': '<removed>'} - - {'old': 'matrix_ldap_registration_proxy_container_port', 'new': 'matrix_ldap_registration_listen_port'} - - {'old': 'matrix_ldap_registration_proxy_registration_endpoint', 'new': 'matrix_ldap_registration_proxy_container_labels_registration_endpoint_path'} - - {'old': 'matrix_ldap_registration_proxy_docker_image', 'new': 'matrix_ldap_registration_proxy_container_image'} - - {'old': 'matrix_ldap_registration_proxy_docker_image_registry_prefix', 'new': 'matrix_ldap_registration_proxy_container_image_registry_prefix'} - - {'old': 'matrix_ldap_registration_proxy_docker_image_registry_prefix_upstream', 'new': 'matrix_ldap_registration_proxy_container_image_registry_prefix_upstream'} - - {'old': 'matrix_ldap_registration_proxy_docker_image_registry_prefix_upstream_default', 'new': 'matrix_ldap_registration_proxy_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_ldap_registration_proxy_docker_src_files_path', 'new': 'matrix_ldap_registration_proxy_container_src_files_path'} - -- name: Fail if required matrix-ldap-registration-proxy settings not defined - ansible.builtin.fail: - msg: >- - You need to define a required configuration setting (`{{ item }}`). - when: "lookup('vars', item, default='') == ''" - with_items: - - "matrix_ldap_registration_proxy_hostname" - - "matrix_ldap_registration_proxy_ldap_uri" - - "matrix_ldap_registration_proxy_ldap_base_dn" - - "matrix_ldap_registration_proxy_ldap_user" - - "matrix_ldap_registration_proxy_ldap_password" - - "matrix_ldap_registration_proxy_container_network" diff --git a/roles/custom/matrix-ldap-registration-proxy/templates/labels.j2 b/roles/custom/matrix-ldap-registration-proxy/templates/labels.j2 deleted file mode 100644 index 73a7d25ed..000000000 --- a/roles/custom/matrix-ldap-registration-proxy/templates/labels.j2 +++ /dev/null @@ -1,51 +0,0 @@ -{# -SPDX-FileCopyrightText: 2024 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later -#} - -{% if matrix_ldap_registration_proxy_container_labels_traefik_enabled %} -traefik.enable=true - -{% if matrix_ldap_registration_proxy_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_ldap_registration_proxy_container_labels_traefik_docker_network }} -{% endif %} - -{% if matrix_ldap_registration_proxy_container_labels_registration_endpoint_enabled %} -############################################################ -# # -# Registration # -# # -############################################################ - -traefik.http.services.matrix-ldap-registration-proxy.loadbalancer.server.port={{ matrix_ldap_registration_listen_port }} - -traefik.http.middlewares.matrix-ldap-registration-proxy-registration-endpoint-replacepath.replacepath.path=/register - -traefik.http.routers.matrix-ldap-registration-proxy-registration.rule={{ matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_rule }} - -traefik.http.routers.matrix-ldap-registration-proxy-registration.middlewares=matrix-ldap-registration-proxy-registration-endpoint-replacepath - -{% if matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_priority | int > 0 %} -traefik.http.routers.matrix-ldap-registration-proxy-registration.priority={{ matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_priority }} -{% endif %} - -traefik.http.routers.matrix-ldap-registration-proxy-registration.service=matrix-ldap-registration-proxy -traefik.http.routers.matrix-ldap-registration-proxy-registration.entrypoints={{ matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_entrypoints }} - -traefik.http.routers.matrix-ldap-registration-proxy-registration.tls={{ matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_tls | to_json }} -{% if matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_tls %} -traefik.http.routers.matrix-ldap-registration-proxy-registration.tls.certResolver={{ matrix_ldap_registration_proxy_container_labels_registration_endpoint_traefik_tls_certResolver }} -{% endif %} - -############################################################ -# # -# /Registration # -# # -############################################################ -{% endif %} - - -{% endif %} - -{{ matrix_ldap_registration_proxy_container_labels_additional_labels }} diff --git a/roles/custom/matrix-ldap-registration-proxy/templates/ldap-registration-proxy.env.j2 b/roles/custom/matrix-ldap-registration-proxy/templates/ldap-registration-proxy.env.j2 deleted file mode 100644 index d40193e1b..000000000 --- a/roles/custom/matrix-ldap-registration-proxy/templates/ldap-registration-proxy.env.j2 +++ /dev/null @@ -1,43 +0,0 @@ -{# -SPDX-FileCopyrightText: 2022 - 2024 Slavi Pantaleev -SPDX-FileCopyrightText: 2022 Julian-Samuel Gebühr -SPDX-FileCopyrightText: 2022 MDAD project contributors - -SPDX-License-Identifier: AGPL-3.0-or-later -#} - -# please specify the configuration here -# -# these settings are mandatory - -# The server to connect to. Please note it must be accessible from the Docker network -# example: `ldap://127.0.0.1:389` -LDAP_SERVER={{ matrix_ldap_registration_proxy_ldap_uri }} - -# the base DN used for user creation - -LDAP_BASE_DN={{ matrix_ldap_registration_proxy_ldap_base_dn }} - -# the privileged user used for user creation including it's DN -# example: `uid=admin,cn=users,cn=accounts,dc=example,dc=org` - -LDAP_USER={{ matrix_ldap_registration_proxy_ldap_user }} - -# the password of the `LDAP_USER` used for authentication -LDAP_PASSWORD={{ matrix_ldap_registration_proxy_ldap_password }} - -# the human-readable server name of your Matrix server as used in the Matrix ID -# example: `example.org` -MATRIX_SERVER_NAME={{ matrix_ldap_registration_proxy_matrix_server_name }} - -# the url to access the Matrix server API without trailing `/` -# example: `https://matrix.example.org` -MATRIX_SERVER_URL={{ matrix_ldap_registration_proxy_matrix_server_url }} - -# these settings are optional: - -# Specify the port to listen on. Default to 8080 -LISTEN_PORT={{ matrix_ldap_registration_listen_port }} - -# Use this to extend the configuration with custom variables -{{ matrix_ldap_registration_proxy_env_variables_extension }} diff --git a/roles/custom/matrix-ldap-registration-proxy/templates/systemd/matrix-ldap-registration-proxy.service.j2 b/roles/custom/matrix-ldap-registration-proxy/templates/systemd/matrix-ldap-registration-proxy.service.j2 deleted file mode 100644 index e9b151373..000000000 --- a/roles/custom/matrix-ldap-registration-proxy/templates/systemd/matrix-ldap-registration-proxy.service.j2 +++ /dev/null @@ -1,52 +0,0 @@ -#jinja2: lstrip_blocks: True -[Unit] -Description=matrix_ldap_registration_proxy -{% for service in matrix_ldap_registration_proxy_systemd_required_services_list %} -Requires={{ service }} -After={{ service }} -{% endfor %} -{% for service in matrix_ldap_registration_proxy_systemd_wanted_services_list %} -Wants={{ service }} -{% endfor %} -DefaultDependencies=no - -[Service] -Type=simple -Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-ldap-registration-proxy 2>/dev/null || true' -ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-ldap-registration-proxy 2>/dev/null || true' - -# matrix_ldap_registration_proxy writes an SQLite shared library (libsqlitejdbc.so) to /tmp and executes it from there, -# so /tmp needs to be mounted with an exec option. -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ - --rm \ - --name=matrix-ldap-registration-proxy \ - --log-driver=none \ - --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ - --cap-drop=ALL \ - --read-only \ - --network={{ matrix_ldap_registration_proxy_container_network }} \ - {% if matrix_ldap_registration_proxy_container_http_host_bind_port %} - -p {{ matrix_ldap_registration_proxy_container_http_host_bind_port }}:{{ matrix_ldap_registration_listen_port }} \ - {% endif %} - --env-file {{ matrix_ldap_registration_proxy_config_path }}/ldap-registration-proxy.env \ - --label-file={{ matrix_ldap_registration_proxy_base_path }}/labels \ - {% for arg in matrix_ldap_registration_proxy_container_extra_arguments %} - {{ arg }} \ - {% endfor %} - {{ matrix_ldap_registration_proxy_container_image }} - -{% for network in matrix_ldap_registration_proxy_container_additional_networks %} -ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-ldap-registration-proxy -{% endfor %} - -ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-ldap-registration-proxy - -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-ldap-registration-proxy 2>/dev/null || true' -ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-ldap-registration-proxy 2>/dev/null || true' -Restart=always -RestartSec=30 -SyslogIdentifier=matrix-ldap-registration-proxy - -[Install] -WantedBy=multi-user.target diff --git a/roles/custom/matrix-ldap-registration-proxy/templates/systemd/matrix-ldap-registration-proxy.service.j2.license b/roles/custom/matrix-ldap-registration-proxy/templates/systemd/matrix-ldap-registration-proxy.service.j2.license deleted file mode 100644 index 618b21aeb..000000000 --- a/roles/custom/matrix-ldap-registration-proxy/templates/systemd/matrix-ldap-registration-proxy.service.j2.license +++ /dev/null @@ -1,5 +0,0 @@ -SPDX-FileCopyrightText: 2022 - 2024 Slavi Pantaleev -SPDX-FileCopyrightText: 2022 Julian-Samuel Gebühr -SPDX-FileCopyrightText: 2022 MDAD project contributors - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-livekit-jwt-service/defaults/main.yml b/roles/custom/matrix-livekit-jwt-service/defaults/main.yml index 6549653de..47ae57228 100644 --- a/roles/custom/matrix-livekit-jwt-service/defaults/main.yml +++ b/roles/custom/matrix-livekit-jwt-service/defaults/main.yml @@ -1,6 +1,6 @@ # SPDX-FileCopyrightText: 2022 MDAD project contributors # SPDX-FileCopyrightText: 2024 wjbeckett -# SPDX-FileCopyrightText: 2024 - 2025 Slavi Pantaleev +# SPDX-FileCopyrightText: 2024 - 2026 Slavi Pantaleev # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -25,11 +25,11 @@ matrix_livekit_jwt_service_container_additional_networks_auto: [] matrix_livekit_jwt_service_container_additional_networks_custom: [] # renovate: datasource=docker depName=ghcr.io/element-hq/lk-jwt-service -matrix_livekit_jwt_service_version: 0.4.1 +matrix_livekit_jwt_service_version: 0.6.0 matrix_livekit_jwt_service_container_image_self_build: false matrix_livekit_jwt_service_container_repo: "https://github.com/element-hq/lk-jwt-service.git" -matrix_livekit_jwt_service_container_repo_version: "{{ 'main' if matrix_livekit_jwt_service_version == 'latest' else ('v' + livekit_server_version) }}" +matrix_livekit_jwt_service_container_repo_version: "{{ 'main' if matrix_livekit_jwt_service_version == 'latest' else ('v' + matrix_livekit_jwt_service_version) }}" matrix_livekit_jwt_service_container_src_files_path: "{{ matrix_livekit_jwt_service_base_path }}/container-src" matrix_livekit_jwt_service_container_image: "{{ matrix_livekit_jwt_service_container_image_registry_prefix }}element-hq/lk-jwt-service:{{ matrix_livekit_jwt_service_container_image_tag }}" @@ -37,7 +37,6 @@ matrix_livekit_jwt_service_container_image_registry_prefix: "{{ 'localhost/' if matrix_livekit_jwt_service_container_image_registry_prefix_upstream: "{{ matrix_livekit_jwt_service_container_image_registry_prefix_upstream_default }}" matrix_livekit_jwt_service_container_image_registry_prefix_upstream_default: ghcr.io/ matrix_livekit_jwt_service_container_image_tag: "{{ matrix_livekit_jwt_service_version }}" -matrix_livekit_jwt_service_container_image_force_pull: "{{ matrix_livekit_jwt_service_container_image.endswith(':latest') }}" matrix_livekit_jwt_service_container_labels_traefik_enabled: true matrix_livekit_jwt_service_container_labels_traefik_docker_network: "{{ matrix_livekit_jwt_service_container_network }}" @@ -68,6 +67,22 @@ matrix_livekit_jwt_service_container_labels_additional_labels: '' # A list of extra arguments to pass to the container matrix_livekit_jwt_service_container_extra_arguments: [] +# Controls whether the container's built-in healthcheck is left enabled. +# +# lk-jwt-service v0.6.0 added a healthcheck which builds its URL as +# `http://localhost:$LIVEKIT_JWT_BIND/healthz`, interpolating the bind address +# into the port slot. Because LIVEKIT_JWT_BIND is a bind address (`:8080`), the +# resulting URL is invalid and the check can never pass, leaving the container +# permanently unhealthy. Traefik skips unhealthy containers, so the service +# stops being routed and Element Call cannot obtain an SFU token. +# +# There is no way to correct the check from here: the image is built `FROM +# scratch`, so it has no shell for a `--health-cmd` override to use. +# +# Re-enable this once upstream fixes the check. +# See: https://github.com/element-hq/lk-jwt-service/pull/186 +matrix_livekit_jwt_service_container_healthcheck_enabled: false + # Controls the port that the service listens on internally in the container. # This is still used for Traefik configuration and container port binding. matrix_livekit_jwt_service_container_port: 8080 @@ -87,12 +102,35 @@ matrix_livekit_jwt_service_environment_variable_livekit_url: "" # Controls the LIVEKIT_SECRET environment variable matrix_livekit_jwt_service_environment_variable_livekit_secret: "" -# Controls the LIVEKIT_FULL_ACCESS_HOMESERVERS environment variable +# Controls the LIVEKIT_FULL_ACCESS_HOMESERVERS environment variable. # Comma-separated list of Matrix homeservers whose users are authorized with full access to LiveKit SFU features -# (supports * as a wildcard to allow all homeservers). +# (like creating rooms on the SFU). +# +# This is a required setting and the service refuses to start without it. +# Setting it to `*` grants full access to any federated Matrix user, but listing only the homeserver(s) +# you intend to serve is strongly recommended. +# +# To add additional homeservers, use `matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list_custom`. matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers: "{{ matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list | join(',') }}" +matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list: "{{ matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list_default + matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list_auto + matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list_custom }}" +matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list_default: ["{{ matrix_domain }}"] +matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list_auto: [] +matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list_custom: [] -matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list: ["*"] +# Controls the LIVEKIT_CS_API_URL_OVERRIDES environment variable. +# +# To learn where a user's homeserver serves its Client-Server API, the service performs `.well-known` discovery. +# That is, it requests `https://<server-name>/.well-known/matrix/client` over the network and reads `m.homeserver.base_url` out of it. +# Entries listed here are consulted first, so that the server names they cover are resolved without discovery. +# +# Keys are Matrix server names and values are Client-Server API base URLs (including the scheme). +# A playbook may inject an entry for the homeserver it manages, pointing the service at it directly. +# +# To add your own entries, use `matrix_livekit_jwt_service_environment_variable_livekit_cs_api_url_overrides_map_custom`. +matrix_livekit_jwt_service_environment_variable_livekit_cs_api_url_overrides: "{{ matrix_livekit_jwt_service_environment_variable_livekit_cs_api_url_overrides_map.items() | map('join', '=') | join(',') }}" +matrix_livekit_jwt_service_environment_variable_livekit_cs_api_url_overrides_map: "{{ matrix_livekit_jwt_service_environment_variable_livekit_cs_api_url_overrides_map_auto | combine(matrix_livekit_jwt_service_environment_variable_livekit_cs_api_url_overrides_map_custom) }}" +matrix_livekit_jwt_service_environment_variable_livekit_cs_api_url_overrides_map_auto: {} +matrix_livekit_jwt_service_environment_variable_livekit_cs_api_url_overrides_map_custom: {} # Additional environment variables to pass to the container. # @@ -118,3 +156,11 @@ matrix_livekit_jwt_service_systemd_required_services_list_custom: [] # The default of `false` means "no restart needed" — appropriate when the role's # installation tasks haven't run (e.g., due to --tags skipping them). matrix_livekit_jwt_service_restart_necessary: false + +# A list of additional "volumes" to mount in the container. +# Contains definition objects like this: `{"type": "bind", "src": "/outside", "dst": "/inside", "options": "readonly"}. +# See the `--mount` documentation for the `docker run` command. +# Note: internally, this uses the `--mount` flag for mounting the specified volumes. +matrix_livekit_jwt_service_container_additional_volumes: "{{ matrix_livekit_jwt_service_container_additional_volumes_auto + matrix_livekit_jwt_service_container_additional_volumes_custom }}" +matrix_livekit_jwt_service_container_additional_volumes_auto: [] +matrix_livekit_jwt_service_container_additional_volumes_custom: [] diff --git a/roles/custom/matrix-livekit-jwt-service/molecule/default/converge.yml b/roles/custom/matrix-livekit-jwt-service/molecule/default/converge.yml new file mode 100644 index 000000000..24e5c4e68 --- /dev/null +++ b/roles/custom/matrix-livekit-jwt-service/molecule/default/converge.yml @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-livekit-jwt-service Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include roles for matrix-livekit-jwt-service Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + - "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + loop_control: + loop_var: role_name + +# The component role installs the unit; systemd_service_manager starts it in a +# full deployment. Start it directly at that same role-scoped boundary. +- name: Ensure matrix-livekit-jwt-service is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure matrix-livekit-jwt-service is started + ansible.builtin.systemd_service: + name: matrix-livekit-jwt-service.service + state: started diff --git a/roles/custom/matrix-livekit-jwt-service/molecule/default/files/openid-fixture.py b/roles/custom/matrix-livekit-jwt-service/molecule/default/files/openid-fixture.py new file mode 100644 index 000000000..cb59f64d6 --- /dev/null +++ b/roles/custom/matrix-livekit-jwt-service/molecule/default/files/openid-fixture.py @@ -0,0 +1,53 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +"""Small HTTPS Matrix federation OpenID userinfo fixture for Molecule.""" + +import json +import ssl +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from urllib.parse import parse_qs, urlparse + + +KNOWN_TOKEN = "known-openid-token" +KNOWN_SUBJECT = "@alice:matrix-openid-fixture:8443" +REQUESTS = [] + + +class OpenIDHandler(BaseHTTPRequestHandler): + def send_json(self, status, document): + body = json.dumps(document, separators=(",", ":")).encode() + self.send_response(status) + self.send_header("Content-Type", "application/json") + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + + def do_GET(self): # noqa: N802 - BaseHTTPRequestHandler API + parsed = urlparse(self.path) + if parsed.path == "/_molecule/requests": + self.send_json(200, {"requests": REQUESTS}) + return + + if parsed.path != "/_matrix/federation/v1/openid/userinfo": + self.send_json(404, {"errcode": "M_NOT_FOUND"}) + return + + token = parse_qs(parsed.query).get("access_token", [""])[0] + REQUESTS.append({"path": parsed.path, "access_token": token}) + if token == KNOWN_TOKEN: + self.send_json(200, {"sub": KNOWN_SUBJECT}) + return + + self.send_json(401, {"errcode": "M_UNAUTHORIZED", "error": "unknown token"}) + + def log_message(self, message, *args): + print("openid-fixture:", message % args, flush=True) + + +server = ThreadingHTTPServer(("0.0.0.0", 8443), OpenIDHandler) +tls_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) +tls_context.load_cert_chain("/fixture/cert.pem", "/fixture/key.pem") +server.socket = tls_context.wrap_socket(server.socket, server_side=True) +server.serve_forever() diff --git a/roles/custom/matrix-livekit-jwt-service/molecule/default/molecule.yml b/roles/custom/matrix-livekit-jwt-service/molecule/default/molecule.yml new file mode 100644 index 000000000..968e05a6b --- /dev/null +++ b/roles/custom/matrix-livekit-jwt-service/molecule/default/molecule.yml @@ -0,0 +1,95 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-livekit-jwt-service-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + matrix_livekit_jwt_service_enabled: true + + # Exercise role-controlled paths and networking with values which differ + # from both the role and image defaults. + matrix_livekit_jwt_service_base_path: /matrix/molecule-livekit-jwt-service + matrix_livekit_jwt_service_container_network: matrix-livekit-jwt-service-molecule + matrix_livekit_jwt_service_container_port: 8097 + matrix_livekit_jwt_service_environment_variable_livekit_jwt_bind: ":8097" + + matrix_livekit_jwt_service_environment_variable_livekit_key: molecule-livekit-api-key + matrix_livekit_jwt_service_environment_variable_livekit_secret: molecule-livekit-signing-secret-32-bytes-long + matrix_livekit_jwt_service_environment_variable_livekit_url: wss://sfu.livekit.molecule.invalid:7881/rtc + + # The OpenID fixture's origin is deliberately absent. This makes the + # successful request a restricted-user flow, so no SFU is contacted. + matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list_default: + - full-access.molecule.local + matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers_list_custom: + - second-full-access.molecule.local + + matrix_livekit_jwt_service_environment_variable_livekit_cs_api_url_overrides_map_custom: + "matrix-openid-fixture:8443": https://client-api.override.molecule.invalid + + # The scenario-local OpenID endpoint uses a self-signed certificate. + matrix_livekit_jwt_service_environment_variables_extension: | + LIVEKIT_INSECURE_SKIP_VERIFY_TLS=YES_I_KNOW_WHAT_I_AM_DOING + LIVEKIT_LOG_LEVEL=debug + MOLECULE_LIVEKIT_MARKER=environment-reached + + # v0.6.0 ships a malformed image healthcheck. The role intentionally + # disables it until upstream fixes its LIVEKIT_JWT_BIND interpolation. + matrix_livekit_jwt_service_container_healthcheck_enabled: false + + matrix_livekit_jwt_service_hostname: jwt.livekit.molecule.local + matrix_livekit_jwt_service_path_prefix: /matrix-rtc/jwt + matrix_livekit_jwt_service_container_labels_traefik_enabled: true + matrix_livekit_jwt_service_container_labels_traefik_priority: 847 + matrix_livekit_jwt_service_container_labels_traefik_entrypoints: web + matrix_livekit_jwt_service_container_labels_traefik_tls: false + matrix_livekit_jwt_service_container_labels_traefik_additional_response_headers_custom: + X-Molecule-LiveKit: jwt-service + matrix_livekit_jwt_service_container_labels_additional_labels: | + molecule.livekit-jwt.coverage=enabled + + # Prove the approved generic Docker-argument escape hatch reaches runtime. + matrix_livekit_jwt_service_container_extra_arguments: + - --hostname=livekit-jwt-molecule-runtime + - --label=molecule.livekit-jwt.extra-argument=reached + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-livekit-jwt-service/molecule/default/prepare.yml b/roles/custom/matrix-livekit-jwt-service/molecule/default/prepare.yml new file mode 100644 index 000000000..d75fed145 --- /dev/null +++ b/roles/custom/matrix-livekit-jwt-service/molecule/default/prepare.yml @@ -0,0 +1,127 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-livekit-jwt-service Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + - openssl + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" + + - name: Ensure the OpenID fixture directory exists + ansible.builtin.file: + path: /matrix/molecule-livekit-openid-fixture + state: directory + mode: "0755" + + - name: Install the OpenID fixture server + ansible.builtin.copy: + src: openid-fixture.py + dest: /matrix/molecule-livekit-openid-fixture/openid-fixture.py + mode: "0644" + + - name: Generate a self-signed certificate for the OpenID fixture + ansible.builtin.command: + argv: + - openssl + - req + - -x509 + - -newkey + - rsa:2048 + - -nodes + - -keyout + - /matrix/molecule-livekit-openid-fixture/key.pem + - -out + - /matrix/molecule-livekit-openid-fixture/cert.pem + - -days + - "2" + - -subj + - /CN=matrix-openid-fixture + creates: /matrix/molecule-livekit-openid-fixture/key.pem + + - name: Ensure the scenario container network exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_livekit_jwt_service_container_network }}" + register: matrix_livekit_jwt_service_molecule_network + changed_when: matrix_livekit_jwt_service_molecule_network.rc == 0 + failed_when: + - matrix_livekit_jwt_service_molecule_network.rc != 0 + - "'already exists' not in matrix_livekit_jwt_service_molecule_network.stderr" + + - name: Ensure a previous HTTPS OpenID fixture is gone + ansible.builtin.command: + argv: + - docker + - rm + - --force + - matrix-livekit-jwt-openid-fixture + register: matrix_livekit_jwt_service_openid_fixture_removal + changed_when: matrix_livekit_jwt_service_openid_fixture_removal.rc == 0 + failed_when: false + + - name: Ensure the HTTPS OpenID fixture is running + ansible.builtin.command: + argv: + - docker + - run + - --detach + - --name=matrix-livekit-jwt-openid-fixture + - --network={{ matrix_livekit_jwt_service_container_network }} + - --network-alias=matrix-openid-fixture + - --mount=type=bind,src=/matrix/molecule-livekit-openid-fixture,dst=/fixture,readonly + - "{{ molecule_shared_image_python }}" + - python3 + - /fixture/openid-fixture.py + register: matrix_livekit_jwt_service_openid_fixture_start + changed_when: matrix_livekit_jwt_service_openid_fixture_start.rc == 0 diff --git a/roles/custom/matrix-livekit-jwt-service/molecule/default/requirements.yml b/roles/custom/matrix-livekit-jwt-service/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-livekit-jwt-service/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-livekit-jwt-service/molecule/default/verify.yml b/roles/custom/matrix-livekit-jwt-service/molecule/default/verify.yml new file mode 100644 index 000000000..2905b329f --- /dev/null +++ b/roles/custom/matrix-livekit-jwt-service/molecule/default/verify.yml @@ -0,0 +1,509 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Verify matrix-livekit-jwt-service + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + vars: + matrix_livekit_jwt_service_runtime: "{{ (matrix_livekit_jwt_service_container_inspect.stdout | from_json) | first }}" + matrix_livekit_jwt_service_valid_request: + room_id: "!call-room:molecule.local" + slot_id: molecule-slot + openid_token: + access_token: known-openid-token + token_type: Bearer + matrix_server_name: "matrix-openid-fixture:8443" + expires_in: 3600 + member: + id: member-molecule-01 + claimed_user_id: "@alice:matrix-openid-fixture:8443" + claimed_device_id: DEVICE_MOLECULE + gather_facts: false + + tasks: + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_livekit_jwt_service_role_defaults + + - name: Wait for the LiveKit JWT service to become active + ansible.builtin.systemd_service: + name: matrix-livekit-jwt-service.service + register: matrix_livekit_jwt_service_service + until: matrix_livekit_jwt_service_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always keeps a crash-looping service nominally active. + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_service.status.ActiveState == 'active' + - matrix_livekit_jwt_service_service.status.NRestarts is defined + - matrix_livekit_jwt_service_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-livekit-jwt-service.service is + {{ matrix_livekit_jwt_service_service.status.ActiveState | default('unknown') }} after + {{ matrix_livekit_jwt_service_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-livekit-jwt-service.service is active and has not restarted" + + - name: Wait for the live health endpoint on the configured non-default port + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_livekit_jwt_service_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --output + - /dev/null + - --write-out + - "HTTP_STATUS=%{http_code}" + - http://matrix-livekit-jwt-service:8097/healthz + register: matrix_livekit_jwt_service_health + changed_when: false + until: matrix_livekit_jwt_service_health.stdout == 'HTTP_STATUS=200' + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the live service is healthy on the configured port + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_health.rc == 0 + - matrix_livekit_jwt_service_health.stdout == 'HTTP_STATUS=200' + fail_msg: "The LiveKit JWT service did not answer /healthz on port 8097" + success_msg: "The LiveKit JWT service is healthy on its non-default port" + + - name: Exercise the get_token CORS preflight + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_livekit_jwt_service_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --include + - --request + - OPTIONS + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-livekit-jwt-service:8097/get_token + register: matrix_livekit_jwt_service_cors + changed_when: false + failed_when: false + + - name: Assert get_token exposes its CORS contract + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_cors.rc == 0 + - "'HTTP_STATUS=200' in matrix_livekit_jwt_service_cors.stdout_lines" + - "'access-control-allow-origin: *' in matrix_livekit_jwt_service_cors.stdout | lower" + - "'access-control-allow-methods: post' in matrix_livekit_jwt_service_cors.stdout | lower" + - "'access-control-allow-headers: accept, content-type, content-length, accept-encoding, x-csrf-token' in matrix_livekit_jwt_service_cors.stdout | lower" + fail_msg: "OPTIONS /get_token did not return the service's expected CORS headers" + success_msg: "OPTIONS /get_token exposes the expected CORS contract" + + - name: Submit malformed JSON to get_token + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_livekit_jwt_service_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --header + - "Content-Type: application/json" + - --data-binary + - "{not-json" + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-livekit-jwt-service:8097/get_token + register: matrix_livekit_jwt_service_malformed + changed_when: false + failed_when: false + + - name: Assert malformed JSON is rejected structurally + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_malformed.rc == 0 + - matrix_livekit_jwt_service_malformed.stdout_lines[-1] == 'HTTP_STATUS=400' + - matrix_livekit_jwt_service_malformed_document.errcode == 'M_NOT_JSON' + - matrix_livekit_jwt_service_malformed_document.error == 'Error reading request' + fail_msg: "Malformed JSON did not produce the expected Matrix error response" + success_msg: "Malformed JSON is rejected with M_NOT_JSON" + vars: + matrix_livekit_jwt_service_malformed_document: >- + {{ matrix_livekit_jwt_service_malformed.stdout | regex_replace('(?s)\s*HTTP_STATUS=[0-9]+\s*$', '') | from_json }} + + - name: Ask get_token to validate an unknown OpenID token + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_livekit_jwt_service_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --header + - "Content-Type: application/json" + - --data-binary + - "{{ matrix_livekit_jwt_service_unknown_token_request | to_json }}" + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-livekit-jwt-service:8097/get_token + register: matrix_livekit_jwt_service_unknown_token + changed_when: false + failed_when: false + vars: + matrix_livekit_jwt_service_unknown_token_request: >- + {{ matrix_livekit_jwt_service_valid_request | combine({'openid_token': matrix_livekit_jwt_service_valid_request.openid_token | combine({'access_token': 'unknown-openid-token'})}, recursive=True) }} + + - name: Assert an unknown OpenID token is unauthorized + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_unknown_token.rc == 0 + - matrix_livekit_jwt_service_unknown_token.stdout_lines[-1] == 'HTTP_STATUS=401' + - matrix_livekit_jwt_service_unknown_token_document.errcode == 'M_UNAUTHORIZED' + - matrix_livekit_jwt_service_unknown_token_document.error == 'The request could not be authorised.' + fail_msg: "An unknown OpenID token was not rejected as unauthorized" + success_msg: "The live service rejects an unknown OpenID token" + vars: + matrix_livekit_jwt_service_unknown_token_document: >- + {{ matrix_livekit_jwt_service_unknown_token.stdout | regex_replace('(?s)\s*HTTP_STATUS=[0-9]+\s*$', '') | from_json }} + + - name: Ask get_token to validate a mismatched claimed user + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_livekit_jwt_service_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --header + - "Content-Type: application/json" + - --data-binary + - "{{ matrix_livekit_jwt_service_mismatched_user_request | to_json }}" + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-livekit-jwt-service:8097/get_token + register: matrix_livekit_jwt_service_mismatched_user + changed_when: false + failed_when: false + vars: + matrix_livekit_jwt_service_mismatched_user_request: >- + {{ matrix_livekit_jwt_service_valid_request | combine({'member': matrix_livekit_jwt_service_valid_request.member | combine({'claimed_user_id': '@mallory:matrix-openid-fixture:8443'})}, recursive=True) }} + + - name: Assert a valid token cannot impersonate another Matrix user + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_mismatched_user.rc == 0 + - matrix_livekit_jwt_service_mismatched_user.stdout_lines[-1] == 'HTTP_STATUS=401' + - matrix_livekit_jwt_service_mismatched_user_document.errcode == 'M_UNAUTHORIZED' + fail_msg: "The OpenID subject and claimed Matrix user mismatch was not rejected" + success_msg: "The live service rejects a claimed-user mismatch" + vars: + matrix_livekit_jwt_service_mismatched_user_document: >- + {{ matrix_livekit_jwt_service_mismatched_user.stdout | regex_replace('(?s)\s*HTTP_STATUS=[0-9]+\s*$', '') | from_json }} + + # The request's server is not in FULL_ACCESS, so this validates OpenID and + # signs a join token without trying to create a room on the absent SFU. + - name: Request a real restricted-user LiveKit JWT + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_livekit_jwt_service_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --header + - "Content-Type: application/json" + - --data-binary + - "{{ matrix_livekit_jwt_service_valid_request | to_json }}" + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-livekit-jwt-service:8097/get_token + register: matrix_livekit_jwt_service_token_response + changed_when: false + failed_when: false + + - name: Parse the successful token response + ansible.builtin.set_fact: + matrix_livekit_jwt_service_token_document: >- + {{ matrix_livekit_jwt_service_token_response.stdout | regex_replace('(?s)\s*HTTP_STATUS=[0-9]+\s*$', '') | from_json }} + + - name: Assert the live service returns a JWT for the configured SFU URL + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_token_response.rc == 0 + - matrix_livekit_jwt_service_token_response.stdout_lines[-1] == 'HTTP_STATUS=200' + - matrix_livekit_jwt_service_token_document.keys() | sort == ['jwt', 'url'] + - matrix_livekit_jwt_service_token_document.url == matrix_livekit_jwt_service_environment_variable_livekit_url + - matrix_livekit_jwt_service_token_document.jwt.split('.') | length == 3 + fail_msg: "The restricted-user exchange did not return a JWT and configured SFU URL" + success_msg: "The restricted-user exchange returns a real JWT for the configured SFU" + + - name: Decode and authenticate the returned LiveKit JWT + ansible.builtin.command: + argv: + - python3 + - -c + - >- + import base64, hashlib, hmac, json, sys; + parts = sys.argv[1].split('.'); + decode = lambda value: json.loads(base64.urlsafe_b64decode(value + '=' * (-len(value) % 4))); + signature = base64.urlsafe_b64decode(parts[2] + '=' * (-len(parts[2]) % 4)); + expected = hmac.new(sys.argv[2].encode(), (parts[0] + '.' + parts[1]).encode(), hashlib.sha256).digest(); + print(json.dumps({'header': decode(parts[0]), 'claims': decode(parts[1]), 'signature_valid': hmac.compare_digest(signature, expected)})) + - "{{ matrix_livekit_jwt_service_token_document.jwt }}" + - "{{ matrix_livekit_jwt_service_environment_variable_livekit_secret }}" + register: matrix_livekit_jwt_service_jwt_decode + changed_when: false + no_log: true + + - name: Assert the JWT signature, identity, room and restricted grant + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_jwt.signature_valid is sameas true + - matrix_livekit_jwt_service_jwt.header.alg == 'HS256' + - matrix_livekit_jwt_service_jwt.claims.iss == matrix_livekit_jwt_service_environment_variable_livekit_key + - matrix_livekit_jwt_service_jwt.claims.sub == 'BE7ZK/J/c3LsogjI1JLni7qtWV/DP6c+ev68BvHem0Y' + - matrix_livekit_jwt_service_jwt.claims.video.room == 'diNaPECp1jHt2l0dLdiDxi+dgNzgucxPYMD0lCs1tEQ' + - matrix_livekit_jwt_service_jwt.claims.video.roomJoin is sameas true + - "'roomCreate' not in matrix_livekit_jwt_service_jwt.claims.video" + - matrix_livekit_jwt_service_jwt.claims.video.canPublish is sameas true + - matrix_livekit_jwt_service_jwt.claims.video.canSubscribe is sameas true + - matrix_livekit_jwt_service_jwt.claims.video.canUpdateOwnMetadata is sameas true + - matrix_livekit_jwt_service_jwt.claims.exp | int - matrix_livekit_jwt_service_jwt.claims.nbf | int == 3600 + fail_msg: "The returned JWT lost its authenticated MSC4195 identity, room or restricted join grant" + success_msg: "The returned JWT has a valid signature and restricted MSC4195 grant" + vars: + matrix_livekit_jwt_service_jwt: "{{ matrix_livekit_jwt_service_jwt_decode.stdout | from_json }}" + + - name: Read the OpenID fixture's observed requests + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_livekit_jwt_service_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --insecure + - https://matrix-livekit-jwt-openid-fixture:8443/_molecule/requests + register: matrix_livekit_jwt_service_openid_requests_command + changed_when: false + + - name: Assert the live service exercised both OpenID fixture outcomes + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_openid_requests.requests | length >= 3 + - matrix_livekit_jwt_service_openid_requests.requests | map(attribute='path') | unique | list == ['/_matrix/federation/v1/openid/userinfo'] + - matrix_livekit_jwt_service_openid_requests.requests[-3:] | map(attribute='access_token') | list == ['unknown-openid-token', 'known-openid-token', 'known-openid-token'] + fail_msg: "The OpenID fixture did not observe the expected unknown and known token exchanges" + success_msg: "The service exercised both HTTPS OpenID fixture outcomes" + vars: + matrix_livekit_jwt_service_openid_requests: "{{ matrix_livekit_jwt_service_openid_requests_command.stdout | from_json }}" + + - name: Read the environment file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_livekit_jwt_service_base_path }}/env" + register: matrix_livekit_jwt_service_env_file + + - name: Initialize the parsed environment + ansible.builtin.set_fact: + matrix_livekit_jwt_service_env_parsed: {} + + - name: Parse the rendered environment + ansible.builtin.set_fact: + matrix_livekit_jwt_service_env_parsed: >- + {{ matrix_livekit_jwt_service_env_parsed | combine({item.split('=', 1)[0]: item.split('=', 1)[1]}) }} + loop: "{{ (matrix_livekit_jwt_service_env_file.content | b64decode).splitlines() | reject('equalto', '') }}" + when: "'=' in item" + no_log: true + + - name: Assert the rendered environment carries every scenario setting + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_env_parsed.LIVEKIT_JWT_BIND == ':8097' + - matrix_livekit_jwt_service_env_parsed.LIVEKIT_KEY == 'molecule-livekit-api-key' + - matrix_livekit_jwt_service_env_parsed.LIVEKIT_SECRET == 'molecule-livekit-signing-secret-32-bytes-long' + - matrix_livekit_jwt_service_env_parsed.LIVEKIT_URL == 'wss://sfu.livekit.molecule.invalid:7881/rtc' + - matrix_livekit_jwt_service_env_parsed.LIVEKIT_FULL_ACCESS_HOMESERVERS == 'full-access.molecule.local,second-full-access.molecule.local' + - matrix_livekit_jwt_service_env_parsed.LIVEKIT_CS_API_URL_OVERRIDES == 'matrix-openid-fixture:8443=https://client-api.override.molecule.invalid' + - matrix_livekit_jwt_service_env_parsed.LIVEKIT_INSECURE_SKIP_VERIFY_TLS == 'YES_I_KNOW_WHAT_I_AM_DOING' + - matrix_livekit_jwt_service_env_parsed.LIVEKIT_LOG_LEVEL == 'debug' + - matrix_livekit_jwt_service_env_parsed.MOLECULE_LIVEKIT_MARKER == 'environment-reached' + fail_msg: "The parsed environment file does not carry the scenario's complete contract" + success_msg: "The parsed environment file carries every scenario setting" + no_log: true + + - name: Read the labels file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_livekit_jwt_service_base_path }}/labels" + register: matrix_livekit_jwt_service_labels_file + + - name: Initialize the parsed labels + ansible.builtin.set_fact: + matrix_livekit_jwt_service_labels_parsed: {} + + - name: Parse the rendered labels + ansible.builtin.set_fact: + matrix_livekit_jwt_service_labels_parsed: >- + {{ matrix_livekit_jwt_service_labels_parsed | combine({item.split('=', 1)[0]: item.split('=', 1)[1]}) }} + loop: "{{ (matrix_livekit_jwt_service_labels_file.content | b64decode).splitlines() | reject('equalto', '') }}" + when: "'=' in item" + no_log: true + + - name: Assert the rendered labels carry the public routing contract + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_labels_parsed['traefik.enable'] == 'true' + - matrix_livekit_jwt_service_labels_parsed['traefik.docker.network'] == matrix_livekit_jwt_service_container_network + - matrix_livekit_jwt_service_labels_parsed['traefik.http.services.matrix-livekit-jwt-service.loadbalancer.server.port'] == '8097' + - matrix_livekit_jwt_service_labels_parsed['traefik.http.routers.matrix-livekit-jwt-service.rule'] == 'Host(`jwt.livekit.molecule.local`) && PathPrefix(`/matrix-rtc/jwt`)' + - matrix_livekit_jwt_service_labels_parsed['traefik.http.routers.matrix-livekit-jwt-service.priority'] == '847' + - matrix_livekit_jwt_service_labels_parsed['traefik.http.routers.matrix-livekit-jwt-service.entrypoints'] == 'web' + - matrix_livekit_jwt_service_labels_parsed['traefik.http.routers.matrix-livekit-jwt-service.tls'] == 'false' + - matrix_livekit_jwt_service_labels_parsed['traefik.http.routers.matrix-livekit-jwt-service.middlewares'] == 'matrix-livekit-jwt-service-slashless-redirect,matrix-livekit-jwt-service-strip-prefix,matrix-livekit-jwt-service-add-headers' + - matrix_livekit_jwt_service_labels_parsed['traefik.http.middlewares.matrix-livekit-jwt-service-add-headers.headers.customresponseheaders.X-Molecule-LiveKit'] == 'jwt-service' + - matrix_livekit_jwt_service_labels_parsed['molecule.livekit-jwt.coverage'] == 'enabled' + fail_msg: "The parsed labels do not carry the scenario's routing contract" + success_msg: "The parsed labels carry the scenario's complete routing contract" + + - name: Inspect the running LiveKit JWT service container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-livekit-jwt-service + register: matrix_livekit_jwt_service_container_inspect + changed_when: false + + - name: Assert the configured environment reached the running container + ansible.builtin.assert: + that: + - "'LIVEKIT_JWT_BIND=:8097' in matrix_livekit_jwt_service_runtime.Config.Env" + - "'LIVEKIT_FULL_ACCESS_HOMESERVERS=full-access.molecule.local,second-full-access.molecule.local' in matrix_livekit_jwt_service_runtime.Config.Env" + - "'LIVEKIT_CS_API_URL_OVERRIDES=matrix-openid-fixture:8443=https://client-api.override.molecule.invalid' in matrix_livekit_jwt_service_runtime.Config.Env" + - "'LIVEKIT_INSECURE_SKIP_VERIFY_TLS=YES_I_KNOW_WHAT_I_AM_DOING' in matrix_livekit_jwt_service_runtime.Config.Env" + - "'MOLECULE_LIVEKIT_MARKER=environment-reached' in matrix_livekit_jwt_service_runtime.Config.Env" + fail_msg: "The running container environment lost role-rendered settings" + success_msg: "The role-rendered environment reached the running container" + + - name: Assert the configured labels reached the running container + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_runtime.Config.Labels['traefik.enable'] == 'true' + - matrix_livekit_jwt_service_runtime.Config.Labels['traefik.docker.network'] == matrix_livekit_jwt_service_container_network + - matrix_livekit_jwt_service_runtime.Config.Labels['traefik.http.routers.matrix-livekit-jwt-service.priority'] == '847' + - matrix_livekit_jwt_service_runtime.Config.Labels['molecule.livekit-jwt.coverage'] == 'enabled' + - matrix_livekit_jwt_service_runtime.Config.Labels['molecule.livekit-jwt.extra-argument'] == 'reached' + fail_msg: "The running container lost role-rendered or extra-argument labels" + success_msg: "The configured labels reached the running container" + + - name: Assert the running container uses the exact image and version the role pins + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_runtime.Config.Image == matrix_livekit_jwt_service_expected_image + fail_msg: >- + The running container uses {{ matrix_livekit_jwt_service_runtime.Config.Image }}, + expected {{ matrix_livekit_jwt_service_expected_image }} + success_msg: "The running container uses the exact image and version defaults/main.yml pins" + vars: + matrix_livekit_jwt_service_expected_image: >- + {{ matrix_livekit_jwt_service_role_defaults.matrix_livekit_jwt_service_container_image_registry_prefix_upstream_default }}element-hq/lk-jwt-service:{{ matrix_livekit_jwt_service_role_defaults.matrix_livekit_jwt_service_version }} + + - name: Assert the running container identity and image command + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_runtime.Config.User == (matrix_user_uid | string) ~ ':' ~ (matrix_user_gid | string) + - matrix_livekit_jwt_service_runtime.Config.Entrypoint | default([], true) | length == 0 + - matrix_livekit_jwt_service_runtime.Config.Cmd == ['/lk-jwt-service'] + - matrix_livekit_jwt_service_runtime.HostConfig.RestartPolicy.Name == 'no' + - matrix_livekit_jwt_service_runtime.HostConfig.AutoRemove is sameas true + - matrix_livekit_jwt_service_runtime.HostConfig.LogConfig.Type == 'none' + fail_msg: "The running container has an unexpected identity, command or Docker lifecycle" + success_msg: "The running container uses the configured identity, command and Docker lifecycle" + + - name: Assert the running container security and filesystem contract + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_runtime.HostConfig.Privileged is sameas false + - matrix_livekit_jwt_service_runtime.HostConfig.CapAdd | default([], true) | length == 0 + - matrix_livekit_jwt_service_runtime.HostConfig.CapDrop == ['ALL'] + - matrix_livekit_jwt_service_runtime.HostConfig.ReadonlyRootfs is sameas false + - matrix_livekit_jwt_service_runtime.Mounts | length == 0 + - matrix_livekit_jwt_service_runtime.HostConfig.Binds | default([], true) | length == 0 + fail_msg: "The running container differs from the role's capability and mount contract" + success_msg: "The running container has all capabilities dropped and no mounts" + + - name: Assert the broken upstream healthcheck is disabled + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_runtime.Config.Healthcheck is mapping + - matrix_livekit_jwt_service_runtime.Config.Healthcheck.Test == ['NONE'] + - matrix_livekit_jwt_service_runtime.State.Health.Status is not defined + fail_msg: "The v0.6.0 image healthcheck was not disabled by the role" + success_msg: "The broken v0.6.0 image healthcheck is disabled" + + - name: Assert the running container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_runtime.HostConfig.NetworkMode == matrix_livekit_jwt_service_container_network + - matrix_livekit_jwt_service_runtime.NetworkSettings.Networks is mapping + - matrix_livekit_jwt_service_runtime.NetworkSettings.Networks | length == 1 + - matrix_livekit_jwt_service_container_network in matrix_livekit_jwt_service_runtime.NetworkSettings.Networks + fail_msg: >- + LiveKit JWT service has unexpected network attachments: + {{ matrix_livekit_jwt_service_runtime.NetworkSettings.Networks.keys() | list }} + success_msg: "The running container is attached only to its dedicated network" + + - name: Assert the observable extra runtime argument reached Docker + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_runtime.Config.Hostname == 'livekit-jwt-molecule-runtime' + fail_msg: "The configured hostname extra argument did not reach Docker" + success_msg: "The approved container extra-argument setting reached Docker" + + - name: Ask Docker for the service's published ports + ansible.builtin.command: + argv: + - docker + - container + - port + - matrix-livekit-jwt-service + register: matrix_livekit_jwt_service_published_ports + changed_when: false + failed_when: false + + - name: Assert the role publishes no host ports + ansible.builtin.assert: + that: + - matrix_livekit_jwt_service_runtime.Config.ExposedPorts.keys() | list == ['8080/tcp'] + - matrix_livekit_jwt_service_runtime.HostConfig.PortBindings | default({}, true) | length == 0 + - matrix_livekit_jwt_service_published_ports.rc == 0 + - matrix_livekit_jwt_service_published_ports.stdout | trim | length == 0 + fail_msg: >- + LiveKit JWT service unexpectedly publishes a host port: + {{ matrix_livekit_jwt_service_published_ports.stdout | default('unknown') }} + success_msg: "The role leaves the image's declared port unpublished" diff --git a/roles/custom/matrix-livekit-jwt-service/tasks/install.yml b/roles/custom/matrix-livekit-jwt-service/tasks/install.yml index 9a5271ccf..bf369b5df 100644 --- a/roles/custom/matrix-livekit-jwt-service/tasks/install.yml +++ b/roles/custom/matrix-livekit-jwt-service/tasks/install.yml @@ -29,11 +29,9 @@ register: matrix_livekit_jwt_service_support_files_result - name: Ensure LiveKit JWT Service container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_livekit_jwt_service_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_livekit_jwt_service_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_livekit_jwt_service_container_image_force_pull }}" + pull: always when: "not matrix_livekit_jwt_service_container_image_self_build | bool" register: matrix_livekit_jwt_service_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -42,6 +40,15 @@ - when: "matrix_livekit_jwt_service_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure LiveKit JWT Service repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_livekit_jwt_service_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure LiveKit JWT Service repository is present on self-build ansible.builtin.git: repo: "{{ matrix_livekit_jwt_service_container_repo }}" @@ -53,17 +60,16 @@ register: matrix_livekit_jwt_service_git_pull_results - name: Ensure LiveKit JWT Service container image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_livekit_jwt_service_container_image }}" - source: build - force_source: "{{ matrix_livekit_jwt_service_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_livekit_jwt_service_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_livekit_jwt_service_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_livekit_jwt_service_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_livekit_jwt_service_git_pull_results.changed | bool else 'never' }}" + register: matrix_livekit_jwt_service_container_image_build_result - name: Ensure LiveKit JWT Service container network is created + when: matrix_livekit_jwt_service_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_livekit_jwt_service_container_network }}" @@ -84,4 +90,5 @@ matrix_livekit_jwt_service_support_files_result.changed | default(false) or matrix_livekit_jwt_service_systemd_service_result.changed | default(false) or matrix_livekit_jwt_service_container_image_pull_result.changed | default(false) + or matrix_livekit_jwt_service_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-livekit-jwt-service/tasks/validate_config.yml b/roles/custom/matrix-livekit-jwt-service/tasks/validate_config.yml index fb44aa236..2bea8c070 100644 --- a/roles/custom/matrix-livekit-jwt-service/tasks/validate_config.yml +++ b/roles/custom/matrix-livekit-jwt-service/tasks/validate_config.yml @@ -1,6 +1,6 @@ # SPDX-FileCopyrightText: 2022 MDAD project contributors # SPDX-FileCopyrightText: 2024 wjbeckett -# SPDX-FileCopyrightText: 2024 Slavi Pantaleev +# SPDX-FileCopyrightText: 2024 - 2026 Slavi Pantaleev # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -14,6 +14,8 @@ when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - {'old': 'matrix_livekit_jwt_service_environment_variable_livekit_jwt_port', 'new': 'matrix_livekit_jwt_service_container_port'} + - {'old': 'matrix_livekit_jwt_service_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_livekit_jwt_service_container_additional_arguments', 'new': 'matrix_livekit_jwt_service_container_extra_arguments'} - name: Fail if required LiveKit JWT Service settings are not defined ansible.builtin.fail: @@ -26,3 +28,4 @@ - {'name': 'matrix_livekit_jwt_service_environment_variable_livekit_key', when: true} - {'name': 'matrix_livekit_jwt_service_environment_variable_livekit_url', when: true} - {'name': 'matrix_livekit_jwt_service_environment_variable_livekit_secret', when: true} + - {'name': 'matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers', when: true} diff --git a/roles/custom/matrix-livekit-jwt-service/templates/env.j2 b/roles/custom/matrix-livekit-jwt-service/templates/env.j2 index 15ac9d4a7..afe93b36e 100644 --- a/roles/custom/matrix-livekit-jwt-service/templates/env.j2 +++ b/roles/custom/matrix-livekit-jwt-service/templates/env.j2 @@ -13,4 +13,6 @@ LIVEKIT_SECRET={{ matrix_livekit_jwt_service_environment_variable_livekit_secret LIVEKIT_FULL_ACCESS_HOMESERVERS={{ matrix_livekit_jwt_service_environment_variable_livekit_full_access_homeservers }} +LIVEKIT_CS_API_URL_OVERRIDES={{ matrix_livekit_jwt_service_environment_variable_livekit_cs_api_url_overrides }} + {{ matrix_livekit_jwt_service_environment_variables_extension }} diff --git a/roles/custom/matrix-livekit-jwt-service/templates/systemd/matrix-livekit-jwt-service.service.j2 b/roles/custom/matrix-livekit-jwt-service/templates/systemd/matrix-livekit-jwt-service.service.j2 index 1d22b8cce..bcfcc7fd3 100644 --- a/roles/custom/matrix-livekit-jwt-service/templates/systemd/matrix-livekit-jwt-service.service.j2 +++ b/roles/custom/matrix-livekit-jwt-service/templates/systemd/matrix-livekit-jwt-service.service.j2 @@ -18,17 +18,28 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ + {% if not matrix_livekit_jwt_service_container_healthcheck_enabled %} + --no-healthcheck \ + {% endif %} --network={{ matrix_livekit_jwt_service_container_network }} \ {% if matrix_livekit_jwt_service_container_http_host_bind_port %} -p {{ matrix_livekit_jwt_service_container_http_host_bind_port }}:{{ matrix_livekit_jwt_service_container_port }} \ {% endif %} + {% for volume in matrix_livekit_jwt_service_container_additional_volumes %} + --mount type={{ volume.type | default('bind' if '/' in volume.src else 'volume') }},src={{ volume.src }},dst={{ volume.dst }}{{ (',' + volume.options) if volume.options else '' }} \ + {% endfor %} + {% for arg in matrix_livekit_jwt_service_container_extra_arguments %} + {{ arg }} \ + {% endfor %} --env-file={{ matrix_livekit_jwt_service_base_path }}/env \ --label-file={{ matrix_livekit_jwt_service_base_path }}/labels \ {{ matrix_livekit_jwt_service_container_image }} +{% if matrix_livekit_jwt_service_container_network != 'host' %} {% for network in matrix_livekit_jwt_service_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-livekit-jwt-service {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-livekit-jwt-service diff --git a/roles/custom/matrix-matrixto/defaults/main.yml b/roles/custom/matrix-matrixto/defaults/main.yml index 838b5e929..da3bf9e0d 100644 --- a/roles/custom/matrix-matrixto/defaults/main.yml +++ b/roles/custom/matrix-matrixto/defaults/main.yml @@ -97,6 +97,12 @@ matrix_matrixto_container_labels_traefik_additional_response_headers_auto: | }} matrix_matrixto_container_labels_traefik_additional_response_headers_custom: {} +# Controls whether a `com.centurylinklabs.watchtower.enable=false` label will be attached to the container. +# The label tells [Watchtower](https://containrrr.dev/watchtower/) (if in use) to skip this container. +# The container image for this service is built locally (from source), so Watchtower cannot update it +# and merely produces "digest retrieval failed" errors when it tries. +matrix_matrixto_container_labels_watchtower_skip_enabled: true + # matrix_matrixto_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # diff --git a/roles/custom/matrix-matrixto/tasks/install.yml b/roles/custom/matrix-matrixto/tasks/install.yml index feae4538e..3da68b309 100644 --- a/roles/custom/matrix-matrixto/tasks/install.yml +++ b/roles/custom/matrix-matrixto/tasks/install.yml @@ -26,29 +26,38 @@ - labels register: matrix_matrixto_support_files_result +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Matrix.to repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_matrixto_container_image_self_build_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure Matrix.to repository is present on self-build ansible.builtin.git: repo: "{{ matrix_matrixto_container_image_self_build_repo }}" version: "{{ matrix_matrixto_container_image_self_build_repo_version }}" dest: "{{ matrix_matrixto_container_image_self_build_src_files_path }}" force: "yes" + become: true + become_user: "{{ matrix_user_name }}" register: matrix_matrixto_git_pull_results - name: Ensure Matrix.to container image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_matrixto_container_image_self_build_name }}" - source: build - force_source: "{{ matrix_matrixto_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_matrixto_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_matrixto_container_image_self_build_src_files_path }}" - pull: true - args: + dockerfile: Dockerfile + path: "{{ matrix_matrixto_container_image_self_build_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_matrixto_git_pull_results.changed | bool else 'never' }}" register: matrix_matrixto_container_image_build_result - name: Ensure Matrix.to container network is created via community.docker.docker_network - when: devture_systemd_docker_base_container_network_creation_method == 'ansible-module' + when: + - devture_systemd_docker_base_container_network_creation_method == 'ansible-module' + - matrix_matrixto_container_network != 'host' community.docker.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_matrixto_container_network }}" @@ -56,7 +65,9 @@ driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - name: Ensure Matrix.to container network is created via ansible.builtin.command - when: devture_systemd_docker_base_container_network_creation_method == 'command' + when: + - devture_systemd_docker_base_container_network_creation_method == 'command' + - matrix_matrixto_container_network != 'host' ansible.builtin.command: cmd: >- {{ devture_systemd_docker_base_host_command_docker }} network create diff --git a/roles/custom/matrix-matrixto/tasks/validate_config.yml b/roles/custom/matrix-matrixto/tasks/validate_config.yml index f7d807d18..c82e7253c 100644 --- a/roles/custom/matrix-matrixto/tasks/validate_config.yml +++ b/roles/custom/matrix-matrixto/tasks/validate_config.yml @@ -41,3 +41,11 @@ msg: >- matrix_matrixto_container_labels_traefik_path_prefix (`{{ matrix_matrixto_container_labels_traefik_path_prefix }}`) must either be `/` or not end with a slash (e.g. `/matrixto`). when: "matrix_matrixto_container_labels_traefik_path_prefix != '/' and matrix_matrixto_container_labels_traefik_path_prefix[-1] == '/'" + +- name: (Deprecation) Catch and report renamed Matrix.to variables + ansible.builtin.fail: + msg: >- + The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_matrixto_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-matrixto/templates/labels.j2 b/roles/custom/matrix-matrixto/templates/labels.j2 index 54c45a4b6..ee9567754 100644 --- a/roles/custom/matrix-matrixto/templates/labels.j2 +++ b/roles/custom/matrix-matrixto/templates/labels.j2 @@ -56,4 +56,8 @@ traefik.http.routers.{{ matrix_matrixto_identifier }}.tls.certResolver={{ matrix traefik.http.services.{{ matrix_matrixto_identifier }}.loadbalancer.server.port={{ matrix_matrixto_container_http_port }} {% endif %} +{% if matrix_matrixto_container_labels_watchtower_skip_enabled %} +com.centurylinklabs.watchtower.enable=false +{% endif %} + {{ matrix_matrixto_container_labels_additional_labels }} diff --git a/roles/custom/matrix-matrixto/templates/systemd/matrix-matrixto.service.j2 b/roles/custom/matrix-matrixto/templates/systemd/matrix-matrixto.service.j2 index 4d02857a5..a3849f9eb 100644 --- a/roles/custom/matrix-matrixto/templates/systemd/matrix-matrixto.service.j2 +++ b/roles/custom/matrix-matrixto/templates/systemd/matrix-matrixto.service.j2 @@ -42,9 +42,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_matrixto_container_image_self_build_name }} +{% if matrix_matrixto_container_network != 'host' %} {% for network in matrix_matrixto_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_matrixto_identifier }} {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_matrixto_identifier }} diff --git a/roles/custom/matrix-media-repo/defaults/main.yml b/roles/custom/matrix-media-repo/defaults/main.yml index 32456aee5..991f92f78 100755 --- a/roles/custom/matrix-media-repo/defaults/main.yml +++ b/roles/custom/matrix-media-repo/defaults/main.yml @@ -30,7 +30,6 @@ matrix_media_repo_container_image_registry_prefix_upstream: "{{ matrix_media_rep matrix_media_repo_container_image_registry_prefix_upstream_default: "ghcr.io/" # renovate: datasource=docker depName=ghcr.io/t2bot/matrix-media-repo matrix_media_repo_container_image_tag: "v1.3.8" -matrix_media_repo_container_image_force_pull: "{{ matrix_media_repo_container_image.endswith(':latest') }}" matrix_media_repo_base_path: "{{ matrix_base_data_path }}/{{ matrix_media_repo_identifier }}" matrix_media_repo_config_path: "{{ matrix_media_repo_base_path }}/config" @@ -414,6 +413,14 @@ matrix_media_repo_shared_secret_auth_token: "PutSomeRandomSecureValueHere" # thumbnails and other misc data is also stored in these places. The media repo, when looking # for a datastore to use, will always use the smallest datastore first. +# Controls whether the file datastore is defined in the configuration at all. +# A datastore can be defined but disabled for uploads (making it readonly) by keeping this enabled +# while setting `matrix_media_repo_datastore_file_for_kinds: []`. This is useful when migrating +# media to another datastore, as previously stored media remains readable. +# By default, the datastore is defined whenever some kinds are assigned to it, matching the +# previous behavior of this role. +matrix_media_repo_datastore_file_enabled: "{{ (matrix_media_repo_datastore_file_for_kinds | length) > 0 }}" + # ID for the file datastore. Any unique alphanumeric string (e.g. generated via `pwgen -s 64 1`). # This value CANNOT be changed after media has been stored — matrix-media-repo ties media to this ID. matrix_media_repo_datastore_file_id: "" @@ -435,6 +442,14 @@ matrix_media_repo_datastore_file_for_kinds: ["thumbnails", "remote_media", "loca # Path to datastore, relative to matrix-media-repo directory root matrix_media_repo_datastore_opts_path: "/data/media" +# Controls whether the S3 datastore is defined in the configuration at all. +# A datastore can be defined but disabled for uploads (making it readonly) by keeping this enabled +# while setting `matrix_media_repo_datastore_s3_for_kinds: []`. This is useful when migrating +# media to another datastore, as previously stored media remains readable. +# By default, the datastore is defined whenever some kinds are assigned to it, matching the +# previous behavior of this role. +matrix_media_repo_datastore_s3_enabled: "{{ (matrix_media_repo_datastore_s3_for_kinds | length) > 0 }}" + # ID for the S3 datastore. Any unique alphanumeric string (e.g. generated via `pwgen -s 64 1`). # This value CANNOT be changed after media has been stored — matrix-media-repo ties media to this ID. matrix_media_repo_datastore_s3_id: "" diff --git a/roles/custom/matrix-media-repo/tasks/setup_install.yml b/roles/custom/matrix-media-repo/tasks/setup_install.yml index 24ed9760b..43155e687 100755 --- a/roles/custom/matrix-media-repo/tasks/setup_install.yml +++ b/roles/custom/matrix-media-repo/tasks/setup_install.yml @@ -47,11 +47,9 @@ register: matrix_media_repo_config_result - name: Ensure media-repo Docker image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_media_repo_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_media_repo_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_media_repo_container_image_force_pull }}" + pull: always when: "not matrix_media_repo_container_image_self_build | bool" register: matrix_media_repo_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -60,6 +58,15 @@ - when: "matrix_media_repo_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure media-repo repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_media_repo_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure media-repo repository is present on self-build ansible.builtin.git: repo: "{{ matrix_media_repo_container_image_self_build_repo }}" @@ -144,6 +151,7 @@ removes: "{{ matrix_media_repo_config_path }}/{{ matrix_media_repo_identifier }}.signing.key.TEMP" - name: Ensure media-repo container network is created + when: matrix_media_repo_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_media_repo_container_network }}" diff --git a/roles/custom/matrix-media-repo/tasks/validate_config.yml b/roles/custom/matrix-media-repo/tasks/validate_config.yml index c4af44d07..6884d9bcb 100644 --- a/roles/custom/matrix-media-repo/tasks/validate_config.yml +++ b/roles/custom/matrix-media-repo/tasks/validate_config.yml @@ -39,6 +39,7 @@ - {'old': 'matrix_media_repo_docker_image_registry_prefix_upstream_default', 'new': 'matrix_media_repo_container_image_registry_prefix_upstream_default'} - {'old': 'matrix_media_repo_docker_image_tag', 'new': 'matrix_media_repo_container_image_tag'} - {'old': 'matrix_media_repo_docker_src_files_path', 'new': 'matrix_media_repo_container_src_files_path'} + - {'old': 'matrix_media_repo_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required matrix-media-repo settings not defined ansible.builtin.fail: @@ -49,5 +50,5 @@ - {'name': 'matrix_media_repo_database_hostname', when: true} - {'name': 'matrix_media_repo_container_labels_traefik_internal_media_entrypoints', when: "{{ matrix_media_repo_container_labels_traefik_internal_media_enabled }}"} - {'name': 'matrix_media_repo_container_labels_traefik_internal_matrix_client_media_entrypoints', when: "{{ matrix_media_repo_container_labels_traefik_internal_matrix_client_media_enabled }}"} - - {'name': 'matrix_media_repo_datastore_file_id', when: "{{ (matrix_media_repo_datastore_file_for_kinds | length) > 0 }}"} - - {'name': 'matrix_media_repo_datastore_s3_id', when: "{{ (matrix_media_repo_datastore_s3_for_kinds | length) > 0 }}"} + - {'name': 'matrix_media_repo_datastore_file_id', when: "{{ matrix_media_repo_datastore_file_enabled }}"} + - {'name': 'matrix_media_repo_datastore_s3_id', when: "{{ matrix_media_repo_datastore_s3_enabled }}"} diff --git a/roles/custom/matrix-media-repo/templates/media-repo/media-repo.yaml.j2 b/roles/custom/matrix-media-repo/templates/media-repo/media-repo.yaml.j2 index fa60434fa..50c54d60c 100644 --- a/roles/custom/matrix-media-repo/templates/media-repo/media-repo.yaml.j2 +++ b/roles/custom/matrix-media-repo/templates/media-repo/media-repo.yaml.j2 @@ -198,7 +198,7 @@ sharedSecretAuth: # thumbnails and other misc data is also stored in these places. The media repo, when looking # for a datastore to use, will always use the smallest datastore first. datastores: -{% if (matrix_media_repo_datastore_file_for_kinds | length) > 0 %} +{% if matrix_media_repo_datastore_file_enabled %} - type: file # ID for this datastore (cannot change). Alphanumeric recommended. id: {{ matrix_media_repo_datastore_file_id | to_json }} @@ -218,7 +218,7 @@ datastores: opts: path: {{ matrix_media_repo_datastore_opts_path | to_json }} {% endif %} -{% if (matrix_media_repo_datastore_s3_for_kinds | length) > 0 %} +{% if matrix_media_repo_datastore_s3_enabled %} - type: s3 # ID for this datastore (cannot change). Alphanumeric recommended. id: {{ matrix_media_repo_datastore_s3_id | to_json }} diff --git a/roles/custom/matrix-media-repo/templates/media-repo/systemd/matrix-media-repo.service.j2 b/roles/custom/matrix-media-repo/templates/media-repo/systemd/matrix-media-repo.service.j2 index 8260d0bdd..cf0c605d4 100755 --- a/roles/custom/matrix-media-repo/templates/media-repo/systemd/matrix-media-repo.service.j2 +++ b/roles/custom/matrix-media-repo/templates/media-repo/systemd/matrix-media-repo.service.j2 @@ -40,9 +40,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_media_repo_container_image }} +{% if matrix_media_repo_container_network != 'host' %} {% for network in matrix_media_repo_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_media_repo_identifier }} {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_media_repo_identifier }} diff --git a/roles/custom/matrix-pantalaimon/defaults/main.yml b/roles/custom/matrix-pantalaimon/defaults/main.yml index a218fbd3c..4ff97c4d7 100644 --- a/roles/custom/matrix-pantalaimon/defaults/main.yml +++ b/roles/custom/matrix-pantalaimon/defaults/main.yml @@ -19,7 +19,6 @@ matrix_pantalaimon_container_image: "{{ matrix_pantalaimon_container_image_regis matrix_pantalaimon_container_image_registry_prefix: "{{ 'localhost/' if matrix_pantalaimon_container_image_self_build else matrix_pantalaimon_container_image_registry_prefix_upstream }}" matrix_pantalaimon_container_image_registry_prefix_upstream: "{{ matrix_pantalaimon_container_image_registry_prefix_upstream_default }}" matrix_pantalaimon_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_pantalaimon_container_image_force_pull: "{{ matrix_pantalaimon_container_image.endswith(':latest') }}" matrix_pantalaimon_base_path: "{{ matrix_base_data_path }}/pantalaimon" matrix_pantalaimon_data_path: "{{ matrix_pantalaimon_base_path }}/data" diff --git a/roles/custom/matrix-pantalaimon/tasks/install.yml b/roles/custom/matrix-pantalaimon/tasks/install.yml index 2c735c57b..618a22d5e 100644 --- a/roles/custom/matrix-pantalaimon/tasks/install.yml +++ b/roles/custom/matrix-pantalaimon/tasks/install.yml @@ -28,17 +28,25 @@ register: matrix_pantalaimon_config_result - name: Ensure pantalaimon container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_pantalaimon_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_pantalaimon_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_pantalaimon_container_image_force_pull }}" + pull: always when: "not matrix_pantalaimon_container_image_self_build | bool" register: matrix_pantalaimon_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_pantalaimon_container_image_pull_result is not failed +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure pantalaimon repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_pantalaimon_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_pantalaimon_container_image_self_build | bool" + - name: Ensure pantalaimon repository is present on self-build ansible.builtin.git: repo: "{{ matrix_pantalaimon_container_image_self_build_repo }}" @@ -51,17 +59,17 @@ when: "matrix_pantalaimon_container_image_self_build | bool" - name: Ensure pantalaimon container image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_pantalaimon_container_image }}" - source: build - force_source: "{{ matrix_pantalaimon_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_pantalaimon_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_pantalaimon_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_pantalaimon_git_pull_results.changed | bool else 'never' }}" when: "matrix_pantalaimon_container_image_self_build | bool" + register: matrix_pantalaimon_container_image_build_result - name: Ensure pantalaimon container network is created + when: matrix_pantalaimon_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_pantalaimon_container_network }}" @@ -82,4 +90,5 @@ matrix_pantalaimon_config_result.changed | default(false) or matrix_pantalaimon_systemd_service_result.changed | default(false) or matrix_pantalaimon_container_image_pull_result.changed | default(false) + or matrix_pantalaimon_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-pantalaimon/tasks/validate_config.yml b/roles/custom/matrix-pantalaimon/tasks/validate_config.yml index 4a2a85c14..129e4e0d6 100644 --- a/roles/custom/matrix-pantalaimon/tasks/validate_config.yml +++ b/roles/custom/matrix-pantalaimon/tasks/validate_config.yml @@ -16,6 +16,7 @@ - {'old': 'matrix_pantalaimon_docker_image_registry_prefix', 'new': 'matrix_pantalaimon_container_image_registry_prefix'} - {'old': 'matrix_pantalaimon_docker_image_registry_prefix_upstream', 'new': 'matrix_pantalaimon_container_image_registry_prefix_upstream'} - {'old': 'matrix_pantalaimon_docker_image_registry_prefix_upstream_default', 'new': 'matrix_pantalaimon_container_image_registry_prefix_upstream_default'} + - {'old': 'matrix_pantalaimon_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required Pantalaimon variables are undefined ansible.builtin.fail: diff --git a/roles/custom/matrix-pantalaimon/templates/systemd/matrix-pantalaimon.service.j2 b/roles/custom/matrix-pantalaimon/templates/systemd/matrix-pantalaimon.service.j2 index fb7d02c41..85fbe9d29 100644 --- a/roles/custom/matrix-pantalaimon/templates/systemd/matrix-pantalaimon.service.j2 +++ b/roles/custom/matrix-pantalaimon/templates/systemd/matrix-pantalaimon.service.j2 @@ -30,9 +30,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_pantalaimon_container_image }} +{% if matrix_pantalaimon_container_network != 'host' %} {% for network in matrix_pantalaimon_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-pantalaimon {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-pantalaimon diff --git a/roles/custom/matrix-prometheus-services-connect/defaults/main.yml b/roles/custom/matrix-prometheus-services-connect/defaults/main.yml index ccbaefdb8..118b22c69 100644 --- a/roles/custom/matrix-prometheus-services-connect/defaults/main.yml +++ b/roles/custom/matrix-prometheus-services-connect/defaults/main.yml @@ -72,6 +72,7 @@ matrix_prometheus_services_connect_scraper_synapse_workers_enabled: "{{ matrix_p matrix_prometheus_services_connect_scraper_synapse_workers_enabled_list: [] +# No {# #} comments inside the block below: indented, they leak whitespace and corrupt the YAML. matrix_prometheus_services_connect_scraper_synapse_workers_static_configs_as_yaml: | {% for worker in matrix_prometheus_services_connect_scraper_synapse_workers_enabled_list %} {% if worker.metrics_port != 0 %} @@ -79,6 +80,7 @@ matrix_prometheus_services_connect_scraper_synapse_workers_static_configs_as_yam labels: instance: {{ matrix_prometheus_services_connect_scraper_synapse_workers_static_configs_instance | to_json }} worker_id: {{ worker.id | to_json }} + index: {{ worker.id | regex_search('[0-9]+') | to_json }} job: {{ worker.type | to_json }} app: {{ worker.app | to_json }} {% endif %} @@ -86,7 +88,7 @@ matrix_prometheus_services_connect_scraper_synapse_workers_static_configs_as_yam matrix_prometheus_services_connect_scraper_synapse_workers_static_configs_instance: "{{ matrix_domain }}" -matrix_prometheus_services_connect_scraper_synapse_workers_static_configs: "{{ [] if matrix_prometheus_services_connect_scraper_synapse_workers_enabled_list | length == 0 else matrix_prometheus_services_connect_scraper_synapse_workers_static_configs_as_yaml | from_yaml }}" +matrix_prometheus_services_connect_scraper_synapse_workers_static_configs: "{{ [] if matrix_prometheus_services_connect_scraper_synapse_workers_enabled_list | length == 0 else matrix_prometheus_services_connect_scraper_synapse_workers_static_configs_as_yaml | from_yaml or [] }}" # Controls whether Postgres (postgres-exporter) shall be scraped matrix_prometheus_services_connect_scraper_postgres_enabled: false @@ -187,3 +189,23 @@ matrix_prometheus_services_connect_scraper_synapse_usage_exporter_scrape_configs 'static_configs': matrix_prometheus_services_connect_scraper_synapse_usage_exporter_static_configs, }] }} + +# Controls whether ntfy shall be scraped +matrix_prometheus_services_connect_scraper_ntfy_enabled: false +matrix_prometheus_services_connect_scraper_ntfy_job_name: ntfy +matrix_prometheus_services_connect_scraper_ntfy_metrics_path: /metrics +matrix_prometheus_services_connect_scraper_ntfy_scrape_interval: 15s +matrix_prometheus_services_connect_scraper_ntfy_scrape_timeout: 15s +matrix_prometheus_services_connect_scraper_ntfy_static_configs: "{{ [{'targets': [matrix_prometheus_services_connect_scraper_ntfy_static_configs_target]}] }}" +matrix_prometheus_services_connect_scraper_ntfy_static_configs_target: '' +# The final scrape config for the ntfy scraper +matrix_prometheus_services_connect_scraper_ntfy_scrape_configs: | + {{ + [{ + 'job_name': matrix_prometheus_services_connect_scraper_ntfy_job_name, + 'metrics_path': matrix_prometheus_services_connect_scraper_ntfy_metrics_path, + 'scrape_interval': matrix_prometheus_services_connect_scraper_ntfy_scrape_interval, + 'scrape_timeout': matrix_prometheus_services_connect_scraper_ntfy_scrape_timeout, + 'static_configs': matrix_prometheus_services_connect_scraper_ntfy_static_configs, + }] + }} diff --git a/roles/custom/matrix-rageshake/defaults/main.yml b/roles/custom/matrix-rageshake/defaults/main.yml index 308f4d875..ce1e78b25 100644 --- a/roles/custom/matrix-rageshake/defaults/main.yml +++ b/roles/custom/matrix-rageshake/defaults/main.yml @@ -24,7 +24,7 @@ matrix_rageshake_path_prefix: / # There are no stable container image tags yet. # See: https://github.com/matrix-org/rageshake/issues/69 # renovate: datasource=docker depName=ghcr.io/matrix-org/rageshake -matrix_rageshake_version: 1.17.1 +matrix_rageshake_version: 1.18.0 matrix_rageshake_base_path: "{{ matrix_base_data_path }}/rageshake" matrix_rageshake_config_path: "{{ matrix_rageshake_base_path }}/config" @@ -35,7 +35,6 @@ matrix_rageshake_container_image: "{{ matrix_rageshake_container_image_registry_ matrix_rageshake_container_image_registry_prefix: "{{ 'localhost/' if matrix_rageshake_container_image_self_build else matrix_rageshake_container_image_registry_prefix_upstream }}" matrix_rageshake_container_image_registry_prefix_upstream: "{{ matrix_rageshake_container_image_registry_prefix_upstream_default }}" matrix_rageshake_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_rageshake_container_image_force_pull: "{{ matrix_rageshake_container_image.endswith(':master') }}" matrix_rageshake_container_image_tag: "{{ matrix_rageshake_version }}" matrix_rageshake_container_image_self_build: false diff --git a/roles/custom/matrix-rageshake/tasks/install.yml b/roles/custom/matrix-rageshake/tasks/install.yml index c25142bbf..31e5fdcba 100644 --- a/roles/custom/matrix-rageshake/tasks/install.yml +++ b/roles/custom/matrix-rageshake/tasks/install.yml @@ -42,17 +42,25 @@ register: matrix_rageshake_support_files_result - name: Ensure rageshake image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_rageshake_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_rageshake_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_rageshake_container_image_force_pull }}" + pull: always when: "not matrix_rageshake_container_image_self_build | bool" register: matrix_rageshake_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_rageshake_container_image_pull_result is not failed +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure rageshake repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_rageshake_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_rageshake_container_image_self_build | bool" + - name: Ensure rageshake repository is present on self-build ansible.builtin.git: repo: "{{ matrix_rageshake_container_image_self_build_repo }}" @@ -75,6 +83,7 @@ when: matrix_rageshake_container_image_self_build | bool - name: Ensure rageshake container network is created + when: matrix_rageshake_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_rageshake_container_network }}" diff --git a/roles/custom/matrix-rageshake/tasks/validate_config.yml b/roles/custom/matrix-rageshake/tasks/validate_config.yml index 19edb6197..64cb9c358 100644 --- a/roles/custom/matrix-rageshake/tasks/validate_config.yml +++ b/roles/custom/matrix-rageshake/tasks/validate_config.yml @@ -22,6 +22,7 @@ when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - {'old': 'matrix_rageshake_docker_image_name_prefix', 'new': 'matrix_rageshake_docker_image_registry_prefix'} + - {'old': 'matrix_rageshake_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - when: matrix_rageshake_container_labels_traefik_enabled | bool block: diff --git a/roles/custom/matrix-rageshake/templates/systemd/matrix-rageshake.service.j2 b/roles/custom/matrix-rageshake/templates/systemd/matrix-rageshake.service.j2 index 68a0e9984..a90ecdb1e 100644 --- a/roles/custom/matrix-rageshake/templates/systemd/matrix-rageshake.service.j2 +++ b/roles/custom/matrix-rageshake/templates/systemd/matrix-rageshake.service.j2 @@ -34,9 +34,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {{ matrix_rageshake_container_image }} \ --config /config/config.yaml +{% if matrix_rageshake_container_network != 'host' %} {% for network in matrix_rageshake_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-rageshake {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-rageshake diff --git a/roles/custom/matrix-registration/defaults/main.yml b/roles/custom/matrix-registration/defaults/main.yml deleted file mode 100644 index 22a7ccff5..000000000 --- a/roles/custom/matrix-registration/defaults/main.yml +++ /dev/null @@ -1,179 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2025 Slavi Pantaleev -# SPDX-FileCopyrightText: 2021 Aaron Raimist -# SPDX-FileCopyrightText: 2021 Ahmad Haghighi -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# SPDX-FileCopyrightText: 2022 Nikita Chernyi -# SPDX-FileCopyrightText: 2023 Samuel Meenzen -# SPDX-FileCopyrightText: 2024 Suguru Hirahara -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- -# matrix-registration is a simple python application to have a token based Matrix registration -# See: https://zeratax.github.io/matrix-registration/ -# Project source code URL: https://github.com/ZerataX/matrix-registration - -matrix_registration_enabled: true - -matrix_registration_scheme: https -matrix_registration_hostname: '' -matrix_registration_path_prefix: / - -matrix_registration_container_image_self_build: false -matrix_registration_container_image_self_build_repo: "https://github.com/ZerataX/matrix-registration" -matrix_registration_container_image_self_build_branch: "{{ 'master' if matrix_registration_version == 'latest' else matrix_registration_version }}" -# Controls whether we'll be patching the dependencies in `setup.py` when self-building. -# Without patching, building will likely fail, because of the poor unbounded way dependencies are defined (e.g. `flask-limiter>=1.1.0`). -# This is an attempt to get matrix-registration in its current (outdated) version to build. -matrix_registration_container_image_self_build_python_dependencies_patch_enabled: true - -matrix_registration_base_path: "{{ matrix_base_data_path }}/matrix-registration" -matrix_registration_config_path: "{{ matrix_registration_base_path }}/config" -matrix_registration_data_path: "{{ matrix_registration_base_path }}/data" -matrix_registration_container_src_files_path: "{{ matrix_registration_base_path }}/docker-src" - -# renovate: datasource=docker depName=zeratax/matrix-registration -matrix_registration_version: "v0.7.2" - -matrix_registration_container_image: "{{ matrix_registration_container_image_registry_prefix }}zeratax/matrix-registration:{{ matrix_registration_version }}" -matrix_registration_container_image_registry_prefix: "{{ 'localhost/' if matrix_registration_container_image_self_build else matrix_registration_container_image_registry_prefix_upstream }}" -matrix_registration_container_image_registry_prefix_upstream: "{{ matrix_registration_container_image_registry_prefix_upstream_default }}" -matrix_registration_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_registration_container_image_force_pull: "{{ matrix_registration_container_image.endswith(':latest') }}" - -matrix_registration_container_network: "" - -matrix_registration_container_additional_networks: "{{ matrix_registration_container_additional_networks_auto + matrix_registration_container_additional_networks_custom }}" -matrix_registration_container_additional_networks_auto: [] -matrix_registration_container_additional_networks_custom: [] - -# matrix_registration_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. -# See `../templates/labels.j2` for details. -# -# To inject your own other container labels, see `matrix_registration_container_labels_additional_labels`. -matrix_registration_container_labels_traefik_enabled: true -matrix_registration_container_labels_traefik_docker_network: "{{ matrix_registration_container_network }}" -matrix_registration_container_labels_traefik_entrypoints: web-secure -matrix_registration_container_labels_traefik_tls_certResolver: default # noqa var-naming - -# Controls whether labels will be added that expose matrix-registration's public endpoints -matrix_registration_container_labels_public_endpoint_enabled: true -matrix_registration_container_labels_public_endpoint_traefik_rule: "Host(`{{ matrix_registration_hostname }}`){% if matrix_registration_path_prefix != '/' %} && PathPrefix(`{{ matrix_registration_path_prefix }}`){% endif %}" -matrix_registration_container_labels_public_endpoint_traefik_priority: 0 -matrix_registration_container_labels_public_endpoint_traefik_entrypoints: "{{ matrix_registration_container_labels_traefik_entrypoints }}" -matrix_registration_container_labels_public_endpoint_traefik_tls: "{{ matrix_registration_container_labels_public_endpoint_traefik_entrypoints != 'web' }}" -matrix_registration_container_labels_public_endpoint_traefik_tls_certResolver: "{{ matrix_registration_container_labels_traefik_tls_certResolver }}" # noqa var-naming - -# matrix_registration_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. -# See `../templates/labels.j2` for details. -# -# Example: -# matrix_registration_container_labels_additional_labels: | -# my.label=1 -# another.label="here" -matrix_registration_container_labels_additional_labels: '' - -# A list of extra arguments to pass to the container -matrix_registration_container_extra_arguments: [] - -# List of systemd services that matrix-registration.service depends on -matrix_registration_systemd_required_services_list: "{{ matrix_registration_systemd_required_services_list_default + matrix_registration_systemd_required_services_list_auto + matrix_registration_systemd_required_services_list_custom }}" -matrix_registration_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" -matrix_registration_systemd_required_services_list_auto: [] -matrix_registration_systemd_required_services_list_custom: [] - -# List of systemd services that matrix-registration.service wants -matrix_registration_systemd_wanted_services_list: [] - -# Controls whether the matrix-registration container exposes its HTTP port (tcp/5000 in the container). -# -# Takes an "<ip>:<port>" or "<port>" value (e.g. "127.0.0.1:8767"), or empty string to not expose. -matrix_registration_container_http_host_bind_port: '' - -# Database-related configuration fields. -# -# To use SQLite, stick to these defaults. -# -# To use Postgres: -# - change the engine (`matrix_registration_database_engine: 'postgres'`) -# - adjust your database credentials via the `matrix_registration_database_*` variables -matrix_registration_database_engine: 'sqlite' - -matrix_registration_sqlite_database_path_local: "{{ matrix_registration_data_path }}/db.sqlite3" -matrix_registration_sqlite_database_path_in_container: "/data/db.sqlite3" - -matrix_registration_database_username: 'matrix_registration' -matrix_registration_database_password: 'some-password' -matrix_registration_database_hostname: '' -matrix_registration_database_port: 5432 -matrix_registration_database_name: 'matrix_registration' - -matrix_registration_database_connection_string: 'postgresql://{{ matrix_registration_database_username }}:{{ matrix_registration_database_password }}@{{ matrix_registration_database_hostname }}:{{ matrix_registration_database_port }}/{{ matrix_registration_database_name }}' - -# For some reason, matrix-registraiton expects the `db` field to be like this: `sqlite:////data/db.sqlite3`. -# (seems like one too many slashes, but..) -matrix_registration_db: "{{ - { - 'sqlite': ('sqlite:///' + matrix_registration_sqlite_database_path_in_container), - 'postgres': matrix_registration_database_connection_string, - }[matrix_registration_database_engine] -}}" - -matrix_registration_base_url: "{{ matrix_registration_path_prefix }}" - -matrix_registration_api_register_endpoint: "{{ matrix_registration_scheme }}://{{ matrix_registration_hostname }}{{ matrix_registration_base_url }}{{ '' if matrix_registration_base_url == '/' else '/' }}register" -matrix_registration_api_token_endpoint: "{{ matrix_registration_scheme }}://{{ matrix_registration_hostname }}{{ matrix_registration_base_url }}{{ '' if matrix_registration_base_url == '/' else '/' }}token" - -matrix_registration_api_validate_certs: true - -# The URL to your homeserver (e.g.: `https://matrix.example.com`). -# A local (in-container address) is preferable. -matrix_registration_server_location: "" - -matrix_registration_server_name: "{{ matrix_domain }}" - -# matrix_registration_shared_secret needs to match the homeserver's registration secret. -# For Synapse, that's the `registration_shared_secret` setting. -matrix_registration_shared_secret: "" - -# matrix_registration_admin_secret is your own admin secret for using matrix-registration (creating new tokens, etc.) -matrix_registration_admin_secret: "" - -matrix_registration_riot_instance: "https://element.io/app/" - -# Default matrix-registration configuration template which covers the generic use case. -# You can customize it by controlling the various variables inside it. -# -# For a more advanced customization, you can extend the default (see `matrix_registration_configuration_extension_yaml`) -# or completely replace this variable with your own template. -matrix_registration_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}" - -matrix_registration_configuration_extension_yaml: | - # Your custom YAML configuration for registration goes here. - # This configuration extends the default starting configuration (`matrix_registration_configuration_yaml`). - # - # You can override individual variables from the default configuration, or introduce new ones. - # - # If you need something more special, you can take full control by - # completely redefining `matrix_registration_configuration_yaml`. - # - # Example configuration extension follows: - # - # password: - # min_length: 12 - -matrix_registration_configuration_extension: "{{ matrix_registration_configuration_extension_yaml | from_yaml if matrix_registration_configuration_extension_yaml | from_yaml is mapping else {} }}" - -# Holds the final matrix-registration configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_registration_configuration_yaml`. -matrix_registration_configuration: "{{ matrix_registration_configuration_yaml | from_yaml | combine(matrix_registration_configuration_extension, recursive=True) }}" - -# matrix_registration_restart_necessary controls whether the service -# will be restarted (when true) or merely started (when false) by the -# systemd service manager role (when conditional restart is enabled). -# -# This value is automatically computed during installation based on whether -# any configuration files, the systemd service file, or the container image changed. -# The default of `false` means "no restart needed" — appropriate when the role's -# installation tasks haven't run (e.g., due to --tags skipping them). -matrix_registration_restart_necessary: false diff --git a/roles/custom/matrix-registration/tasks/generate_token.yml b/roles/custom/matrix-registration/tasks/generate_token.yml deleted file mode 100644 index 0a3e47258..000000000 --- a/roles/custom/matrix-registration/tasks/generate_token.yml +++ /dev/null @@ -1,57 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2022 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Fail if playbook called incorrectly - ansible.builtin.fail: - msg: "The `one_time` variable needs to be provided to this playbook, via --extra-vars" - when: "one_time is not defined or one_time not in ['yes', 'no']" - -- name: Fail if playbook called incorrectly - ansible.builtin.fail: - msg: "The `ex_date` variable (expiration date) needs to be provided to this playbook, via --extra-vars" - when: "ex_date is not defined or ex_date == '<date>'" - -- name: Call matrix-registration token creation API - ansible.builtin.uri: - url: "{{ matrix_registration_api_token_endpoint }}" - follow_redirects: none - validate_certs: "{{ matrix_registration_api_validate_certs }}" - headers: - Content-Type: application/json - Authorization: "SharedSecret {{ matrix_registration_admin_secret }}" - method: POST - body_format: json - body: | - { - "one_time": {{ 'true' if one_time == 'yes' else 'false' }}, - "ex_date": {{ ex_date | to_json }} - } - check_mode: false - register: matrix_registration_api_result - -- ansible.builtin.set_fact: - matrix_registration_api_result_message: >- - matrix-registration result: - - Direct registration link (with the token prefilled): - - {{ matrix_registration_api_register_endpoint }}?token={{ matrix_registration_api_result.json.name }} - - Full token details are: - - {{ matrix_registration_api_result.json }} - check_mode: false - -- name: Inject result message into devture_playbook_runtime_messages_list - ansible.builtin.set_fact: - devture_playbook_runtime_messages_list: | - {{ - devture_playbook_runtime_messages_list | default([]) - + - [matrix_registration_api_result_message] - }} - check_mode: false diff --git a/roles/custom/matrix-registration/tasks/list_tokens.yml b/roles/custom/matrix-registration/tasks/list_tokens.yml deleted file mode 100644 index f5c85a04d..000000000 --- a/roles/custom/matrix-registration/tasks/list_tokens.yml +++ /dev/null @@ -1,37 +0,0 @@ -# SPDX-FileCopyrightText: 2021 MDAD project contributors -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# SPDX-FileCopyrightText: 2022 Slavi Pantaleev -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Call matrix-registration list all tokens API - ansible.builtin.uri: - url: "{{ matrix_registration_api_token_endpoint }}" - follow_redirects: none - validate_certs: "{{ matrix_registration_api_validate_certs }}" - headers: - Content-Type: application/json - Authorization: "SharedSecret {{ matrix_registration_admin_secret }}" - method: GET - body_format: json - check_mode: false - register: matrix_registration_api_result - -- ansible.builtin.set_fact: - matrix_registration_api_result_message: >- - matrix-registration result: - - {{ matrix_registration_api_result.json | to_nice_json }} - check_mode: false - -- name: Inject result message into devture_playbook_runtime_messages_list - ansible.builtin.set_fact: - devture_playbook_runtime_messages_list: | - {{ - devture_playbook_runtime_messages_list | default([]) - + - [matrix_registration_api_result_message] - }} - check_mode: false diff --git a/roles/custom/matrix-registration/tasks/main.yml b/roles/custom/matrix-registration/tasks/main.yml deleted file mode 100644 index dcae5528e..000000000 --- a/roles/custom/matrix-registration/tasks/main.yml +++ /dev/null @@ -1,38 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2021 MDAD project contributors -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- tags: - - setup-all - - setup-matrix-registration - - install-all - - install-matrix-registration - block: - - when: matrix_registration_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" - - - when: matrix_registration_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml" - -- tags: - - setup-all - - setup-matrix-registration - block: - - when: not matrix_registration_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml" - -- tags: - - generate-matrix-registration-token - block: - - when: matrix_registration_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/generate_token.yml" - -- tags: - - list-matrix-registration-tokens - block: - - when: matrix_registration_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/list_tokens.yml" diff --git a/roles/custom/matrix-registration/tasks/setup_install.yml b/roles/custom/matrix-registration/tasks/setup_install.yml deleted file mode 100644 index 8f6b2c166..000000000 --- a/roles/custom/matrix-registration/tasks/setup_install.yml +++ /dev/null @@ -1,152 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2020 Stuart Mumford -# SPDX-FileCopyrightText: 2022 Jim Myhrberg -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# SPDX-FileCopyrightText: 2022 Nikita Chernyi -# SPDX-FileCopyrightText: 2022 Sebastian Gumprich -# SPDX-FileCopyrightText: 2024 David Mehren -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- ansible.builtin.set_fact: - matrix_registration_migration_requires_restart: false - -- when: "matrix_registration_database_engine == 'postgres'" - block: - - name: Check if an SQLite database already exists - ansible.builtin.stat: - path: "{{ matrix_registration_sqlite_database_path_local }}" - register: matrix_registration_sqlite_database_path_local_stat_result - - - when: "matrix_registration_sqlite_database_path_local_stat_result.stat.exists | bool" - block: - - ansible.builtin.include_role: - name: galaxy/postgres - tasks_from: migrate_db_to_postgres - vars: - postgres_db_migration_request: - src: "{{ matrix_registration_sqlite_database_path_local }}" - dst: "{{ matrix_registration_database_connection_string }}" - caller: "{{ role_path | basename }}" - engine_variable_name: 'matrix_registration_database_engine' - engine_old: 'sqlite' - systemd_services_to_stop: ['matrix-registration.service'] - # pgloader makes `ex_date` of type `TIMESTAMP WITH TIMEZONE`, - # which makes matrix-registration choke on it later on when comparing dates. - additional_psql_statements_list: - - ALTER TABLE tokens ALTER COLUMN ex_date TYPE TIMESTAMP WITHOUT TIME ZONE; - additional_psql_statements_db_name: "{{ matrix_registration_database_name }}" - - - ansible.builtin.set_fact: - matrix_registration_migration_requires_restart: true - -- name: Ensure matrix-registration paths exist - ansible.builtin.file: - path: "{{ item.path }}" - state: directory - mode: '0750' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - with_items: - - {path: "{{ matrix_registration_base_path }}", when: true} - - {path: "{{ matrix_registration_config_path }}", when: true} - - {path: "{{ matrix_registration_data_path }}", when: true} - - {path: "{{ matrix_registration_container_src_files_path }}", when: "{{ matrix_registration_container_image_self_build }}"} - when: "item.when | bool" - -- name: Ensure matrix-registration image is pulled - community.docker.docker_image: - name: "{{ matrix_registration_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_registration_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_registration_container_image_force_pull }}" - when: "not matrix_registration_container_image_self_build | bool" - register: matrix_registration_container_image_pull_result - retries: "{{ devture_playbook_help_container_retries_count }}" - delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_registration_container_image_pull_result is not failed - -- name: Ensure matrix-registration repository is present when self-building - ansible.builtin.git: - repo: "{{ matrix_registration_container_image_self_build_repo }}" - dest: "{{ matrix_registration_container_src_files_path }}" - version: "{{ matrix_registration_container_image_self_build_branch }}" - force: "yes" - become: true - become_user: "{{ matrix_user_name }}" - register: matrix_registration_git_pull_results - when: "matrix_registration_container_image_self_build | bool" - -# See: https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1864 -- name: Patch setup.py to allow self-built version to work - ansible.builtin.lineinfile: - path: "{{ matrix_registration_container_src_files_path }}/setup.py" - regexp: 'flask-limiter' - line: '"flask-limiter~=1.1.0", "Markupsafe<2.1",' - when: "matrix_registration_container_image_self_build | bool and matrix_registration_container_image_self_build_python_dependencies_patch_enabled | bool" - -- name: Ensure matrix-registration Docker image is built - community.docker.docker_image: - name: "{{ matrix_registration_container_image }}" - source: build - force_source: "{{ matrix_registration_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_registration_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_registration_container_src_files_path }}" - pull: true - when: "matrix_registration_container_image_self_build | bool" - -- name: Ensure matrix-registration config installed - ansible.builtin.copy: - content: "{{ matrix_registration_configuration | to_nice_yaml(indent=2, width=999999) }}" - dest: "{{ matrix_registration_config_path }}/config.yaml" - mode: '0644' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - register: matrix_registration_config_result - -- name: Ensure matrix-registration support files installed - ansible.builtin.template: - src: "{{ role_path }}/templates/{{ item }}.j2" - dest: "{{ matrix_registration_base_path }}/{{ item }}" - mode: '0640' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - with_items: - - labels - register: matrix_registration_support_files_result - -- name: Ensure matrix-registration container network is created - community.general.docker_network: - enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_registration_container_network }}" - driver: bridge - driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - -- name: Ensure matrix-registration.service installed - ansible.builtin.template: - src: "{{ role_path }}/templates/systemd/matrix-registration.service.j2" - dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-registration.service" - mode: '0644' - register: matrix_registration_systemd_service_result - -- name: Determine whether matrix-registration needs a restart - ansible.builtin.set_fact: - matrix_registration_restart_necessary: >- - {{ - matrix_registration_migration_requires_restart | default(false) - or matrix_registration_config_result.changed | default(false) - or matrix_registration_support_files_result.changed | default(false) - or matrix_registration_systemd_service_result.changed | default(false) - or matrix_registration_container_image_pull_result.changed | default(false) - }} - -- name: Ensure matrix-registration.service restarted, if necessary - ansible.builtin.service: - name: "matrix-registration.service" - state: restarted - daemon_reload: true - when: "matrix_registration_migration_requires_restart | bool" diff --git a/roles/custom/matrix-registration/tasks/setup_uninstall.yml b/roles/custom/matrix-registration/tasks/setup_uninstall.yml deleted file mode 100644 index b8037d59d..000000000 --- a/roles/custom/matrix-registration/tasks/setup_uninstall.yml +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2022 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# SPDX-FileCopyrightText: 2022 Sebastian Gumprich -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Check existence of matrix-registration service - ansible.builtin.stat: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-registration.service" - register: matrix_registration_service_stat - -- when: matrix_registration_service_stat.stat.exists | bool - block: - - name: Ensure matrix-registration is stopped - ansible.builtin.service: - name: matrix-registration - state: stopped - enabled: false - daemon_reload: true - - - name: Ensure matrix-registration.service doesn't exist - ansible.builtin.file: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-registration.service" - state: absent diff --git a/roles/custom/matrix-registration/tasks/validate_config.yml b/roles/custom/matrix-registration/tasks/validate_config.yml deleted file mode 100644 index 232ba6dad..000000000 --- a/roles/custom/matrix-registration/tasks/validate_config.yml +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2025 Suguru Hirahara -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: (Deprecation) Catch and report renamed settings - ansible.builtin.fail: - msg: >- - Your configuration contains a variable, which now has a different name. - Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). - when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" - with_items: - - {'old': 'matrix_registration_docker_repo', 'new': 'matrix_registration_container_image_self_build_repo'} - - {'old': 'matrix_registration_public_endpoint', 'new': 'matrix_registration_path_prefix'} - - {'old': 'matrix_registration_docker_image', 'new': 'matrix_registration_container_image'} - - {'old': 'matrix_registration_docker_image_force_pull', 'new': 'matrix_registration_container_image_force_pull'} - - {'old': 'matrix_registration_docker_image_registry_prefix', 'new': 'matrix_registration_container_image_registry_prefix'} - - {'old': 'matrix_registration_docker_image_registry_prefix_upstream', 'new': 'matrix_registration_container_image_registry_prefix_upstream'} - - {'old': 'matrix_registration_docker_image_registry_prefix_upstream_default', 'new': 'matrix_registration_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_registration_docker_src_files_path', 'new': 'matrix_registration_container_src_files_path'} - -- name: Fail if required matrix-registration settings not defined - ansible.builtin.fail: - msg: > - You need to define a required configuration setting (`{{ item.name }}`). - when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" - with_items: - - {'name': 'matrix_registration_hostname', when: true} - - {'name': 'matrix_registration_path_prefix', when: true} - - {'name': 'matrix_registration_container_network', when: true} - - {'name': 'matrix_registration_shared_secret', when: true} - - {'name': 'matrix_registration_admin_secret', when: true} - - {'name': 'matrix_registration_server_location', when: true} - - {'name': 'matrix_registration_database_hostname', when: "{{ matrix_registration_database_engine == 'postgres' }}"} diff --git a/roles/custom/matrix-registration/templates/config.yaml.j2 b/roles/custom/matrix-registration/templates/config.yaml.j2 deleted file mode 100644 index 2884d6800..000000000 --- a/roles/custom/matrix-registration/templates/config.yaml.j2 +++ /dev/null @@ -1,37 +0,0 @@ -{# -SPDX-FileCopyrightText: 2020 - 2022 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later -#} - -server_location: {{ matrix_registration_server_location|to_json }} -server_name: {{ matrix_registration_server_name|to_json }} -shared_secret: {{ matrix_registration_shared_secret|to_json }} -admin_secret: {{ matrix_registration_admin_secret|to_json }} -riot_instance: {{ matrix_registration_riot_instance|to_json }} -db: {{ matrix_registration_db|to_json }} -host: '0.0.0.0' -port: 5000 -rate_limit: ["100 per day", "10 per minute"] -allow_cors: false -logging: - disable_existing_loggers: False - version: 1 - root: - level: DEBUG - handlers: [console] - formatters: - brief: - format: '%(name)s - %(levelname)s - %(message)s' - precise: - format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s' - handlers: - console: - class: logging.StreamHandler - level: INFO - formatter: brief - stream: ext://sys.stdout -# password requirements -password: - min_length: 8 -base_url: {{ matrix_registration_base_url|to_json }} diff --git a/roles/custom/matrix-registration/templates/labels.j2 b/roles/custom/matrix-registration/templates/labels.j2 deleted file mode 100644 index 7961e84aa..000000000 --- a/roles/custom/matrix-registration/templates/labels.j2 +++ /dev/null @@ -1,69 +0,0 @@ -{# -SPDX-FileCopyrightText: 2024 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later -#} - -{% if matrix_registration_container_labels_traefik_enabled %} -traefik.enable=true - -{% if matrix_registration_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_registration_container_labels_traefik_docker_network }} -{% endif %} - -traefik.http.services.matrix-registration.loadbalancer.server.port=5000 - -{% if matrix_registration_container_labels_public_endpoint_enabled %} -############################################################ -# # -# Public (e.g. /matrix-registration) # -# # -############################################################ - -{% set middlewares = [] %} - -{% if matrix_registration_path_prefix != '/' %} -traefik.http.middlewares.matrix-registration-slashless-redirect-slashless.redirectregex.regex=({{ matrix_registration_path_prefix | quote }})$ -traefik.http.middlewares.matrix-registration-slashless-redirect-slashless.redirectregex.replacement=${1}/ -{% set middlewares = middlewares + ['matrix-registration-slashless-redirect-slashless'] %} -{% endif %} - -# matrix-registration serves nothing at the root URL, so we redirect to /register instead. -traefik.http.middlewares.matrix-registration-slashless-redirect-root.redirectregex.regex=({{ matrix_registration_path_prefix | quote }}{{ '' if matrix_registration_path_prefix == '/' else '/' }})$ -traefik.http.middlewares.matrix-registration-slashless-redirect-root.redirectregex.replacement=${1}register -{% set middlewares = middlewares + ['matrix-registration-slashless-redirect-root'] %} - -{% if matrix_registration_path_prefix != '/' %} -traefik.http.middlewares.matrix-registration-strip-prefix.stripprefix.prefixes={{ matrix_registration_path_prefix }} -{% set middlewares = middlewares + ['matrix-registration-strip-prefix'] %} -{% endif %} - -traefik.http.routers.matrix-registration-public.rule={{ matrix_registration_container_labels_public_endpoint_traefik_rule }} - -{% if middlewares | length > 0 %} -traefik.http.routers.matrix-registration-public.middlewares={{ middlewares | join(',') }} -{% endif %} - -{% if matrix_registration_container_labels_public_endpoint_traefik_priority | int > 0 %} -traefik.http.routers.matrix-registration-public.priority={{ matrix_registration_container_labels_public_endpoint_traefik_priority }} -{% endif %} - -traefik.http.routers.matrix-registration-public.service=matrix-registration -traefik.http.routers.matrix-registration-public.entrypoints={{ matrix_registration_container_labels_public_endpoint_traefik_entrypoints }} - -traefik.http.routers.matrix-registration-public.tls={{ matrix_registration_container_labels_public_endpoint_traefik_tls | to_json }} -{% if matrix_registration_container_labels_public_endpoint_traefik_tls %} -traefik.http.routers.matrix-registration-public.tls.certResolver={{ matrix_registration_container_labels_public_endpoint_traefik_tls_certResolver }} -{% endif %} - -############################################################ -# # -# /Public (e.g. /matrix-registration) # -# # -############################################################ -{% endif %} - - -{% endif %} - -{{ matrix_registration_container_labels_additional_labels }} diff --git a/roles/custom/matrix-registration/templates/systemd/matrix-registration.service.j2.license b/roles/custom/matrix-registration/templates/systemd/matrix-registration.service.j2.license deleted file mode 100644 index 9d697f20f..000000000 --- a/roles/custom/matrix-registration/templates/systemd/matrix-registration.service.j2.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2020 Slavi Pantaleev - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-static-files/defaults/main.yml b/roles/custom/matrix-static-files/defaults/main.yml index 137dee2ba..22a994785 100644 --- a/roles/custom/matrix-static-files/defaults/main.yml +++ b/roles/custom/matrix-static-files/defaults/main.yml @@ -13,7 +13,7 @@ matrix_static_files_enabled: true matrix_static_files_identifier: matrix-static-files # renovate: datasource=docker depName=joseluisq/static-web-server -matrix_static_files_version: 2.42.0 +matrix_static_files_version: 2.44.0 matrix_static_files_base_path: "{{ matrix_base_data_path }}/{{ 'static-files' if matrix_static_files_identifier == 'matrix-static-files' else matrix_static_files_identifier }}" matrix_static_files_config_path: "{{ matrix_static_files_base_path }}/config" @@ -35,7 +35,6 @@ matrix_static_files_container_image_registry_prefix: "{{ matrix_static_files_con matrix_static_files_container_image_registry_prefix_upstream: "{{ matrix_static_files_container_image_registry_prefix_upstream_default }}" matrix_static_files_container_image_registry_prefix_upstream_default: "docker.io/" matrix_static_files_container_image_tag: "{{ 'latest' if matrix_static_files_version == 'latest' else (matrix_static_files_version + '-alpine') }}" -matrix_static_files_container_image_force_pull: "{{ matrix_static_files_container_image.endswith(':latest') }}" matrix_static_files_container_network: "{{ matrix_static_files_identifier }}" @@ -85,7 +84,7 @@ matrix_static_files_container_labels_well_known_matrix_endpoint_middleware_compr matrix_static_files_container_labels_base_domain_enabled: false matrix_static_files_container_labels_base_domain_traefik_hostname: '' matrix_static_files_container_labels_base_domain_traefik_path_prefix: / -matrix_static_files_container_labels_base_domain_traefik_rule: "Host(`{{ matrix_static_files_container_labels_base_domain_traefik_hostname }}`){% if matrix_static_files_container_labels_base_domain_traefik_path_prefix != '/' %} && PathPrefix(`{{ matrix_static_files_container_labels_well_known_matrix_endpoint_traefik_path_prefix }}`){% endif %}" +matrix_static_files_container_labels_base_domain_traefik_rule: "Host(`{{ matrix_static_files_container_labels_base_domain_traefik_hostname }}`){% if matrix_static_files_container_labels_base_domain_traefik_path_prefix != '/' %} && PathPrefix(`{{ matrix_static_files_container_labels_base_domain_traefik_path_prefix }}`){% endif %}" matrix_static_files_container_labels_base_domain_traefik_priority: 0 matrix_static_files_container_labels_base_domain_traefik_entrypoints: "{{ matrix_static_files_container_labels_traefik_entrypoints }}" matrix_static_files_container_labels_base_domain_traefik_tls: "{{ matrix_static_files_container_labels_base_domain_traefik_entrypoints != 'web' }}" @@ -192,23 +191,30 @@ matrix_static_files_file_matrix_client_property_io_element_e2ee_default: true # See: https://github.com/element-hq/element-web/blob/develop/docs/e2ee.md matrix_static_files_file_matrix_client_property_io_element_e2ee_force_disable: false -# Controls whether `cc.etke.synapse-admin`-related entries should be added to the client well-known. -# By default, if there are entries in `matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin`, we show them (by enabling this). -matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin_enabled: "{{ matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin | default({}) | dict2items | length > 0 }}" +# Controls whether `cc.etke.ketesa`-related entries should be added to the client well-known. +# By default, if there are entries in `matrix_static_files_file_matrix_client_property_cc_etke_ketesa`, we show them (by enabling this). +matrix_static_files_file_matrix_client_property_cc_etke_ketesa_enabled: "{{ matrix_static_files_file_matrix_client_property_cc_etke_ketesa | default({}) | dict2items | length > 0 }}" -# Controls the cc.etke.synapse-admin property in the /.well-known/matrix/client file. -# See `matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin_entries_enabled` -matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin: "{{ matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin_auto | combine(matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin_custom, recursive=True) }}" -matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin_auto: {} -matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin_custom: {} +# Controls the cc.etke.ketesa property in the /.well-known/matrix/client file. +matrix_static_files_file_matrix_client_property_cc_etke_ketesa: "{{ matrix_static_files_file_matrix_client_property_cc_etke_ketesa_auto | combine(matrix_static_files_file_matrix_client_property_cc_etke_ketesa_custom, recursive=True) }}" +matrix_static_files_file_matrix_client_property_cc_etke_ketesa_auto: {} +matrix_static_files_file_matrix_client_property_cc_etke_ketesa_custom: {} + +# The `org.matrix.msc4143.rtc_foci` property has been dropped from MSC4143 in favor of the homeserver's own RTC transports API, +# but remains the only way to reach clients which cannot consult that API. +# Element Call running as a widget (which is how Element Web and Element Desktop invoke it) is one such client, +# because a widget holds no access token of its own and the API requires authentication. +# Newer Element Call versions ask their host client for the transports over the widget API (MSC4515) instead, +# so this property can go away once such versions are widely deployed. +# # Controls whether `org.matrix.msc4143.rtc_foci`-related entries should be added to the client well-known. # By default, if there are entries in `matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci`, we show them (by enabling this). -matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_enabled: "{{ matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci | default({}) | dict2items | length > 0 }}" +matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_enabled: "{{ matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci | default([]) | length > 0 }}" # Controls the org.matrix.msc4143.rtc_foci property in the /.well-known/matrix/client file. # See `matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_enabled` -matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci: "{{ matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_auto+ matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_custom }}" +matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci: "{{ matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_auto + matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_custom }}" matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_auto: [] matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_custom: [] @@ -359,6 +365,59 @@ matrix_static_files_file_matrix_support_configuration: "{{ matrix_static_files_f ######################################################################## +######################################################################## +# # +# Related to /.well-known/matrix/mautrix # +# # +######################################################################## + +# Controls whether a `/.well-known/matrix/mautrix` file is generated and used at all. +# This file allows tools like Mautrix Manager (https://github.com/mautrix/manager) to auto-discover the bridges hosted on this server. +# By default, it's enabled only when there's something to advertise (see `matrix_static_files_file_matrix_mautrix_property_fi_mau_bridges`). +matrix_static_files_file_matrix_mautrix_enabled: "{{ matrix_static_files_file_matrix_mautrix_property_fi_mau_bridges | length > 0 }}" + +# Controls the fi.mau.bridges property in the /.well-known/matrix/mautrix file. +# This is a list of base URLs for bridges hosted on (and connected to) this server. +matrix_static_files_file_matrix_mautrix_property_fi_mau_bridges: "{{ matrix_static_files_file_matrix_mautrix_property_fi_mau_bridges_auto + matrix_static_files_file_matrix_mautrix_property_fi_mau_bridges_custom }}" +matrix_static_files_file_matrix_mautrix_property_fi_mau_bridges_auto: [] +matrix_static_files_file_matrix_mautrix_property_fi_mau_bridges_custom: [] + +# Default /.well-known/matrix/mautrix configuration template which covers the generic use case. +# You can customize it by controlling the various variables inside it. +# +# For a more advanced customization, you can extend the default (see `matrix_static_files_file_matrix_mautrix_configuration_extension_json`) +# or completely replace this variable with your own template. +matrix_static_files_file_matrix_mautrix_configuration_json: "{{ lookup('template', 'templates/public/.well-known/matrix/mautrix.j2', convert_data=False) | from_json }}" + +# Your custom JSON configuration for /.well-known/matrix/mautrix should go to `matrix_static_files_file_matrix_mautrix_configuration_extension_json`. +# This configuration extends the default starting configuration (`matrix_static_files_file_matrix_mautrix_configuration_extension_json`). +# +# You can override individual variables from the default configuration, or introduce new ones. +# +# If you need something more special, you can take full control by +# completely redefining `matrix_static_files_file_matrix_mautrix_configuration_json`. +# +# Example configuration extension follows: +# +# matrix_static_files_file_matrix_mautrix_configuration_extension_json: | +# { +# "fi.mau.external_bridge_servers": ["https://bridges.example.com"] +# } +matrix_static_files_file_matrix_mautrix_configuration_extension_json: '{}' + +matrix_static_files_file_matrix_mautrix_configuration_extension: "{{ matrix_static_files_file_matrix_mautrix_configuration_extension_json | from_json if matrix_static_files_file_matrix_mautrix_configuration_extension_json | from_json is mapping else {} }}" + +# Holds the final /.well-known/matrix/mautrix configuration (a combination of the default and its extension). +# You most likely don't need to touch this variable. Instead, see `matrix_static_files_file_matrix_mautrix_configuration_json` or `matrix_static_files_file_matrix_mautrix_configuration_extension_json`. +matrix_static_files_file_matrix_mautrix_configuration: "{{ matrix_static_files_file_matrix_mautrix_configuration_json | combine(matrix_static_files_file_matrix_mautrix_configuration_extension, recursive=True) }}" + +######################################################################## +# # +# /Related to /.well-known/matrix/mautrix # +# # +######################################################################## + + ######################################################################## # # # Related to index.html # diff --git a/roles/custom/matrix-static-files/molecule/default/converge.yml b/roles/custom/matrix-static-files/molecule/default/converge.yml new file mode 100644 index 000000000..ed693ef0a --- /dev/null +++ b/roles/custom/matrix-static-files/molecule/default/converge.yml @@ -0,0 +1,48 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-static-files Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include base roles for matrix-static-files Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + loop_control: + loop_var: role_name + + # main.yml also invokes the separately-tagged public self-check. In the full + # playbook that runs only after systemd_service_manager has started services. + - name: Include matrix-static-files setup task files + ansible.builtin.include_role: + name: "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + public: true + tasks_from: "{{ role_task_file }}" + loop: + - validate_config.yml + - install.yml + loop_control: + loop_var: role_task_file + +- name: Ensure matrix-static-files is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure matrix-static-files systemd service is started + ansible.builtin.systemd_service: + name: matrix-static-files.service + state: started diff --git a/roles/custom/matrix-static-files/molecule/default/molecule.yml b/roles/custom/matrix-static-files/molecule/default/molecule.yml new file mode 100644 index 000000000..311bd1701 --- /dev/null +++ b/roles/custom/matrix-static-files/molecule/default/molecule.yml @@ -0,0 +1,148 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-static-files-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + # verify.yml is a separate play, so paths and runtime settings it reads are + # pinned here rather than relying on role defaults remaining in scope. + matrix_static_files_base_path: /matrix/static-files + matrix_static_files_config_path: /matrix/static-files/config + matrix_static_files_public_path: /matrix/static-files/public + matrix_static_files_container_network: matrix-static-files-molecule + matrix_static_files_container_http_host_bind_port: '' + + # Exercise the generated environment and prove the server listens on what + # the role rendered rather than static-web-server's own port default. + matrix_static_files_environment_variable_server_port: 18082 + matrix_static_files_environment_variable_server_log_level: debug + matrix_static_files_environment_variable_server_log_remote_address: true + matrix_static_files_environment_variable_server_ignore_hidden_files: false + matrix_static_files_environment_variables_additional_variables: | + MOLECULE_STATIC_FILES_MARKER=environment-reached + matrix_static_files_files_cache_time_hours: 7 + + # Render both router families with non-default routing knobs. Traefik does + # not need to run: the file and the attached container labels are inspected. + matrix_static_files_container_labels_traefik_entrypoints: web + matrix_static_files_container_labels_well_known_matrix_endpoint_traefik_hostname: matrix-well-known.molecule.local + matrix_static_files_container_labels_well_known_matrix_endpoint_traefik_path_prefix: /molecule-well-known + matrix_static_files_container_labels_well_known_matrix_endpoint_traefik_priority: 67 + matrix_static_files_container_labels_well_known_matrix_endpoint_middleware_compress_minResponseBodyBytes: 321 + matrix_static_files_container_labels_base_domain_enabled: true + matrix_static_files_container_labels_base_domain_traefik_hostname: base.molecule.local + matrix_static_files_container_labels_base_domain_traefik_path_prefix: /molecule-base + matrix_static_files_container_labels_base_domain_traefik_priority: 43 + matrix_static_files_container_labels_base_domain_root_path_redirection_enabled: false + matrix_static_files_container_labels_additional_labels: | + molecule.scenario=matrix-static-files + + matrix_static_files_file_index_html_template: |- + <!doctype html> + <html> + <body>Molecule static-files index marker</body> + </html> + + # All URLs are inert data: the static server never contacts them. The mix + # exercises optional sections, recursive extensions, lists and mappings. + matrix_static_files_file_matrix_client_property_m_homeserver_base_url: https://homeserver.molecule.invalid + matrix_static_files_file_matrix_client_property_m_identity_server_base_url: '' + matrix_static_files_file_matrix_client_property_m_integrations_managers_api_url: https://integrations.molecule.invalid/api + matrix_static_files_file_matrix_client_property_m_integrations_managers_ui_url: https://integrations.molecule.invalid/ui + matrix_static_files_file_matrix_client_property_io_element_jitsi_preferred_domain: jitsi.molecule.local + matrix_static_files_file_matrix_client_property_org_matrix_msc2965_authentication_enabled: true + matrix_static_files_file_matrix_client_property_org_matrix_msc2965_authentication_issuer: https://auth.molecule.invalid/ + matrix_static_files_file_matrix_client_property_org_matrix_msc2965_authentication_account: https://auth.molecule.invalid/account + matrix_static_files_file_matrix_client_property_org_matrix_msc3575_proxy_url: https://sync.molecule.invalid + matrix_static_files_file_matrix_client_property_m_tile_server_entries_enabled: true + matrix_static_files_file_matrix_client_property_m_tile_server_map_style_url: https://maps.molecule.invalid/style.json + matrix_static_files_file_matrix_client_property_io_element_e2ee_default: false + matrix_static_files_file_matrix_client_property_io_element_e2ee_force_disable: true + matrix_static_files_file_matrix_client_property_cc_etke_ketesa_custom: + allow: + - molecule-client + marker: ketesa-custom + matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_custom: + - type: livekit + livekit_service_url: https://livekit.molecule.invalid + matrix_static_files_file_matrix_client_configuration_extension_json: | + { + "m.homeserver": { + "molecule_extension_marker": "recursive-merge-reached" + }, + "org.example.molecule": { + "enabled": true, + "sequence": 42 + } + } + + matrix_static_files_file_matrix_server_property_m_server: federation.molecule.local:9448 + matrix_static_files_file_matrix_server_configuration_extension_json: | + { + "org.example.molecule": "server-extension-reached" + } + + matrix_static_files_file_matrix_support_enabled: true + matrix_static_files_file_matrix_support_property_m_contacts: + - matrix_id: "@support:molecule.local" + email_address: support@molecule.invalid + role: m.role.admin + matrix_static_files_file_matrix_support_property_m_support_page: https://support.molecule.invalid + matrix_static_files_file_matrix_support_configuration_extension_json: | + { + "org.example.molecule": { + "channel": "support-extension-reached" + } + } + + matrix_static_files_file_matrix_mautrix_property_fi_mau_bridges_custom: + - https://telegram.molecule.invalid + - https://signal.molecule.invalid + matrix_static_files_file_matrix_mautrix_configuration_extension_json: | + { + "fi.mau.external_bridge_servers": [ + "https://external-bridges.molecule.invalid" + ], + "org.example.molecule": "mautrix-extension-reached" + } + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-static-files/molecule/default/prepare.yml b/roles/custom/matrix-static-files/molecule/default/prepare.yml new file mode 100644 index 000000000..1aa754942 --- /dev/null +++ b/roles/custom/matrix-static-files/molecule/default/prepare.yml @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-static-files Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + # The role's file tasks resolve owner and group by name. matrix-base creates + # these during a real deployment, so the scenario supplies that prerequisite. + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: "0750" diff --git a/roles/custom/matrix-static-files/molecule/default/requirements.yml b/roles/custom/matrix-static-files/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-static-files/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-static-files/molecule/default/verify.yml b/roles/custom/matrix-static-files/molecule/default/verify.yml new file mode 100644 index 000000000..e07815ff9 --- /dev/null +++ b/roles/custom/matrix-static-files/molecule/default/verify.yml @@ -0,0 +1,469 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Verify matrix-static-files + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + + tasks: + # Load the shipped version independently of the scenario. A role version bump + # therefore advances the expected image instead of comparing two test pins. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_static_files_role_defaults + + - name: Wait for the matrix-static-files service to become active + ansible.builtin.systemd_service: + name: matrix-static-files.service + register: matrix_static_files_service + until: matrix_static_files_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + # Restart=always means ActiveState alone stays green during a crash loop. + - name: Assert the service is active and has not restarted + ansible.builtin.assert: + that: + - matrix_static_files_service.status.ActiveState == 'active' + - matrix_static_files_service.status.NRestarts is defined + - matrix_static_files_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-static-files.service is + {{ matrix_static_files_service.status.ActiveState | default('unknown') }} + after {{ matrix_static_files_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-static-files.service is active and has not restarted" + + # Probe over the private container network, matching how Traefik reaches the + # service in a deployment. Every document is generated by a different role path. + - name: Fetch the generated JSON documents from the running service + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_static_files_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nMOLECULE_HTTP_STATUS=%{http_code}" + - "http://matrix-static-files:{{ matrix_static_files_environment_variable_server_port }}{{ item.path }}" + loop: + - name: client + path: /.well-known/matrix/client + - name: server + path: /.well-known/matrix/server + - name: support + path: /.well-known/matrix/support + - name: mautrix + path: /.well-known/matrix/mautrix + register: matrix_static_files_document_responses + changed_when: false + until: "'MOLECULE_HTTP_STATUS=200' in matrix_static_files_document_responses.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert every enabled generated document is served successfully + ansible.builtin.assert: + that: + - "'MOLECULE_HTTP_STATUS=200' in item.stdout" + fail_msg: >- + {{ item.item.path }} was not served successfully + ({{ item.stdout | default('no output') }}) + success_msg: "{{ item.item.path }} is served successfully" + loop: "{{ matrix_static_files_document_responses.results }}" + loop_control: + label: "{{ item.item.name }}" + + - name: Initialize parsed served documents + ansible.builtin.set_fact: + matrix_static_files_served_documents: {} + + - name: Parse the served JSON documents + ansible.builtin.set_fact: + matrix_static_files_served_documents: >- + {{ + matrix_static_files_served_documents + | combine({item.item.name: item.stdout | regex_replace('\nMOLECULE_HTTP_STATUS=[0-9]+\s*$', '') | from_json}) + }} + loop: "{{ matrix_static_files_document_responses.results }}" + loop_control: + label: "{{ item.item.name }}" + + # The default server port must be closed. Otherwise a response on the scenario's + # port would not prove SERVER_PORT reached the process. + - name: Probe static-web-server's default port + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_static_files_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --write-out + - "MOLECULE_HTTP_STATUS=%{http_code}" + - --connect-timeout + - "2" + - http://matrix-static-files:8080/.well-known/matrix/client + register: matrix_static_files_default_port_response + changed_when: false + failed_when: false + + - name: Assert static-web-server's default port is not listening + ansible.builtin.assert: + that: + - "'MOLECULE_HTTP_STATUS=200' not in matrix_static_files_default_port_response.stdout" + fail_msg: >- + Port 8080 answered, so the live probe does not prove the non-default + SERVER_PORT reached static-web-server + success_msg: "Only the configured non-default internal port answers" + + - name: Read the generated JSON files from disk + ansible.builtin.slurp: + src: "{{ matrix_static_files_public_path }}/.well-known/matrix/{{ item }}" + loop: + - client + - server + - support + - mautrix + register: matrix_static_files_rendered_document_files + + - name: Initialize parsed rendered documents + ansible.builtin.set_fact: + matrix_static_files_rendered_documents: {} + + - name: Parse the generated JSON files + ansible.builtin.set_fact: + matrix_static_files_rendered_documents: >- + {{ + matrix_static_files_rendered_documents + | combine({item.item: item.content | b64decode | from_json}) + }} + loop: "{{ matrix_static_files_rendered_document_files.results }}" + loop_control: + label: "{{ item.item }}" + + - name: Assert the running service exposes the exact documents the role generated + ansible.builtin.assert: + that: + - matrix_static_files_served_documents[item] == matrix_static_files_rendered_documents[item] + fail_msg: "The served {{ item }} document differs from the generated file" + success_msg: "The served {{ item }} document is the generated file" + loop: + - client + - server + - support + - mautrix + + - name: Assert the client document carries all configured discovery sections + ansible.builtin.assert: + that: + - matrix_static_files_served_documents.client['m.homeserver'].base_url == 'https://homeserver.molecule.invalid' + - matrix_static_files_served_documents.client['m.integrations'].managers[0].api_url == 'https://integrations.molecule.invalid/api' + - matrix_static_files_served_documents.client['m.integrations'].managers[0].ui_url == 'https://integrations.molecule.invalid/ui' + - matrix_static_files_served_documents.client['io.element.jitsi'].preferredDomain == 'jitsi.molecule.local' + - matrix_static_files_served_documents.client['org.matrix.msc2965.authentication'].issuer == 'https://auth.molecule.invalid/' + - matrix_static_files_served_documents.client['org.matrix.msc2965.authentication'].account == 'https://auth.molecule.invalid/account' + - matrix_static_files_served_documents.client['org.matrix.msc3575.proxy'].url == 'https://sync.molecule.invalid' + - matrix_static_files_served_documents.client['m.tile_server'].map_style_url == 'https://maps.molecule.invalid/style.json' + - matrix_static_files_served_documents.client['io.element.e2ee'].default == false + - matrix_static_files_served_documents.client['io.element.e2ee'].force_disable == true + - matrix_static_files_served_documents.client['cc.etke.ketesa'].marker == 'ketesa-custom' + - matrix_static_files_served_documents.client['org.matrix.msc4143.rtc_foci'][0].livekit_service_url == 'https://livekit.molecule.invalid' + fail_msg: "The client document does not carry the configured discovery sections" + success_msg: "The client document carries the configured discovery sections" + + - name: Assert recursive extension and omission behavior in the client document + ansible.builtin.assert: + that: + - matrix_static_files_served_documents.client['m.homeserver'].molecule_extension_marker == 'recursive-merge-reached' + - matrix_static_files_served_documents.client['org.example.molecule'].enabled == true + - matrix_static_files_served_documents.client['org.example.molecule'].sequence == 42 + - "'m.identity_server' not in matrix_static_files_served_documents.client" + fail_msg: "The client extension was not merged recursively or an omitted section leaked in" + success_msg: "The client extension is merged recursively and disabled identity discovery is omitted" + + - name: Assert the server, support and mautrix documents carry configured data and extensions + ansible.builtin.assert: + that: + - matrix_static_files_served_documents.server['m.server'] == 'federation.molecule.local:9448' + - matrix_static_files_served_documents.server['org.example.molecule'] == 'server-extension-reached' + - matrix_static_files_served_documents.support.contacts[0].matrix_id == '@support:molecule.local' + - matrix_static_files_served_documents.support.contacts[0].role == 'm.role.admin' + - matrix_static_files_served_documents.support.support_page == 'https://support.molecule.invalid' + - matrix_static_files_served_documents.support['org.example.molecule'].channel == 'support-extension-reached' + - matrix_static_files_served_documents.mautrix['fi.mau.bridges'] | length == 2 + - "'https://telegram.molecule.invalid' in matrix_static_files_served_documents.mautrix['fi.mau.bridges']" + - matrix_static_files_served_documents.mautrix['fi.mau.external_bridge_servers'][0] == 'https://external-bridges.molecule.invalid' + - matrix_static_files_served_documents.mautrix['org.example.molecule'] == 'mautrix-extension-reached' + fail_msg: "One or more auxiliary documents lost configured data or extensions" + success_msg: "Server, support and mautrix documents carry configured data and extensions" + + - name: Fetch response headers for every generated JSON document + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_static_files_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --head + - "http://matrix-static-files:{{ matrix_static_files_environment_variable_server_port }}/.well-known/matrix/{{ item }}" + loop: + - client + - server + - support + - mautrix + register: matrix_static_files_document_headers + changed_when: false + + - name: Assert every generated JSON document carries the configured headers + ansible.builtin.assert: + that: + - "'content-type: application/json' in item.stdout_lines" + - "'access-control-allow-origin: *' in item.stdout_lines" + - "'cache-control: max-age=25200' in item.stdout_lines" + fail_msg: >- + {{ item.item }} did not carry the configured JSON, CORS and cache headers: + {{ item.stdout }} + success_msg: "{{ item.item }} carries the configured JSON, CORS and cache headers" + loop: "{{ matrix_static_files_document_headers.results }}" + loop_control: + label: "{{ item.item }}" + + - name: Fetch the generated base-domain index document + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_static_files_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nMOLECULE_HTTP_STATUS=%{http_code}" + - "http://matrix-static-files:{{ matrix_static_files_environment_variable_server_port }}/" + register: matrix_static_files_index_response + changed_when: false + + - name: Assert the configured base-domain index is served + ansible.builtin.assert: + that: + - "'MOLECULE_HTTP_STATUS=200' in matrix_static_files_index_response.stdout" + - "'Molecule static-files index marker' in matrix_static_files_index_response.stdout" + fail_msg: >- + The configured base-domain index was not served + ({{ matrix_static_files_index_response.stdout | default('no output') }}) + success_msg: "The configured base-domain index is served" + + - name: Parse the TOML configuration the role rendered + ansible.builtin.command: + argv: + - python3 + - -c + - >- + import json, sys, tomllib; + print(json.dumps(tomllib.load(open(sys.argv[1], 'rb')))) + - "{{ matrix_static_files_config_path }}/config.toml" + register: matrix_static_files_config_command + changed_when: false + + - name: Assert the parsed server configuration carries the header contract + ansible.builtin.assert: + that: + - matrix_static_files_config.advanced.headers[0].source == '/.well-known/matrix/*' + - matrix_static_files_config.advanced.headers[0].headers['Content-Type'] == 'application/json' + - matrix_static_files_config.advanced.headers[0].headers['Access-Control-Allow-Origin'] == '*' + - matrix_static_files_config.advanced.headers[0].headers['Cache-Control'] == 'max-age=25200' + fail_msg: "The parsed config.toml does not carry the configured header contract" + success_msg: "The parsed config.toml carries the configured header contract" + vars: + matrix_static_files_config: "{{ matrix_static_files_config_command.stdout | from_json }}" + + - name: Read the environment file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_static_files_base_path }}/env" + register: matrix_static_files_env_file + + - name: Initialize the parsed environment + ansible.builtin.set_fact: + matrix_static_files_env_parsed: {} + + - name: Parse the rendered environment + ansible.builtin.set_fact: + matrix_static_files_env_parsed: >- + {{ matrix_static_files_env_parsed | combine({item.split('=', 1)[0]: item.split('=', 1)[1]}) }} + loop: "{{ (matrix_static_files_env_file.content | b64decode).splitlines() | reject('equalto', '') }}" + when: "'=' in item" + no_log: true + + - name: Assert the rendered environment carries the scenario's settings + ansible.builtin.assert: + that: + - matrix_static_files_env_parsed.SERVER_PORT == matrix_static_files_environment_variable_server_port | string + - matrix_static_files_env_parsed.SERVER_LOG_LEVEL == 'debug' + - matrix_static_files_env_parsed.SERVER_LOG_REMOTE_ADDRESS == 'true' + - matrix_static_files_env_parsed.SERVER_IGNORE_HIDDEN_FILES == 'false' + - matrix_static_files_env_parsed.MOLECULE_STATIC_FILES_MARKER == 'environment-reached' + fail_msg: "The parsed environment file does not carry the scenario's settings" + success_msg: "The parsed environment file carries the scenario's settings" + + - name: Read the labels file the role rendered + ansible.builtin.slurp: + src: "{{ matrix_static_files_base_path }}/labels" + register: matrix_static_files_labels_file + + - name: Initialize the parsed labels + ansible.builtin.set_fact: + matrix_static_files_labels_parsed: {} + + - name: Parse the rendered labels + ansible.builtin.set_fact: + matrix_static_files_labels_parsed: >- + {{ matrix_static_files_labels_parsed | combine({item.split('=', 1)[0]: item.split('=', 1)[1]}) }} + loop: "{{ (matrix_static_files_labels_file.content | b64decode).splitlines() | reject('equalto', '') }}" + when: + - "'=' in item" + - not item.startswith('#') + no_log: true + + - name: Assert the rendered labels carry both routing contracts + ansible.builtin.assert: + that: + - matrix_static_files_labels_parsed['traefik.enable'] == 'true' + - matrix_static_files_labels_parsed['traefik.docker.network'] == matrix_static_files_container_network + - matrix_static_files_labels_parsed['traefik.http.services.matrix-static-files.loadbalancer.server.port'] == matrix_static_files_environment_variable_server_port | string + - "'Host(`matrix-well-known.molecule.local`)' in matrix_static_files_labels_parsed['traefik.http.routers.matrix-static-files-well-known-matrix.rule']" + - "'PathPrefix(`/molecule-well-known`)' in matrix_static_files_labels_parsed['traefik.http.routers.matrix-static-files-well-known-matrix.rule']" + - matrix_static_files_labels_parsed['traefik.http.routers.matrix-static-files-well-known-matrix.priority'] == '67' + - matrix_static_files_labels_parsed['traefik.http.routers.matrix-static-files-well-known-matrix.entrypoints'] == 'web' + - matrix_static_files_labels_parsed['traefik.http.routers.matrix-static-files-well-known-matrix.tls'] == 'false' + - matrix_static_files_labels_parsed['traefik.http.middlewares.matrix-static-files-well-known-matrix-compress.compress.minResponseBodyBytes'] == '321' + - "'Host(`base.molecule.local`)' in matrix_static_files_labels_parsed['traefik.http.routers.matrix-static-files-base-domain.rule']" + - "'PathPrefix(`/molecule-base`)' in matrix_static_files_labels_parsed['traefik.http.routers.matrix-static-files-base-domain.rule']" + - matrix_static_files_labels_parsed['traefik.http.routers.matrix-static-files-base-domain.priority'] == '43' + - matrix_static_files_labels_parsed['traefik.http.routers.matrix-static-files-base-domain.tls'] == 'false' + - matrix_static_files_labels_parsed['molecule.scenario'] == 'matrix-static-files' + fail_msg: "The rendered labels do not carry both routing contracts" + success_msg: "The rendered labels carry both routing contracts" + + - name: Inspect the running matrix-static-files container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-static-files + register: matrix_static_files_container_inspect_command + changed_when: false + + - name: Parse the running container inspection + ansible.builtin.set_fact: + matrix_static_files_container: "{{ (matrix_static_files_container_inspect_command.stdout | from_json)[0] }}" + + - name: Assert the configured environment reached the running container + ansible.builtin.assert: + that: + - "('SERVER_PORT=' ~ (matrix_static_files_environment_variable_server_port | string)) in matrix_static_files_container.Config.Env" + - "'SERVER_LOG_LEVEL=debug' in matrix_static_files_container.Config.Env" + - "'SERVER_LOG_REMOTE_ADDRESS=true' in matrix_static_files_container.Config.Env" + - "'SERVER_IGNORE_HIDDEN_FILES=false' in matrix_static_files_container.Config.Env" + - "'MOLECULE_STATIC_FILES_MARKER=environment-reached' in matrix_static_files_container.Config.Env" + fail_msg: "The running container environment does not carry the scenario's settings" + success_msg: "The configured environment reached the running container" + + - name: Assert the rendered labels reached the running container + ansible.builtin.assert: + that: + - matrix_static_files_container.Config.Labels['traefik.enable'] == 'true' + - matrix_static_files_container.Config.Labels['traefik.docker.network'] == matrix_static_files_container_network + - matrix_static_files_container.Config.Labels['traefik.http.services.matrix-static-files.loadbalancer.server.port'] == matrix_static_files_environment_variable_server_port | string + - matrix_static_files_container.Config.Labels['traefik.http.routers.matrix-static-files-well-known-matrix.priority'] == '67' + - matrix_static_files_container.Config.Labels['traefik.http.routers.matrix-static-files-base-domain.priority'] == '43' + - matrix_static_files_container.Config.Labels['molecule.scenario'] == 'matrix-static-files' + fail_msg: "The running container does not carry the labels the role rendered" + success_msg: "The rendered labels reached the running container" + + - name: Assert the running container uses the exact image and version the role pins + ansible.builtin.assert: + that: + - matrix_static_files_container.Config.Image == matrix_static_files_expected_image + fail_msg: >- + The running container uses {{ matrix_static_files_container.Config.Image }}, + expected {{ matrix_static_files_expected_image }} + success_msg: "The running container uses the exact image and version defaults/main.yml pins" + vars: + matrix_static_files_expected_tag: >- + {{ + 'latest' + if matrix_static_files_role_defaults.matrix_static_files_version == 'latest' + else matrix_static_files_role_defaults.matrix_static_files_version ~ '-alpine' + }} + matrix_static_files_expected_image: >- + {{ matrix_static_files_role_defaults.matrix_static_files_container_image_registry_prefix_upstream_default }}joseluisq/static-web-server:{{ matrix_static_files_expected_tag }} + + - name: Assert the running container uses the configured UID and GID + ansible.builtin.assert: + that: + - matrix_static_files_container.Config.User == (matrix_user_uid | string) ~ ':' ~ (matrix_user_gid | string) + fail_msg: >- + The running container uses {{ matrix_static_files_container.Config.User }}, + expected {{ matrix_user_uid }}:{{ matrix_user_gid }} + success_msg: "The running container uses the configured UID and GID" + + - name: Assert the running container has a read-only root filesystem + ansible.builtin.assert: + that: + - matrix_static_files_container.HostConfig.ReadonlyRootfs == true + fail_msg: "The running container's root filesystem is writable" + success_msg: "The running container has a read-only root filesystem" + + - name: Assert the running container drops all capabilities and adds none + ansible.builtin.assert: + that: + - matrix_static_files_container.HostConfig.CapDrop == ['ALL'] + - matrix_static_files_container.HostConfig.CapAdd | default([], true) | length == 0 + fail_msg: "The running container does not have the expected capability restrictions" + success_msg: "The running container drops all capabilities and adds none" + + - name: Assert both bind mounts are read-only + ansible.builtin.assert: + that: + - matrix_static_files_container.Mounts | selectattr('Destination', 'equalto', '/var/public') | list | length == 1 + - (matrix_static_files_container.Mounts | selectattr('Destination', 'equalto', '/var/public') | first).RW == false + - matrix_static_files_container.Mounts | selectattr('Destination', 'equalto', '/config') | list | length == 1 + - (matrix_static_files_container.Mounts | selectattr('Destination', 'equalto', '/config') | first).RW == false + fail_msg: "The running container is missing a read-only content or configuration mount" + success_msg: "Both bind mounts are present and read-only" + + - name: Assert the running container is attached only to its dedicated network + ansible.builtin.assert: + that: + - matrix_static_files_container.NetworkSettings.Networks.keys() | list | length == 1 + - matrix_static_files_container_network in matrix_static_files_container.NetworkSettings.Networks + fail_msg: >- + The running container is attached to unexpected networks: + {{ matrix_static_files_container.NetworkSettings.Networks.keys() | list }} + success_msg: "The running container is attached only to its dedicated network" + + - name: Assert the running container publishes no host ports + ansible.builtin.assert: + that: + - matrix_static_files_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: "The running container unexpectedly publishes a host port" + success_msg: "The running container publishes no host ports" diff --git a/roles/custom/matrix-static-files/tasks/install.yml b/roles/custom/matrix-static-files/tasks/install.yml index 3761497e7..df3552280 100644 --- a/roles/custom/matrix-static-files/tasks/install.yml +++ b/roles/custom/matrix-static-files/tasks/install.yml @@ -65,6 +65,10 @@ dest: "{{ matrix_static_files_public_well_known_matrix_path }}/support" when: "{{ matrix_static_files_file_matrix_support_enabled }}" + - content: "{{ matrix_static_files_file_matrix_mautrix_configuration | to_nice_json }}" + dest: "{{ matrix_static_files_public_well_known_matrix_path }}/mautrix" + when: "{{ matrix_static_files_file_matrix_mautrix_enabled }}" + # This one will not be deleted if `matrix_static_files_file_index_html_enabled` flips to `false`. # See the comment for `matrix_static_files_file_index_html_enabled` to learn why. - content: "{{ matrix_static_files_file_index_html_template }}" @@ -84,18 +88,23 @@ state: absent when: "not matrix_static_files_file_matrix_support_enabled | bool" +- name: Ensure /.well-known/matrix/mautrix file deleted if not enabled + ansible.builtin.file: + path: "{{ matrix_static_files_public_well_known_matrix_path }}/mautrix" + state: absent + when: "not matrix_static_files_file_matrix_mautrix_enabled | bool" + - name: Ensure matrix-static-files container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_static_files_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_static_files_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_static_files_container_image_force_pull }}" + pull: always register: matrix_static_files_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_static_files_container_image_pull_result is not failed - name: Ensure matrix-static-files container network is created + when: matrix_static_files_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_static_files_container_network }}" diff --git a/roles/custom/matrix-static-files/tasks/validate_config.yml b/roles/custom/matrix-static-files/tasks/validate_config.yml index 7924507f7..889fb1a31 100644 --- a/roles/custom/matrix-static-files/tasks/validate_config.yml +++ b/roles/custom/matrix-static-files/tasks/validate_config.yml @@ -20,3 +20,11 @@ - {'name': 'matrix_static_files_file_matrix_client_property_org_matrix_msc2965_authentication_issuer', when: "{{ matrix_static_files_file_matrix_client_property_org_matrix_msc2965_authentication_enabled and matrix_static_files_container_labels_base_domain_root_path_redirection_enabled }}"} - {'name': 'matrix_static_files_file_matrix_client_property_org_matrix_msc2965_authentication_account', when: "{{ matrix_static_files_file_matrix_client_property_org_matrix_msc2965_authentication_enabled and matrix_static_files_container_labels_base_domain_root_path_redirection_enabled }}"} + +- name: (Deprecation) Catch and report renamed matrix-static-files variables + ansible.builtin.fail: + msg: >- + The variable `{{ item.old }}` is deprecated. Please use `{{ item.new }}` instead. + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_static_files_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-static-files/templates/public/.well-known/matrix/client.j2 b/roles/custom/matrix-static-files/templates/public/.well-known/matrix/client.j2 index feabaeb2b..75fbff472 100644 --- a/roles/custom/matrix-static-files/templates/public/.well-known/matrix/client.j2 +++ b/roles/custom/matrix-static-files/templates/public/.well-known/matrix/client.j2 @@ -52,9 +52,10 @@ "default": {{ matrix_static_files_file_matrix_client_property_io_element_e2ee_default|to_json }} } {% endif %} - {% if matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin_enabled %}, - "cc.etke.synapse-admin": {{ matrix_static_files_file_matrix_client_property_cc_etke_synapse_admin | to_json }} + {% if matrix_static_files_file_matrix_client_property_cc_etke_ketesa_enabled %}, + "cc.etke.ketesa": {{ matrix_static_files_file_matrix_client_property_cc_etke_ketesa | to_json }} {% endif %} + {% if matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci_enabled %}, "org.matrix.msc4143.rtc_foci": {{ matrix_static_files_file_matrix_client_property_org_matrix_msc4143_rtc_foci | to_json }} {% endif %} diff --git a/roles/custom/matrix-static-files/templates/public/.well-known/matrix/mautrix.j2 b/roles/custom/matrix-static-files/templates/public/.well-known/matrix/mautrix.j2 new file mode 100644 index 000000000..72ce29ca9 --- /dev/null +++ b/roles/custom/matrix-static-files/templates/public/.well-known/matrix/mautrix.j2 @@ -0,0 +1,3 @@ +{ + "fi.mau.bridges": {{ matrix_static_files_file_matrix_mautrix_property_fi_mau_bridges | to_json }} +} diff --git a/roles/custom/matrix-static-files/templates/public/.well-known/matrix/mautrix.j2.license b/roles/custom/matrix-static-files/templates/public/.well-known/matrix/mautrix.j2.license new file mode 100644 index 000000000..dbb307901 --- /dev/null +++ b/roles/custom/matrix-static-files/templates/public/.well-known/matrix/mautrix.j2.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-static-files/templates/systemd/matrix-static-files.service.j2 b/roles/custom/matrix-static-files/templates/systemd/matrix-static-files.service.j2 index 8f93ef0e2..759c4d8cf 100755 --- a/roles/custom/matrix-static-files/templates/systemd/matrix-static-files.service.j2 +++ b/roles/custom/matrix-static-files/templates/systemd/matrix-static-files.service.j2 @@ -33,9 +33,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --mount type=bind,src={{ matrix_static_files_config_path }},dst=/config,ro \ {{ matrix_static_files_container_image }} +{% if matrix_static_files_container_network != 'host' %} {% for network in matrix_static_files_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-static-files {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-static-files diff --git a/roles/custom/matrix-sygnal/defaults/main.yml b/roles/custom/matrix-sygnal/defaults/main.yml index d5774205d..331fe218c 100644 --- a/roles/custom/matrix-sygnal/defaults/main.yml +++ b/roles/custom/matrix-sygnal/defaults/main.yml @@ -22,7 +22,7 @@ matrix_sygnal_hostname: '' matrix_sygnal_path_prefix: / # renovate: datasource=docker depName=matrixdotorg/sygnal -matrix_sygnal_version: v0.15.1 +matrix_sygnal_version: v0.17.0 matrix_sygnal_base_path: "{{ matrix_base_data_path }}/sygnal" matrix_sygnal_config_path: "{{ matrix_sygnal_base_path }}/config" @@ -39,7 +39,6 @@ matrix_sygnal_container_image_tag: "{{ matrix_sygnal_version }}" matrix_sygnal_container_image_registry_prefix: "{{ matrix_sygnal_container_image_registry_prefix_upstream }}" matrix_sygnal_container_image_registry_prefix_upstream: "{{ matrix_sygnal_container_image_registry_prefix_upstream_default }}" matrix_sygnal_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_sygnal_container_image_force_pull: "{{ matrix_sygnal_container_image.endswith(':latest') }}" # The base container network. It will be auto-created by this role if it doesn't exist already. matrix_sygnal_container_network: "{{ matrix_sygnal_identifier }}" diff --git a/roles/custom/matrix-sygnal/tasks/install.yml b/roles/custom/matrix-sygnal/tasks/install.yml index cb82d3bc9..bca568ebc 100644 --- a/roles/custom/matrix-sygnal/tasks/install.yml +++ b/roles/custom/matrix-sygnal/tasks/install.yml @@ -40,17 +40,16 @@ register: matrix_sygnal_support_files_result - name: Ensure Sygnal image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_sygnal_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_sygnal_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_sygnal_container_image_force_pull }}" + pull: always register: matrix_sygnal_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_sygnal_container_image_pull_result is not failed - name: Ensure Sygnal container network is created + when: matrix_sygnal_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_sygnal_container_network }}" diff --git a/roles/custom/matrix-sygnal/tasks/validate_config.yml b/roles/custom/matrix-sygnal/tasks/validate_config.yml index 60ef972f7..19955c42e 100644 --- a/roles/custom/matrix-sygnal/tasks/validate_config.yml +++ b/roles/custom/matrix-sygnal/tasks/validate_config.yml @@ -18,6 +18,7 @@ - {'old': 'matrix_sygnal_docker_image_registry_prefix_upstream', 'new': 'matrix_sygnal_container_image_registry_prefix_upstream'} - {'old': 'matrix_sygnal_docker_image_registry_prefix_upstream_default', 'new': 'matrix_sygnal_container_image_registry_prefix_upstream_default'} - {'old': 'matrix_sygnal_docker_image_tag', 'new': 'matrix_sygnal_container_image_tag'} + - {'old': 'matrix_sygnal_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - name: Fail if required Sygnal settings not defined diff --git a/roles/custom/matrix-sygnal/templates/systemd/matrix-sygnal.service.j2 b/roles/custom/matrix-sygnal/templates/systemd/matrix-sygnal.service.j2 index ef7c20d97..b948673f3 100644 --- a/roles/custom/matrix-sygnal/templates/systemd/matrix-sygnal.service.j2 +++ b/roles/custom/matrix-sygnal/templates/systemd/matrix-sygnal.service.j2 @@ -16,12 +16,16 @@ Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-sygnal 2>/dev/null || true' ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-sygnal 2>/dev/null || true' +{# --no-healthcheck is used below, because the healthcheck hardcoded in the image (since v0.16.0) can never pass - + it relies on curl, which the image does not include. + See https://github.com/element-hq/sygnal/issues/326 and https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/4794 #} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --rm \ --name=matrix-sygnal \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --cap-drop=ALL \ + --no-healthcheck \ --env=SYGNAL_CONF=/config/sygnal.yaml \ --network={{ matrix_sygnal_container_network }} \ {% if matrix_sygnal_container_http_host_bind_port %} @@ -35,9 +39,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_sygnal_container_image }} +{% if matrix_sygnal_container_network != 'host' %} {% for network in matrix_sygnal_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-sygnal {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-sygnal diff --git a/roles/custom/matrix-synapse-admin/defaults/main.yml b/roles/custom/matrix-synapse-admin/defaults/main.yml deleted file mode 100644 index 515b98223..000000000 --- a/roles/custom/matrix-synapse-admin/defaults/main.yml +++ /dev/null @@ -1,260 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2021 Aaron Raimist -# SPDX-FileCopyrightText: 2020 - 2025 Slavi Pantaleev -# SPDX-FileCopyrightText: 2020 Dennis Ciba -# SPDX-FileCopyrightText: 2021 - 2025 MDAD project contributors -# SPDX-FileCopyrightText: 2021 Ahmad Haghighi -# SPDX-FileCopyrightText: 2022 - 2025 Nikita Chernyi -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# SPDX-FileCopyrightText: 2023 Samuel Meenzen -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- -# matrix-synapse-admin is a web UI for managing the Synapse Matrix server -# Project source code URL: https://github.com/Awesome-Technologies/synapse-admin -# Fork source code URL: https://github.com/etkecc/synapse-admin - -matrix_synapse_admin_enabled: true - -# A path on host where all related files will be saved -matrix_synapse_admin_base_path: "{{ matrix_base_data_path }}/synapse-admin" -matrix_synapse_admin_config_path: "{{ matrix_synapse_admin_base_path }}/config" -matrix_synapse_admin_container_src_files_path: "{{ matrix_synapse_admin_base_path }}/docker-src" - -matrix_synapse_admin_container_uid: '' -matrix_synapse_admin_container_gid: '' - -matrix_synapse_admin_container_image_self_build: false -matrix_synapse_admin_container_image_self_build_repo: "https://github.com/etkecc/synapse-admin.git" - -# renovate: datasource=docker depName=ghcr.io/etkecc/synapse-admin -matrix_synapse_admin_version: v0.11.4-etke54 -matrix_synapse_admin_container_image: "{{ matrix_synapse_admin_container_image_registry_prefix }}etkecc/synapse-admin:{{ matrix_synapse_admin_version }}" -matrix_synapse_admin_container_image_registry_prefix: "{{ 'localhost/' if matrix_synapse_admin_container_image_self_build else matrix_synapse_admin_container_image_registry_prefix_upstream }}" -matrix_synapse_admin_container_image_registry_prefix_upstream: "{{ matrix_synapse_admin_container_image_registry_prefix_upstream_default }}" -matrix_synapse_admin_container_image_registry_prefix_upstream_default: "ghcr.io/" -matrix_synapse_admin_container_image_force_pull: "{{ matrix_synapse_admin_container_image.endswith(':latest') }}" - -# The base container network -matrix_synapse_admin_container_network: matrix-synapse-admin - -# A list of additional container networks that the container would be connected to. -# The role does not create these networks, so make sure they already exist. -# Use this to expose this container to a reverse proxy, which runs in a different container network. -matrix_synapse_admin_container_additional_networks: [] - -# Controls whether the matrix-synapse-admin container exposes its HTTP port (tcp/8080 in the container). -# -# Takes an "<ip>:<port>" or "<port>" value (e.g. "127.0.0.1:8766"), or empty string to not expose. -matrix_synapse_admin_container_http_host_bind_port: '' - -# A list of extra arguments to pass to the container -matrix_synapse_admin_container_extra_arguments: [] - -# matrix_synapse_admin_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. -# See `../templates/labels.j2` for details. -# -# To inject your own other container labels, see `matrix_synapse_admin_container_labels_additional_labels`. -matrix_synapse_admin_container_labels_traefik_enabled: true -matrix_synapse_admin_container_labels_traefik_docker_network: "{{ matrix_synapse_admin_container_network }}" -matrix_synapse_admin_container_labels_traefik_hostname: "{{ matrix_synapse_admin_hostname }}" -# The path prefix must either be `/` or not end with a slash (e.g. `/synapse-admin`). -matrix_synapse_admin_container_labels_traefik_path_prefix: "{{ matrix_synapse_admin_path_prefix }}" -matrix_synapse_admin_container_labels_traefik_rule: "Host(`{{ matrix_synapse_admin_container_labels_traefik_hostname }}`){% if matrix_synapse_admin_container_labels_traefik_path_prefix != '/' %} && PathPrefix(`{{ matrix_synapse_admin_container_labels_traefik_path_prefix }}`){% endif %}" -matrix_synapse_admin_container_labels_traefik_priority: 0 -matrix_synapse_admin_container_labels_traefik_entrypoints: web-secure -matrix_synapse_admin_container_labels_traefik_tls: "{{ matrix_synapse_admin_container_labels_traefik_entrypoints != 'web' }}" -matrix_synapse_admin_container_labels_traefik_tls_certResolver: default # noqa var-naming -# This setting is to define a list ip addresses to allow access to synapse-admin. -# Each IP address should be in CIDR format, e.g. xxx.xxx.xxx.xxx/xx. -# For more information, see: https://doc.traefik.io/traefik/middlewares/http/ipallowlist/ -# If the list is empty, all IP addresses are allowed. -matrix_synapse_admin_container_labels_traefik_ipallowlist_sourcerange: [] - -# Controls which additional headers to attach to all HTTP responses. -# To add your own headers, use `matrix_synapse_admin_container_labels_traefik_additional_response_headers_custom` -matrix_synapse_admin_container_labels_traefik_additional_response_headers: "{{ matrix_synapse_admin_container_labels_traefik_additional_response_headers_auto | combine(matrix_synapse_admin_container_labels_traefik_additional_response_headers_custom) }}" -matrix_synapse_admin_container_labels_traefik_additional_response_headers_auto: | - {{ - {} - | combine ({'X-XSS-Protection': matrix_synapse_admin_http_header_xss_protection} if matrix_synapse_admin_http_header_xss_protection else {}) - | combine ({'X-Content-Type-Options': matrix_synapse_admin_http_header_content_type_options} if matrix_synapse_admin_http_header_content_type_options else {}) - | combine ({'Content-Security-Policy': matrix_synapse_admin_http_header_content_security_policy} if matrix_synapse_admin_http_header_content_security_policy else {}) - | combine ({'Permission-Policy': matrix_synapse_admin_http_header_content_permission_policy} if matrix_synapse_admin_http_header_content_permission_policy else {}) - | combine ({'Strict-Transport-Security': matrix_synapse_admin_http_header_strict_transport_security} if matrix_synapse_admin_http_header_strict_transport_security and matrix_synapse_admin_container_labels_traefik_tls else {}) - }} -matrix_synapse_admin_container_labels_traefik_additional_response_headers_custom: {} - -# matrix_synapse_admin_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. -# See `../templates/labels.j2` for details. -# -# Example: -# matrix_synapse_admin_container_labels_additional_labels: | -# my.label=1 -# another.label="here" -matrix_synapse_admin_container_labels_additional_labels: '' - -# List of systemd services that matrix-synapse-admin.service depends on -matrix_synapse_admin_systemd_required_services_list: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" - -# List of systemd services that matrix-synapse-admin.service wants -matrix_synapse_admin_systemd_wanted_services_list: [] - -# Specifies the value of the `X-XSS-Protection` header -# Stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. -# -# Learn more about it is here: -# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection -# - https://portswigger.net/web-security/cross-site-scripting/reflected -matrix_synapse_admin_http_header_xss_protection: "1; mode=block" - -# Specifies the value of the `X-Content-Type-Options` header. -# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options -matrix_synapse_admin_http_header_content_type_options: nosniff - -# Specifies the value of the `Content-Security-Policy` header. -# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy -matrix_synapse_admin_http_header_content_security_policy: frame-ancestors 'self' - -# Specifies the value of the `Permission-Policy` header. -# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permission-Policy -matrix_synapse_admin_http_header_content_permission_policy: "{{ 'interest-cohort=()' if matrix_synapse_admin_floc_optout_enabled else '' }}" - -# Specifies the value of the `Strict-Transport-Security` header. -# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security -matrix_synapse_admin_http_header_strict_transport_security: "max-age=31536000; includeSubDomains{{ '; preload' if matrix_synapse_admin_hsts_preload_enabled else '' }}" - -# Controls whether to send a "Permissions-Policy interest-cohort=();" header along with all responses -# -# Learn more about what it is here: -# - https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea -# - https://paramdeo.com/blog/opting-your-website-out-of-googles-floc-network -# - https://amifloced.org/ -# -# Of course, a better solution is to just stop using browsers (like Chrome), which participate in such tracking practices. -# See: `matrix_synapse_admin_content_permission_policy` -matrix_synapse_admin_floc_optout_enabled: true - -# Controls if HSTS preloading is enabled -# -# In its strongest and recommended form, the [HSTS policy](https://www.chromium.org/hsts) includes all subdomains, and -# indicates a willingness to be "preloaded" into browsers: -# `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload` -# For more information visit: -# - https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security -# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security -# - https://hstspreload.org/#opt-in -# See: `matrix_synapse_admin_http_header_strict_transport_security` -matrix_synapse_admin_hsts_preload_enabled: false - -# The hostname at which Synapse Admin is served. -matrix_synapse_admin_hostname: "{{ matrix_server_fqn_matrix }}" - -# The path at which Synapse Admin is exposed. -# This value must either be `/` or not end with a slash (e.g. `/synapse-admin`). -matrix_synapse_admin_path_prefix: /synapse-admin - -# Default synapse-admin configuration template which covers the generic use case. -# You can customize it by controlling the various variables inside it. -# -# For a more advanced customization, you can extend the default (see `matrix_synapse_admin_configuration_extension_json`) -# or completely replace this variable with your own template. -# -# The side-effect of this lookup is that Ansible would even parse the JSON for us, returning a dict. -# This is unlike what it does when looking up YAML template files (no automatic parsing there). -matrix_synapse_admin_configuration_default: - restrictBaseUrl: "{{ matrix_synapse_admin_config_restrictBaseUrl }}" - externalAuthProvider: "{{ matrix_synapse_admin_config_externalAuthProvider }}" - corsCredentials: "{{ matrix_synapse_admin_config_corsCredentials }}" - asManagedUsers: "{{ matrix_synapse_admin_config_asManagedUsers }}" - menu: "{{ matrix_synapse_admin_config_menu }}" - -# Your custom JSON configuration for synapse-admin should go to `matrix_synapse_admin_configuration_extension_json`. -# This configuration extends the default starting configuration (`matrix_synapse_admin_configuration_default`). -# -# You can override individual variables from the default configuration, or introduce new ones. -# -# If you need something more special, you can take full control by -# completely redefining `matrix_synapse_admin_configuration_default`. -# -# Example configuration extension follows: -# -# matrix_synapse_admin_configuration_extension_json: | -# { -# "some_setting": true, -# "another_setting": false -# } -matrix_synapse_admin_configuration_extension_json: '{}' - -# This is similar to `matrix_synapse_admin_configuration_extension_json`, but intended for use by playbook or group vars -matrix_synapse_admin_configuration_extension_json_auto: '{}' - -matrix_synapse_admin_configuration_extension: "{{ matrix_synapse_admin_configuration_extension_json_auto | from_json | combine(matrix_synapse_admin_configuration_extension_json | from_json if matrix_synapse_admin_configuration_extension_json | from_json is mapping else {}, recursive=True) }}" - -# Holds the final synapse-admin configuration (a combination of the default and its extension). -# You most likely don't need to touch this variable. Instead, see `matrix_synapse_admin_configuration_default`. -matrix_synapse_admin_configuration: "{{ matrix_synapse_admin_configuration_default | combine(matrix_synapse_admin_configuration_extension, recursive=True) }}" - -# Controls the restrictBaseUrl configuration setting, which, if defined, -# restricts the homeserver(s), so that the user can no longer define a homeserver manually during login. -matrix_synapse_admin_config_restrictBaseUrl: "{{ matrix_homeserver_url }}" # noqa var-naming - -# Controls the externalAuthProvider configuration setting, which, if defined, -# enables a special compatibility mode that works better for external auth providers like LDAP, MAS, etc. -matrix_synapse_admin_config_externalAuthProvider: false # noqa var-naming - -# Controls the corsCredentials configuration setting, which, if defined, -# allows including credentials (cookies, authorization headers, or TLS client certificates) in requests -# ref: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#including_credentials -matrix_synapse_admin_config_corsCredentials: "same-origin" # noqa var-naming - -# Controls the menu configuration setting, which, if defined, adds new menu items to the Synapse Admin UI. -# The format is a list of objects, where each object has the following keys: -# - `label` (string, required): The label of the menu item. -# - `i18n` (dict, optional): Dictionary of translations for the label. The keys should be BCP 47 language tags (e.g., en, fr, de) supported by Synapse Admin (see src/i18n). -# - `icon` (string, optional): The icon of the menu item, one of the https://github.com/etkecc/synapse-admin/blob/main/src/components/icons.ts -# - `url` (string, required): The URL of the menu item. -# Example: -# [ -# { -# "label": "Contact support", -# "i18n": { -# "de": "Support kontaktieren", -# "fr": "Contacter le support", -# "zh": "联系支持" -# }, -# "icon": "SupportAgent", -# "url": "https://github.com/etkecc/synapse-admin/issues" -# } -# ] -matrix_synapse_admin_config_menu: [] - -# Controls the asManagedUsers configuration setting (managed by playbook), which, if defined, -# restricts modifications of the specified users (e.g., bridge-managed). -# You should use JS regex syntax to match the user IDs. -# Example for mautrix-telegram: ["^@telegram_[a-zA-Z0-9]+:example\\.com$"] -# WARNING: you want to use matrix_synapse_admin_config_asManagedUsers_custom instead of this variable. -matrix_synapse_admin_config_asManagedUsers_auto: [] # noqa var-naming - -# Controls the asManagedUsers configuration setting (managed per host), which, if defined, -# restricts modifications of the specified users (e.g., bridge-managed). -# You should use JS regex syntax to match the user IDs. -# Example for mautrix-telegram: ["^@telegram_[a-zA-Z0-9]+:example\\.com$"] -matrix_synapse_admin_config_asManagedUsers_custom: [] # noqa var-naming - -# Controls the asManagedUsers configuration setting, which, if defined, -# restricts modifications of the specified users (e.g., bridge-managed). -# You should use JS regex syntax to match the user IDs. -# Example for mautrix-telegram: ["^@telegram_[a-zA-Z0-9]+:example\\.com$"] -# WARNING: you want to use matrix_synapse_admin_config_asManagedUsers_custom instead of this variable. -matrix_synapse_admin_config_asManagedUsers: "{{ matrix_synapse_admin_config_asManagedUsers_auto + matrix_synapse_admin_config_asManagedUsers_custom }}" # noqa var-naming - -# matrix_synapse_admin_restart_necessary controls whether the service -# will be restarted (when true) or merely started (when false) by the -# systemd service manager role (when conditional restart is enabled). -# -# This value is automatically computed during installation based on whether -# any configuration files, the systemd service file, or the container image changed. -# The default of `false` means "no restart needed" — appropriate when the role's -# installation tasks haven't run (e.g., due to --tags skipping them). -matrix_synapse_admin_restart_necessary: false diff --git a/roles/custom/matrix-synapse-admin/tasks/setup_install.yml b/roles/custom/matrix-synapse-admin/tasks/setup_install.yml deleted file mode 100644 index fac0f7fd3..000000000 --- a/roles/custom/matrix-synapse-admin/tasks/setup_install.yml +++ /dev/null @@ -1,102 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2024 Slavi Pantaleev -# SPDX-FileCopyrightText: 2020 Dennis Ciba -# SPDX-FileCopyrightText: 2021 Aaron Raimist -# SPDX-FileCopyrightText: 2022 MDAD project contributors -# SPDX-FileCopyrightText: 2022 Marko Weltzer -# SPDX-FileCopyrightText: 2022 Nikita Chernyi -# SPDX-FileCopyrightText: 2022 Sebastian Gumprich -# SPDX-FileCopyrightText: 2024 David Mehren -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Ensure matrix-synapse-admin paths exists - ansible.builtin.file: - path: "{{ item.path }}" - state: directory - mode: '0750' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - with_items: - - {path: "{{ matrix_synapse_admin_base_path }}", when: true} - - {path: "{{ matrix_synapse_admin_config_path }}", when: true} - - {path: "{{ matrix_synapse_admin_container_src_files_path }}", when: "{{ matrix_synapse_admin_container_image_self_build }}"} - when: "item.when | bool" - -- name: Ensure matrix-synapse-admin labels file is created - ansible.builtin.template: - src: "{{ role_path }}/templates/labels.j2" - dest: "{{ matrix_synapse_admin_base_path }}/labels" - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - mode: '0640' - register: matrix_synapse_admin_support_files_result - -- name: Ensure matrix-synapse-admin configuration installed - ansible.builtin.copy: - content: "{{ matrix_synapse_admin_configuration | to_nice_json }}" - dest: "{{ matrix_synapse_admin_config_path }}/config.json" - mode: '0644' - owner: "{{ matrix_user_name }}" - group: "{{ matrix_group_name }}" - register: matrix_synapse_admin_config_result - -- name: Ensure matrix-synapse-admin image is pulled - community.docker.docker_image: - name: "{{ matrix_synapse_admin_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_synapse_admin_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_synapse_admin_container_image_force_pull }}" - when: not matrix_synapse_admin_container_image_self_build | bool - register: matrix_synapse_admin_container_image_pull_result - retries: "{{ devture_playbook_help_container_retries_count }}" - delay: "{{ devture_playbook_help_container_retries_delay }}" - until: matrix_synapse_admin_container_image_pull_result is not failed - -- name: Ensure matrix-synapse-admin repository is present when self-building - ansible.builtin.git: - repo: "{{ matrix_synapse_admin_container_image_self_build_repo }}" - dest: "{{ matrix_synapse_admin_container_src_files_path }}" - version: "{{ matrix_synapse_admin_container_image.split(':')[1] }}" - force: "yes" - become: true - become_user: "{{ matrix_user_name }}" - register: matrix_synapse_admin_git_pull_results - when: matrix_synapse_admin_container_image_self_build | bool - -- name: Ensure matrix-synapse-admin Docker image is built - community.docker.docker_image: - name: "{{ matrix_synapse_admin_container_image }}" - source: build - force_source: "{{ matrix_synapse_admin_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_synapse_admin_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_synapse_admin_container_src_files_path }}" - pull: true - when: matrix_synapse_admin_container_image_self_build | bool - -- name: Ensure matrix-synapse-admin container network is created - community.general.docker_network: - enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" - name: "{{ matrix_synapse_admin_container_network }}" - driver: bridge - driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" - -- name: Ensure matrix-synapse-admin.service installed - ansible.builtin.template: - src: "{{ role_path }}/templates/systemd/matrix-synapse-admin.service.j2" - dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-synapse-admin.service" - mode: '0644' - register: matrix_synapse_admin_systemd_service_result - -- name: Determine whether Synapse Admin needs a restart - ansible.builtin.set_fact: - matrix_synapse_admin_restart_necessary: >- - {{ - matrix_synapse_admin_support_files_result.changed | default(false) - or matrix_synapse_admin_config_result.changed | default(false) - or matrix_synapse_admin_systemd_service_result.changed | default(false) - or matrix_synapse_admin_container_image_pull_result.changed | default(false) - }} diff --git a/roles/custom/matrix-synapse-admin/tasks/setup_uninstall.yml b/roles/custom/matrix-synapse-admin/tasks/setup_uninstall.yml deleted file mode 100644 index 5436bc82b..000000000 --- a/roles/custom/matrix-synapse-admin/tasks/setup_uninstall.yml +++ /dev/null @@ -1,29 +0,0 @@ -# SPDX-FileCopyrightText: 2022 - 2023 Slavi Pantaleev -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Check existence of matrix-synapse-admin service - ansible.builtin.stat: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-synapse-admin.service" - register: matrix_synapse_admin_service_stat - -- when: matrix_synapse_admin_service_stat.stat.exists | bool - block: - - name: Ensure matrix-synapse-admin is stopped - ansible.builtin.service: - name: matrix-synapse-admin - state: stopped - enabled: false - daemon_reload: true - - - name: Ensure matrix-synapse-admin.service doesn't exist - ansible.builtin.file: - path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-synapse-admin.service" - state: absent - - - name: Ensure matrix-synapse-admin directory doesn't exist - ansible.builtin.file: - path: "{{ matrix_synapse_admin_base_path }}" - state: absent diff --git a/roles/custom/matrix-synapse-admin/tasks/validate_config.yml b/roles/custom/matrix-synapse-admin/tasks/validate_config.yml deleted file mode 100644 index 77439ef8d..000000000 --- a/roles/custom/matrix-synapse-admin/tasks/validate_config.yml +++ /dev/null @@ -1,57 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2025 Slavi Pantaleev -# SPDX-FileCopyrightText: 2022 MDAD project contributors -# SPDX-FileCopyrightText: 2025 Suguru Hirahara -# -# SPDX-License-Identifier: AGPL-3.0-or-later - ---- - -- name: Fail if matrix-synapse-admin is enabled for a non-Synapse homeserver - ansible.builtin.fail: - msg: >- - matrix-synapse-admin can only be used with the Synapse homeserver implementation. - Your configuration has `matrix_synapse_admin_enabled: true`, but `matrix_homeserver_implementation` is set to `{{ matrix_homeserver_implementation }}`. - Disable matrix-synapse-admin or switch to Synapse. - when: - - matrix_synapse_admin_enabled | bool - - matrix_homeserver_implementation != 'synapse' - -- name: (Deprecation) Catch and report renamed matrix-synapse-admin settings - ansible.builtin.fail: - msg: >- - Your configuration contains a variable, which now has a different name. - Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). - when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" - with_items: - - {'old': 'matrix_synapse_admin_docker_repo', 'new': 'matrix_synapse_admin_container_self_build_repo'} - - {'old': 'matrix_synapse_admin_container_self_build', 'new': 'matrix_synapse_admin_container_image_self_build'} - - {'old': 'matrix_synapse_admin_container_self_build_repo', 'new': 'matrix_synapse_admin_container_image_self_build_repo'} - - {'old': 'matrix_synapse_admin_public_endpoint', 'new': 'matrix_synapse_admin_path_prefix'} - - {'old': 'matrix_synapse_admin_nginx_proxy_integration_enabled', 'new': '<removed>'} - - {'old': 'matrix_synapse_admin_docker_image_name_prefix', 'new': 'matrix_synapse_admin_container_image_registry_prefix'} - - {'old': 'matrix_synapse_admin_docker_image', 'new': 'matrix_synapse_admin_container_image'} - - {'old': 'matrix_synapse_admin_docker_image_force_pull', 'new': 'matrix_synapse_admin_container_image_force_pull'} - - {'old': 'matrix_synapse_admin_docker_image_registry_prefix', 'new': 'matrix_synapse_admin_container_image_registry_prefix'} - - {'old': 'matrix_synapse_admin_docker_image_registry_prefix_upstream', 'new': 'matrix_synapse_admin_container_image_registry_prefix_upstream'} - - {'old': 'matrix_synapse_admin_docker_image_registry_prefix_upstream_default', 'new': 'matrix_synapse_admin_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_synapse_admin_docker_src_files_path', 'new': 'matrix_synapse_admin_container_src_files_path'} - -- when: matrix_synapse_admin_container_labels_traefik_enabled | bool - block: - - name: Fail if required matrix-synapse-admin Traefik settings not defined - ansible.builtin.fail: - msg: >- - You need to define a required configuration setting (`{{ item }}`). - when: "lookup('vars', item, default='') == ''" - with_items: - - matrix_synapse_admin_container_labels_traefik_hostname - - matrix_synapse_admin_container_labels_traefik_path_prefix - - # We ensure it doesn't end with a slash, because we handle both (slash and no-slash). - # Knowing that `matrix_synapse_admin_container_labels_traefik_path_prefix` does not end with a slash - # ensures we know how to set these routes up without having to do "does it end with a slash" checks elsewhere. - - name: Fail if matrix_synapse_admin_container_labels_traefik_path_prefix ends with a slash - ansible.builtin.fail: - msg: >- - matrix_synapse_admin_container_labels_traefik_path_prefix (`{{ matrix_synapse_admin_container_labels_traefik_path_prefix }}`) must either be `/` or not end with a slash (e.g. `/synapse-admin`). - when: "matrix_synapse_admin_container_labels_traefik_path_prefix != '/' and matrix_synapse_admin_container_labels_traefik_path_prefix[-1] == '/'" diff --git a/roles/custom/matrix-synapse-admin/templates/labels.j2 b/roles/custom/matrix-synapse-admin/templates/labels.j2 deleted file mode 100644 index e030d49ca..000000000 --- a/roles/custom/matrix-synapse-admin/templates/labels.j2 +++ /dev/null @@ -1,58 +0,0 @@ -{# -SPDX-FileCopyrightText: 2023 - 2024 Slavi Pantaleev -SPDX-FileCopyrightText: 2025 MDAD project contributors - -SPDX-License-Identifier: AGPL-3.0-or-later -#} - -{% if matrix_synapse_admin_container_labels_traefik_enabled %} -traefik.enable=true - -{% if matrix_synapse_admin_container_labels_traefik_docker_network %} -traefik.docker.network={{ matrix_synapse_admin_container_labels_traefik_docker_network }} -{% endif %} - -traefik.http.services.matrix-synapse-admin.loadbalancer.server.port=8080 - -{% set middlewares = [] %} - -{% if matrix_synapse_admin_container_labels_traefik_ipallowlist_sourcerange | length > 0 %} -traefik.http.middlewares.matrix-synapse-admin-ipallowlist.ipallowlist.sourcerange={{ matrix_synapse_admin_container_labels_traefik_ipallowlist_sourcerange | join(',') }} -{% set middlewares = middlewares + ['matrix-synapse-admin-ipallowlist'] %} -{% endif %} - -{% if matrix_synapse_admin_container_labels_traefik_path_prefix != '/' %} -traefik.http.middlewares.matrix-synapse-admin-slashless-redirect.redirectregex.regex=({{ matrix_synapse_admin_container_labels_traefik_path_prefix | quote }})$ -traefik.http.middlewares.matrix-synapse-admin-slashless-redirect.redirectregex.replacement=${1}/ -{% set middlewares = middlewares + ['matrix-synapse-admin-slashless-redirect'] %} -{% endif %} - -{% if matrix_synapse_admin_container_labels_traefik_path_prefix != '/' %} -traefik.http.middlewares.matrix-synapse-admin-strip-prefix.stripprefix.prefixes={{ matrix_synapse_admin_container_labels_traefik_path_prefix }} -{% set middlewares = middlewares + ['matrix-synapse-admin-strip-prefix'] %} -{% endif %} - -{% if matrix_synapse_admin_container_labels_traefik_additional_response_headers.keys() | length > 0 %} -{% for name, value in matrix_synapse_admin_container_labels_traefik_additional_response_headers.items() %} -traefik.http.middlewares.matrix-synapse-admin-add-headers.headers.customresponseheaders.{{ name }}={{ value }} -{% endfor %} -{% set middlewares = middlewares + ['matrix-synapse-admin-add-headers'] %} -{% endif %} - -traefik.http.routers.matrix-synapse-admin.rule={{ matrix_synapse_admin_container_labels_traefik_rule }} -{% if matrix_synapse_admin_container_labels_traefik_priority | int > 0 %} -traefik.http.routers.matrix-synapse-admin.priority={{ matrix_synapse_admin_container_labels_traefik_priority }} -{% endif %} -{% if middlewares | length > 0 %} -traefik.http.routers.matrix-synapse-admin.middlewares={{ middlewares | join(',') }} -{% endif %} -traefik.http.routers.matrix-synapse-admin.service=matrix-synapse-admin -traefik.http.routers.matrix-synapse-admin.entrypoints={{ matrix_synapse_admin_container_labels_traefik_entrypoints }} -traefik.http.routers.matrix-synapse-admin.tls={{ matrix_synapse_admin_container_labels_traefik_tls | to_json }} -{% if matrix_synapse_admin_container_labels_traefik_tls %} -traefik.http.routers.matrix-synapse-admin.tls.certResolver={{ matrix_synapse_admin_container_labels_traefik_tls_certResolver }} -{% endif %} - -{% endif %} - -{{ matrix_synapse_admin_container_labels_additional_labels }} diff --git a/roles/custom/matrix-synapse-admin/templates/systemd/matrix-synapse-admin.service.j2.license b/roles/custom/matrix-synapse-admin/templates/systemd/matrix-synapse-admin.service.j2.license deleted file mode 100644 index 9b305e18b..000000000 --- a/roles/custom/matrix-synapse-admin/templates/systemd/matrix-synapse-admin.service.j2.license +++ /dev/null @@ -1,4 +0,0 @@ -SPDX-FileCopyrightText: 2020 - 2025 Slavi Pantaleev -SPDX-FileCopyrightText: 2020 Dan Arnfield - -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-synapse-auto-compressor/defaults/main.yml b/roles/custom/matrix-synapse-auto-compressor/defaults/main.yml index bb24afd4b..5cb83ba0d 100644 --- a/roles/custom/matrix-synapse-auto-compressor/defaults/main.yml +++ b/roles/custom/matrix-synapse-auto-compressor/defaults/main.yml @@ -33,7 +33,6 @@ matrix_synapse_auto_compressor_container_image: "{{ matrix_synapse_auto_compress matrix_synapse_auto_compressor_container_image_registry_prefix: "{{ 'localhost/' if matrix_synapse_auto_compressor_container_image_self_build else matrix_synapse_auto_compressor_container_image_registry_prefix_upstream }}" matrix_synapse_auto_compressor_container_image_registry_prefix_upstream: "{{ matrix_synapse_auto_compressor_container_image_registry_prefix_upstream_default }}" matrix_synapse_auto_compressor_container_image_registry_prefix_upstream_default: "registry.gitlab.com/" -matrix_synapse_auto_compressor_container_image_force_pull: "{{ matrix_synapse_auto_compressor_container_image.endswith(':latest') }}" # The base container network. It will be auto-created by this role if it doesn't exist already. matrix_synapse_auto_compressor_container_network: matrix-synapse-auto-compressor diff --git a/roles/custom/matrix-synapse-auto-compressor/molecule/default/converge.yml b/roles/custom/matrix-synapse-auto-compressor/molecule/default/converge.yml new file mode 100644 index 000000000..862fd3812 --- /dev/null +++ b/roles/custom/matrix-synapse-auto-compressor/molecule/default/converge.yml @@ -0,0 +1,63 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for matrix-synapse-auto-compressor Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include base roles for matrix-synapse-auto-compressor Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + loop_control: + loop_var: role_name + + # A genuine Synapse installation and migration is part of the fixture; hand-made subsets + # of the schema cannot establish compatibility with what Synapse actually deploys. + - name: Include Synapse setup task files + ansible.builtin.include_role: + name: custom/matrix-synapse + public: true + tasks_from: "{{ role_task_file }}" + loop: + - init.yml + - validate_config.yml + - setup_install.yml + loop_control: + loop_var: role_task_file + + - name: Include matrix-synapse-auto-compressor + ansible.builtin.include_role: + name: "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + public: true + vars: + matrix_synapse_auto_compressor_postgres_image: "{{ molecule_shared_image_postgres }}" + +- name: Start the Synapse fixture and compressor timer + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the Synapse systemd service is started + ansible.builtin.systemd_service: + name: matrix-synapse.service + state: started + + - name: Ensure the compressor timer is enabled and started + ansible.builtin.systemd_service: + name: matrix-synapse-auto-compressor.timer + enabled: true + state: started diff --git a/roles/custom/matrix-synapse-auto-compressor/molecule/default/molecule.yml b/roles/custom/matrix-synapse-auto-compressor/molecule/default/molecule.yml new file mode 100644 index 000000000..91c9ea3fa --- /dev/null +++ b/roles/custom/matrix-synapse-auto-compressor/molecule/default/molecule.yml @@ -0,0 +1,119 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: matrix-synapse-auto-compressor-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + # A real single-process Synapse supplies its migrated schema and the state groups + # exercised by the compressor. Optional Synapse topology stays out of this scenario. + matrix_synapse_workers_enabled: false + matrix_synapse_redis_enabled: false + matrix_synapse_reverse_proxy_companion_enabled: false + matrix_synapse_username: matrix + matrix_synapse_uid: 1234 + matrix_synapse_gid: 1234 + matrix_synapse_container_network: synapse-auto-compressor-molecule + matrix_synapse_container_client_api_port: 18008 + matrix_synapse_container_client_api_host_bind_port: '' + matrix_synapse_container_master_extra_arguments: + - "--health-cmd='curl -fSs http://localhost:18008/health'" + matrix_synapse_container_labels_traefik_enabled: false + matrix_synapse_container_labels_traefik_hostname: matrix.molecule.local + matrix_synapse_systemd_service_post_start_delay_seconds: 0 + + matrix_synapse_database_host: matrix-postgres-molecule + matrix_synapse_database_port: 5432 + matrix_synapse_database_user: molecule_compressor + matrix_synapse_database_password: molecule_compressor_pg_password_9b742d + matrix_synapse_database_database: molecule_compressor + + matrix_synapse_macaroon_secret_key: molecule_compressor_macaroon_4b3f891d + matrix_synapse_registration_shared_secret: molecule_compressor_registration_27ed51a8 + matrix_synapse_form_secret: molecule_compressor_form_96a04c7b + matrix_synapse_password_config_pepper: molecule_compressor_pepper_c0f371e6 + matrix_synapse_public_baseurl: http://matrix.molecule.local:18008/ + matrix_synapse_rc_message: + per_second: 1000 + burst_count: 1000 + matrix_synapse_trusted_key_servers: [] + matrix_synapse_suppress_key_server_warning: true + matrix_synapse_federation_enabled: false + matrix_synapse_federation_port_openid_resource_required: false + matrix_synapse_tls_federation_listener_enabled: false + matrix_synapse_metrics_enabled: false + matrix_synapse_email_enabled: false + matrix_synapse_matrix_authentication_service_enabled: false + matrix_authentication_service_migration_in_progress: false + matrix_synapse_ext_synapse_s3_storage_provider_enabled: false + matrix_s3_media_store_enabled: false + matrix_playbook_ssl_enabled: false + + # These non-defaults exercise every role-supplied runtime and scheduling input. + matrix_synapse_auto_compressor_uid: 1234 + matrix_synapse_auto_compressor_gid: 1234 + matrix_synapse_auto_compressor_container_network: synapse-auto-compressor-molecule + matrix_synapse_auto_compressor_container_additional_networks: + - synapse-auto-compressor-extra-molecule + matrix_synapse_auto_compressor_container_extra_arguments: + - "--label=molecule.contract=synapse-auto-compressor" + matrix_synapse_auto_compressor_database_hostname: matrix-postgres-molecule + matrix_synapse_auto_compressor_database_port: 5432 + matrix_synapse_auto_compressor_database_username: molecule_compressor + matrix_synapse_auto_compressor_database_password: molecule_compressor_pg_password_9b742d + matrix_synapse_auto_compressor_database_name: molecule_compressor + matrix_synapse_auto_compressor_schedule: "Mon..Fri *-*-* 03:17:00" + matrix_synapse_auto_compressor_schedule_randomized_delay_sec: 47min + matrix_synapse_auto_compressor_chunk_size: 128 + matrix_synapse_auto_compressor_chunks_to_compress: 2 + # Keep the transient container alive briefly after genuine compression so verify.yml + # can inspect the runtime contract before Type=oneshot removes it. + matrix_synapse_auto_compressor_command: >- + synapse_auto_compressor -p $$POSTGRES_LOCATION -c 128 -n 2 && sleep 45 + + # verify.yml is a separate play, so paths derived from role defaults are pinned here. + matrix_synapse_base_path: /matrix/synapse + matrix_synapse_config_dir_path: /matrix/synapse/config + matrix_synapse_storage_path: /matrix/synapse/storage + matrix_synapse_media_store_path: /matrix/synapse/storage/media-store + matrix_synapse_auto_compressor_base_path: /matrix/synapse-auto-compressor + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-synapse-auto-compressor/molecule/default/prepare.yml b/roles/custom/matrix-synapse-auto-compressor/molecule/default/prepare.yml new file mode 100644 index 000000000..76c4674ce --- /dev/null +++ b/roles/custom/matrix-synapse-auto-compressor/molecule/default/prepare.yml @@ -0,0 +1,128 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare matrix-synapse-auto-compressor Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + # Synapse's production unit uses slave bind propagation for the media store. + - name: Ensure nested Docker can use Synapse media-store bind propagation + ansible.builtin.command: + argv: + - mount + - --make-rshared + - / + changed_when: false + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: '0750' + + # Postgres must attach before the role creates this network during converge. + - name: Ensure the shared Synapse and compressor network exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_synapse_auto_compressor_container_network }}" + register: matrix_synapse_auto_compressor_molecule_network + changed_when: matrix_synapse_auto_compressor_molecule_network.rc == 0 + failed_when: + - matrix_synapse_auto_compressor_molecule_network.rc != 0 + - "'already exists' not in matrix_synapse_auto_compressor_molecule_network.stderr" + + - name: Ensure the compressor additional network exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_synapse_auto_compressor_container_additional_networks | first }}" + register: matrix_synapse_auto_compressor_molecule_additional_network + changed_when: matrix_synapse_auto_compressor_molecule_additional_network.rc == 0 + failed_when: + - matrix_synapse_auto_compressor_molecule_additional_network.rc != 0 + - "'already exists' not in matrix_synapse_auto_compressor_molecule_additional_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_synapse_auto_compressor_container_network }}" + molecule_shared_postgres_database: "{{ matrix_synapse_database_database }}" + molecule_shared_postgres_username: "{{ matrix_synapse_database_user }}" + molecule_shared_postgres_password: "{{ matrix_synapse_database_password }}" + + # Synapse refuses locale-dependent database collation. + - name: Remove the locale-dependent empty Synapse database + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_synapse_database_user }} + - --dbname=postgres + - --command=DROP DATABASE IF EXISTS "{{ matrix_synapse_database_database }}" + changed_when: true + + - name: Create the empty Synapse database with C collation + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_synapse_database_user }} + - --dbname=postgres + - >- + --command=CREATE DATABASE "{{ matrix_synapse_database_database }}" + OWNER "{{ matrix_synapse_database_user }}" TEMPLATE template0 + LC_COLLATE 'C' LC_CTYPE 'C' + changed_when: true diff --git a/roles/custom/matrix-synapse-auto-compressor/molecule/default/requirements.yml b/roles/custom/matrix-synapse-auto-compressor/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-synapse-auto-compressor/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-synapse-auto-compressor/molecule/default/verify.yml b/roles/custom/matrix-synapse-auto-compressor/molecule/default/verify.yml new file mode 100644 index 000000000..7df084117 --- /dev/null +++ b/roles/custom/matrix-synapse-auto-compressor/molecule/default/verify.yml @@ -0,0 +1,591 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves the role drives the real compressor against a genuinely migrated Synapse +# Postgres database, and observes the otherwise-transient container while it runs. +- name: Verify matrix-synapse-auto-compressor + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + vars: + matrix_synapse_auto_compressor_expected_postgres_location: >- + postgres://molecule_compressor:molecule_compressor_pg_password_9b742d@matrix-postgres-molecule:5432/molecule_compressor + matrix_synapse_auto_compressor_expected_command: >- + synapse_auto_compressor -p $POSTGRES_LOCATION -c 128 -n 2 && sleep 45 + matrix_synapse_auto_compressor_seed_username: compressor-admin + matrix_synapse_auto_compressor_seed_password: molecule_compressor_admin_password_1d3b + + tasks: + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_synapse_auto_compressor_role_defaults + + - name: Wait for the Synapse fixture to become active + ansible.builtin.systemd_service: + name: matrix-synapse.service + register: matrix_synapse_auto_compressor_synapse_service + until: matrix_synapse_auto_compressor_synapse_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + - name: Request the real Synapse health endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_synapse_auto_compressor_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-synapse:{{ matrix_synapse_container_client_api_port }}/health + register: matrix_synapse_auto_compressor_synapse_health + changed_when: false + until: "'HTTP_STATUS=200' in matrix_synapse_auto_compressor_synapse_health.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert the real Synapse fixture is healthy and stable + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_synapse_service.status.ActiveState == 'active' + - matrix_synapse_auto_compressor_synapse_service.status.NRestarts is defined + - matrix_synapse_auto_compressor_synapse_service.status.NRestarts | int == 0 + - matrix_synapse_auto_compressor_synapse_health.rc == 0 + - "'HTTP_STATUS=200' in matrix_synapse_auto_compressor_synapse_health.stdout" + - matrix_synapse_auto_compressor_synapse_health.stdout.startswith('OK') + fail_msg: "The real Synapse fixture is not healthy and stable" + success_msg: "The real Synapse fixture is healthy and stable" + + # These tables can only be present after Synapse resolved the configured hostname, + # authenticated to Postgres, and performed its own migrations. + - name: List the tables Synapse created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_synapse_database_user }} + - --dbname={{ matrix_synapse_database_database }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: matrix_synapse_auto_compressor_synapse_tables + changed_when: false + + - name: Assert Synapse genuinely migrated the compressor database + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_synapse_tables.rc == 0 + - "'schema_version' in matrix_synapse_auto_compressor_synapse_table_names" + - "'rooms' in matrix_synapse_auto_compressor_synapse_table_names" + - "'events' in matrix_synapse_auto_compressor_synapse_table_names" + - "'state_groups' in matrix_synapse_auto_compressor_synapse_table_names" + - "'state_groups_state' in matrix_synapse_auto_compressor_synapse_table_names" + - matrix_synapse_auto_compressor_synapse_table_names | length > 50 + fail_msg: "Synapse did not genuinely migrate the configured Postgres database" + success_msg: "Synapse genuinely migrated the configured Postgres database" + vars: + matrix_synapse_auto_compressor_synapse_table_names: >- + {{ matrix_synapse_auto_compressor_synapse_tables.stdout_lines | select | list }} + + - name: Register the local compressor fixture administrator + ansible.builtin.command: + argv: + - docker + - exec + - matrix-synapse + - register_new_matrix_user + - --config + - /data/homeserver.yaml + - --user + - "{{ matrix_synapse_auto_compressor_seed_username }}" + - --password + - "{{ matrix_synapse_auto_compressor_seed_password }}" + - --admin + - http://localhost:{{ matrix_synapse_container_client_api_port }} + register: matrix_synapse_auto_compressor_registration + changed_when: matrix_synapse_auto_compressor_registration.rc == 0 + failed_when: + - matrix_synapse_auto_compressor_registration.rc != 0 + - "'User ID already taken' not in matrix_synapse_auto_compressor_registration.stdout" + no_log: true + + - name: Log the local fixture administrator in to Synapse + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_synapse_auto_compressor_container_network }} + - "{{ molecule_shared_image_curl }}" + - --fail-with-body + - --silent + - --show-error + - --request + - POST + - --header + - 'Content-Type: application/json' + - --data + - >- + {"type":"m.login.password","identifier":{"type":"m.id.user","user":"{{ matrix_synapse_auto_compressor_seed_username }}"},"password":"{{ matrix_synapse_auto_compressor_seed_password }}"} + - http://matrix-synapse:{{ matrix_synapse_container_client_api_port }}/_matrix/client/v3/login + register: matrix_synapse_auto_compressor_login_response + changed_when: false + no_log: true + + - name: Parse the local fixture login response + ansible.builtin.set_fact: + matrix_synapse_auto_compressor_login: "{{ matrix_synapse_auto_compressor_login_response.stdout | from_json }}" + no_log: true + + - name: Assert Synapse authenticated the local fixture administrator + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_login.access_token is string + - matrix_synapse_auto_compressor_login.access_token | length > 20 + - matrix_synapse_auto_compressor_login.user_id == '@' + matrix_synapse_auto_compressor_seed_username + ':' + matrix_domain + fail_msg: "Synapse did not authenticate the local compressor fixture administrator" + success_msg: "Synapse authenticated the local compressor fixture administrator" + no_log: true + + - name: Create a real Matrix room for compressor state + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_synapse_auto_compressor_container_network }} + - "{{ molecule_shared_image_curl }}" + - --fail-with-body + - --silent + - --show-error + - --request + - POST + - --header + - 'Content-Type: application/json' + - --header + - 'Authorization: Bearer {{ matrix_synapse_auto_compressor_login.access_token }}' + - --data + - '{"preset":"private_chat","name":"Compressor Molecule State"}' + - http://matrix-synapse:{{ matrix_synapse_container_client_api_port }}/_matrix/client/v3/createRoom + register: matrix_synapse_auto_compressor_room_response + changed_when: true + no_log: true + + - name: Parse the real Matrix room response + ansible.builtin.set_fact: + matrix_synapse_auto_compressor_room: "{{ matrix_synapse_auto_compressor_room_response.stdout | from_json }}" + no_log: true + + # A unique state key per request creates enough genuine Synapse state groups for the + # non-default chunk size to consume a complete chunk, without manufacturing database rows. + - name: Populate the room with genuine state transitions through Synapse + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_synapse_auto_compressor_container_network }} + - --env=ACCESS_TOKEN={{ matrix_synapse_auto_compressor_login.access_token }} + - --env=ROOM_ID={{ matrix_synapse_auto_compressor_room.room_id }} + - --entrypoint=/bin/sh + - "{{ molecule_shared_image_curl }}" + - -c + - |- + set -eu; + i=1; + while [ "$i" -le 140 ]; do + curl --fail-with-body --silent --show-error \ + --request PUT \ + --header "Authorization: Bearer $ACCESS_TOKEN" \ + --header 'Content-Type: application/json' \ + --data "{\"sequence\":$i}" \ + "http://matrix-synapse:{{ matrix_synapse_container_client_api_port }}/_matrix/client/v3/rooms/$ROOM_ID/state/com.example.molecule/$i" \ + >/dev/null; + i=$((i + 1)); + done + register: matrix_synapse_auto_compressor_seed_result + changed_when: matrix_synapse_auto_compressor_seed_result.rc == 0 + failed_when: false + no_log: true + + - name: Report a sanitized state-seeding failure + ansible.builtin.debug: + msg: "{{ matrix_synapse_auto_compressor_seed_result.stderr }}" + when: matrix_synapse_auto_compressor_seed_result.rc != 0 + + - name: Assert Synapse accepted every real state transition + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_seed_result.rc == 0 + fail_msg: "Synapse rejected one of the real Matrix state transitions" + success_msg: "Synapse accepted every real Matrix state transition" + + - name: Count genuine state groups for the Matrix room + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_synapse_database_user }} + - --dbname={{ matrix_synapse_database_database }} + - --tuples-only + - --no-align + - >- + --command=SELECT COUNT(*) FROM state_groups + WHERE room_id = '{{ matrix_synapse_auto_compressor_room.room_id }}' + register: matrix_synapse_auto_compressor_state_group_count + changed_when: false + + - name: Assert Synapse created enough genuine state groups for a complete chunk + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_state_group_count.rc == 0 + - matrix_synapse_auto_compressor_state_group_count.stdout | trim | int >= matrix_synapse_auto_compressor_chunk_size | int + fail_msg: "The Matrix API fixture did not create a complete real compressor chunk" + success_msg: "The Matrix API fixture created a complete real compressor chunk" + + - name: Read the rendered compressor files + ansible.builtin.slurp: + src: "{{ item }}" + loop: + - "{{ matrix_synapse_auto_compressor_base_path }}/env" + - "{{ matrix_synapse_auto_compressor_base_path }}/matrix-synapse-auto-compressor-fix.sh" + - /etc/systemd/system/matrix-synapse-auto-compressor.service + - /etc/systemd/system/matrix-synapse-auto-compressor.timer + register: matrix_synapse_auto_compressor_rendered_files + + - name: Inspect the rendered compressor file identities + ansible.builtin.stat: + path: "{{ item }}" + loop: + - "{{ matrix_synapse_auto_compressor_base_path }}" + - "{{ matrix_synapse_auto_compressor_base_path }}/env" + - "{{ matrix_synapse_auto_compressor_base_path }}/matrix-synapse-auto-compressor-fix.sh" + - /etc/systemd/system/matrix-synapse-auto-compressor.service + - /etc/systemd/system/matrix-synapse-auto-compressor.timer + register: matrix_synapse_auto_compressor_rendered_stats + + - name: Parse the rendered compressor files + ansible.builtin.set_fact: + matrix_synapse_auto_compressor_rendered_env: "{{ matrix_synapse_auto_compressor_rendered_files.results[0].content | b64decode }}" + matrix_synapse_auto_compressor_rendered_script: "{{ matrix_synapse_auto_compressor_rendered_files.results[1].content | b64decode }}" + matrix_synapse_auto_compressor_rendered_service: "{{ matrix_synapse_auto_compressor_rendered_files.results[2].content | b64decode }}" + matrix_synapse_auto_compressor_rendered_timer: "{{ matrix_synapse_auto_compressor_rendered_files.results[3].content | b64decode }}" + + - name: Check the workaround script syntax + ansible.builtin.command: + argv: + - bash + - -n + - "{{ matrix_synapse_auto_compressor_base_path }}/matrix-synapse-auto-compressor-fix.sh" + register: matrix_synapse_auto_compressor_script_syntax + changed_when: false + + - name: Verify systemd parsed the rendered units + ansible.builtin.command: + argv: + - systemd-analyze + - verify + - matrix-synapse-auto-compressor.service + - matrix-synapse-auto-compressor.timer + register: matrix_synapse_auto_compressor_unit_syntax + changed_when: false + + - name: Verify systemd parsed the non-default calendar + ansible.builtin.command: + argv: + - systemd-analyze + - calendar + - "{{ matrix_synapse_auto_compressor_schedule }}" + register: matrix_synapse_auto_compressor_calendar_syntax + changed_when: false + + - name: Assert the rendered environment carries the exact Postgres connection + ansible.builtin.assert: + that: + - "'POSTGRES_LOCATION=' + matrix_synapse_auto_compressor_expected_postgres_location in matrix_synapse_auto_compressor_rendered_env.splitlines()" + - "'PGHOST=' + matrix_synapse_auto_compressor_database_hostname in matrix_synapse_auto_compressor_rendered_env.splitlines()" + - "'PGDATABASE=' + matrix_synapse_auto_compressor_database_name in matrix_synapse_auto_compressor_rendered_env.splitlines()" + - "'PGUSER=' + matrix_synapse_auto_compressor_database_username in matrix_synapse_auto_compressor_rendered_env.splitlines()" + - "'PGPASSWORD=' + matrix_synapse_auto_compressor_database_password in matrix_synapse_auto_compressor_rendered_env.splitlines()" + fail_msg: "The rendered environment does not carry the exact scenario Postgres connection" + success_msg: "The rendered environment carries the exact scenario Postgres connection" + no_log: true + + - name: Assert the rendered workaround script contract + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_script_syntax.rc == 0 + - "'--user=1234:1234' in matrix_synapse_auto_compressor_rendered_script" + - "'--cap-drop=ALL' in matrix_synapse_auto_compressor_rendered_script" + - "'--network=' + matrix_synapse_auto_compressor_container_network in matrix_synapse_auto_compressor_rendered_script" + - molecule_shared_image_postgres in matrix_synapse_auto_compressor_rendered_script + - "'psql -h ' + matrix_synapse_auto_compressor_database_hostname in matrix_synapse_auto_compressor_rendered_script" + - "'DELETE\nFROM state_compressor_state' in matrix_synapse_auto_compressor_rendered_script" + - "'DELETE\nFROM state_compressor_progress' in matrix_synapse_auto_compressor_rendered_script" + fail_msg: "The rendered workaround script does not carry its runtime and cleanup contract" + success_msg: "The rendered workaround script carries its runtime and cleanup contract" + + - name: Assert the rendered oneshot service contract + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_unit_syntax.rc == 0 + - "'Type=oneshot' in matrix_synapse_auto_compressor_rendered_service" + - "'--rm' in matrix_synapse_auto_compressor_rendered_service" + - "'--log-driver=none' in matrix_synapse_auto_compressor_rendered_service" + - "'--cap-drop=ALL' in matrix_synapse_auto_compressor_rendered_service" + - "'--read-only' in matrix_synapse_auto_compressor_rendered_service" + - "'--user=1234:1234' in matrix_synapse_auto_compressor_rendered_service" + - "'--network=' + matrix_synapse_auto_compressor_container_network in matrix_synapse_auto_compressor_rendered_service" + - "'--label=molecule.contract=synapse-auto-compressor' in matrix_synapse_auto_compressor_rendered_service" + - matrix_synapse_auto_compressor_expected_command in matrix_synapse_auto_compressor_rendered_service + - "'network connect synapse-auto-compressor-extra-molecule matrix-synapse-auto-compressor' in matrix_synapse_auto_compressor_rendered_service" + fail_msg: "The rendered service does not carry the exact oneshot runtime contract" + success_msg: "The rendered service carries the exact oneshot runtime contract" + + - name: Assert the rendered non-default timer contract + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_calendar_syntax.rc == 0 + - "'Unit=matrix-synapse-auto-compressor.service' in matrix_synapse_auto_compressor_rendered_timer" + - "'OnCalendar=Mon..Fri *-*-* 03:17:00' in matrix_synapse_auto_compressor_rendered_timer" + - "'RandomizedDelaySec=47min' in matrix_synapse_auto_compressor_rendered_timer" + fail_msg: "The rendered timer does not carry the non-default schedule" + success_msg: "The rendered timer carries the non-default schedule" + + - name: Assert the rendered file identities + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_rendered_stats.results[0].stat.uid | int == matrix_user_uid | int + - matrix_synapse_auto_compressor_rendered_stats.results[0].stat.gid | int == matrix_user_gid | int + - matrix_synapse_auto_compressor_rendered_stats.results[0].stat.mode == '0750' + - matrix_synapse_auto_compressor_rendered_stats.results[1].stat.uid | int == matrix_user_uid | int + - matrix_synapse_auto_compressor_rendered_stats.results[1].stat.gid | int == matrix_user_gid | int + - matrix_synapse_auto_compressor_rendered_stats.results[1].stat.mode == '0640' + - matrix_synapse_auto_compressor_rendered_stats.results[2].stat.uid | int == matrix_user_uid | int + - matrix_synapse_auto_compressor_rendered_stats.results[2].stat.gid | int == matrix_user_gid | int + - matrix_synapse_auto_compressor_rendered_stats.results[2].stat.mode == '0750' + - matrix_synapse_auto_compressor_rendered_stats.results[3].stat.uid | int == 0 + - matrix_synapse_auto_compressor_rendered_stats.results[3].stat.gid | int == 0 + - matrix_synapse_auto_compressor_rendered_stats.results[3].stat.mode == '0644' + - matrix_synapse_auto_compressor_rendered_stats.results[4].stat.uid | int == 0 + - matrix_synapse_auto_compressor_rendered_stats.results[4].stat.gid | int == 0 + - matrix_synapse_auto_compressor_rendered_stats.results[4].stat.mode == '0644' + fail_msg: "The compressor paths and rendered files have the wrong identity or mode" + success_msg: "The compressor paths and rendered files have the expected identities and modes" + + - name: Inspect the enabled compressor timer + ansible.builtin.systemd_service: + name: matrix-synapse-auto-compressor.timer + register: matrix_synapse_auto_compressor_timer + + - name: Assert the compressor timer is enabled and active + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_timer.status.ActiveState == 'active' + - matrix_synapse_auto_compressor_timer.status.SubState == 'waiting' + - matrix_synapse_auto_compressor_timer.status.UnitFileState == 'enabled' + - matrix_synapse_auto_compressor_timer.status.NextElapseUSecRealtime is defined + - matrix_synapse_auto_compressor_timer.status.NextElapseUSecRealtime != 'infinity' + fail_msg: "The compressor timer is not enabled and waiting on its parsed schedule" + success_msg: "The compressor timer is enabled and waiting on its parsed schedule" + + # no_block gives the test a window to inspect this otherwise-transient container. The + # command has already performed genuine compression before its final short sleep. + - name: Start the real compressor asynchronously + ansible.builtin.systemd_service: + name: matrix-synapse-auto-compressor.service + state: started + no_block: true + changed_when: true + + - name: Wait for the transient compressor container to become inspectable + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-synapse-auto-compressor + register: matrix_synapse_auto_compressor_container_inspect + changed_when: false + until: matrix_synapse_auto_compressor_container_inspect.rc == 0 + retries: 30 + delay: 1 + failed_when: false + + - name: Parse the transient compressor container inspection + ansible.builtin.set_fact: + matrix_synapse_auto_compressor_container: >- + {{ (matrix_synapse_auto_compressor_container_inspect.stdout | from_json) | first }} + + - name: Assert the live container uses the exact pinned image + ansible.builtin.assert: + that: + - >- + matrix_synapse_auto_compressor_container.Config.Image == + 'registry.gitlab.com/mb-saces/rust-synapse-tools:' + matrix_synapse_auto_compressor_role_defaults.matrix_synapse_auto_compressor_version + fail_msg: "The live compressor container does not use the image defaults/main.yml pins" + success_msg: "The live compressor container uses the image defaults/main.yml pins" + + - name: Assert the live container process and environment contract + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_container.Config.User == '1234:1234' + - matrix_synapse_auto_compressor_container.Config.Entrypoint == ['/bin/sh'] + - matrix_synapse_auto_compressor_container.Config.Cmd == ['-c', matrix_synapse_auto_compressor_expected_command] + - "'POSTGRES_LOCATION=' + matrix_synapse_auto_compressor_expected_postgres_location in matrix_synapse_auto_compressor_container.Config.Env" + - "'PGHOST=' + matrix_synapse_auto_compressor_database_hostname in matrix_synapse_auto_compressor_container.Config.Env" + - "'PGDATABASE=' + matrix_synapse_auto_compressor_database_name in matrix_synapse_auto_compressor_container.Config.Env" + - "'PGUSER=' + matrix_synapse_auto_compressor_database_username in matrix_synapse_auto_compressor_container.Config.Env" + - "'PGPASSWORD=' + matrix_synapse_auto_compressor_database_password in matrix_synapse_auto_compressor_container.Config.Env" + fail_msg: "The live compressor process does not carry the exact identity, command, and environment" + success_msg: "The live compressor process carries the exact identity, command, and environment" + no_log: true + + - name: Assert the live container security contract + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_container.HostConfig.AutoRemove + - matrix_synapse_auto_compressor_container.HostConfig.ReadonlyRootfs + - "'ALL' in matrix_synapse_auto_compressor_container.HostConfig.CapDrop" + - matrix_synapse_auto_compressor_container.HostConfig.LogConfig.Type == 'none' + - matrix_synapse_auto_compressor_container.Mounts | length == 0 + fail_msg: "The live compressor container does not carry its ephemeral security isolation" + success_msg: "The live compressor container carries its ephemeral security isolation" + + - name: Assert the live container network contract + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_container_network in matrix_synapse_auto_compressor_container.NetworkSettings.Networks + - "'synapse-auto-compressor-extra-molecule' in matrix_synapse_auto_compressor_container.NetworkSettings.Networks" + - matrix_synapse_auto_compressor_container.NetworkSettings.Networks | length == 2 + fail_msg: "The live compressor container does not have exactly its two configured networks" + success_msg: "The live compressor container has exactly its two configured networks" + + - name: Assert the live container publishes no host ports + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_container.HostConfig.PortBindings | default({}, true) | length == 0 + - matrix_synapse_auto_compressor_container.Config.ExposedPorts | default({}, true) | length == 0 + fail_msg: "The live compressor container unexpectedly publishes a host port" + success_msg: "The live compressor container publishes no host ports" + + - name: Assert the live container carries the scenario label + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_container.Config.Labels['molecule.contract'] == 'synapse-auto-compressor' + fail_msg: "The live compressor container does not carry its configured label" + success_msg: "The live compressor container carries its configured label" + + - name: Wait for the oneshot compressor to finish + ansible.builtin.systemd_service: + name: matrix-synapse-auto-compressor.service + register: matrix_synapse_auto_compressor_service + until: matrix_synapse_auto_compressor_service.status.ActiveState in ['inactive', 'failed'] + retries: 60 + delay: 1 + failed_when: false + + - name: Assert the real compressor oneshot completed cleanly + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_service.status.ActiveState == 'inactive' + - matrix_synapse_auto_compressor_service.status.Result == 'success' + - matrix_synapse_auto_compressor_service.status.ExecMainCode == '1' + - matrix_synapse_auto_compressor_service.status.ExecMainStatus | int == 0 + - matrix_synapse_auto_compressor_service.status.NRestarts is defined + - matrix_synapse_auto_compressor_service.status.NRestarts | int == 0 + fail_msg: "The real compressor oneshot did not complete cleanly" + success_msg: "The real compressor oneshot completed cleanly" + + - name: List the compressor-owned Postgres tables + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_synapse_database_user }} + - --dbname={{ matrix_synapse_database_database }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tablename LIKE 'state_compressor_%' + register: matrix_synapse_auto_compressor_owned_tables + changed_when: false + + - name: Count rows in the compressor-owned progress tables + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_synapse_database_user }} + - --dbname={{ matrix_synapse_database_database }} + - --tuples-only + - --no-align + - >- + --command=SELECT + (SELECT COUNT(*) FROM state_compressor_state) || '|' || + (SELECT COUNT(*) FROM state_compressor_progress) || '|' || + (SELECT COUNT(*) FROM state_compressor_total_progress) || '|' || + (SELECT COUNT(*) FROM state_compressor_state + WHERE room_id = '{{ matrix_synapse_auto_compressor_room.room_id }}') || '|' || + (SELECT COUNT(*) FROM state_compressor_progress + WHERE room_id = '{{ matrix_synapse_auto_compressor_room.room_id }}') + register: matrix_synapse_auto_compressor_progress_counts + changed_when: false + + - name: Assert the real compressor created durable database-side progress + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_owned_tables.rc == 0 + - "'state_compressor_state' in matrix_synapse_auto_compressor_owned_table_names" + - "'state_compressor_progress' in matrix_synapse_auto_compressor_owned_table_names" + - "'state_compressor_total_progress' in matrix_synapse_auto_compressor_owned_table_names" + - matrix_synapse_auto_compressor_progress_counts.rc == 0 + - matrix_synapse_auto_compressor_progress_count_values | length == 5 + - matrix_synapse_auto_compressor_progress_count_values[0] | int > 0 + - matrix_synapse_auto_compressor_progress_count_values[1] | int > 0 + - matrix_synapse_auto_compressor_progress_count_values[2] | int > 0 + - matrix_synapse_auto_compressor_progress_count_values[3] | int > 0 + - matrix_synapse_auto_compressor_progress_count_values[4] | int > 0 + fail_msg: "The real compressor did not leave durable progress for the API-created room" + success_msg: "The real compressor left durable progress for the API-created room and globally" + vars: + matrix_synapse_auto_compressor_owned_table_names: >- + {{ matrix_synapse_auto_compressor_owned_tables.stdout_lines | select | list }} + matrix_synapse_auto_compressor_progress_count_values: >- + {{ matrix_synapse_auto_compressor_progress_counts.stdout | trim | split('|') }} + + - name: Confirm the ephemeral compressor container was removed + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-synapse-auto-compressor + register: matrix_synapse_auto_compressor_removed_container + changed_when: false + failed_when: false + + - name: Assert the completed compressor container was removed + ansible.builtin.assert: + that: + - matrix_synapse_auto_compressor_removed_container.rc != 0 + fail_msg: "The completed ephemeral compressor container was not removed" + success_msg: "The completed ephemeral compressor container was removed" diff --git a/roles/custom/matrix-synapse-auto-compressor/tasks/install.yml b/roles/custom/matrix-synapse-auto-compressor/tasks/install.yml index e9201a6ea..e64a32aaa 100644 --- a/roles/custom/matrix-synapse-auto-compressor/tasks/install.yml +++ b/roles/custom/matrix-synapse-auto-compressor/tasks/install.yml @@ -39,11 +39,9 @@ register: matrix_synapse_auto_compressor_config_script_result - name: Ensure synapse-auto-compressor image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_synapse_auto_compressor_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_synapse_auto_compressor_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_synapse_auto_compressor_container_image_force_pull }}" + pull: always when: "not matrix_synapse_auto_compressor_container_image_self_build | bool" register: matrix_synapse_auto_compressor_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -53,6 +51,15 @@ - when: "matrix_synapse_auto_compressor_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure synapse-auto-compressor repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_synapse_auto_compressor_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure synapse-auto-compressor repository is present on self-build ansible.builtin.git: repo: "{{ matrix_synapse_auto_compressor_container_image_self_build_repo }}" @@ -85,6 +92,7 @@ when: "matrix_synapse_auto_compressor_git_pull_results.changed | bool or matrix_synapse_auto_compressor_container_image_check_result.stdout == ''" - name: Ensure matrix-synapse-auto-compressor container network is created + when: matrix_synapse_auto_compressor_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_synapse_auto_compressor_container_network }}" diff --git a/roles/custom/matrix-synapse-auto-compressor/tasks/validate_config.yml b/roles/custom/matrix-synapse-auto-compressor/tasks/validate_config.yml index 65108ad85..b398122c8 100644 --- a/roles/custom/matrix-synapse-auto-compressor/tasks/validate_config.yml +++ b/roles/custom/matrix-synapse-auto-compressor/tasks/validate_config.yml @@ -15,6 +15,8 @@ "new": "matrix_synapse_auto_compressor_schedule" - "old": "matrix_synapse_auto_compressor_container_image_name_prefix" "new": "matrix_synapse_auto_compressor_container_image_registry_prefix" + - "old": "matrix_synapse_auto_compressor_container_image_force_pull" + "new": "<removed> (the new community.docker.docker_image_pull module handles this natively)" - name: Fail if required matrix-synapse-auto-compressor settings not defined ansible.builtin.fail: diff --git a/roles/custom/matrix-synapse-auto-compressor/templates/matrix-synapse-auto-compressor.service.j2 b/roles/custom/matrix-synapse-auto-compressor/templates/matrix-synapse-auto-compressor.service.j2 index 07435ee37..b5a36cefe 100644 --- a/roles/custom/matrix-synapse-auto-compressor/templates/matrix-synapse-auto-compressor.service.j2 +++ b/roles/custom/matrix-synapse-auto-compressor/templates/matrix-synapse-auto-compressor.service.j2 @@ -33,9 +33,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {{ matrix_synapse_auto_compressor_container_image }} \ -c '{{ matrix_synapse_auto_compressor_command }}' +{% if matrix_synapse_auto_compressor_container_network != 'host' %} {% for network in matrix_synapse_auto_compressor_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-synapse-auto-compressor {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-synapse-auto-compressor diff --git a/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml b/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml index 464676afe..030581bc9 100644 --- a/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml +++ b/roles/custom/matrix-synapse-usage-exporter/defaults/main.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2024 - 2025 Slavi Pantaleev +# SPDX-FileCopyrightText: 2024 - 2026 Slavi Pantaleev # SPDX-FileCopyrightText: 2024 Michael Hollister # SPDX-FileCopyrightText: 2024 Suguru Hirahara # @@ -11,8 +11,11 @@ matrix_synapse_usage_exporter_enabled: false -# Controls the hostname and path that this component exposes its web services on. +# Controls the hostname and path that the usage-stats ingestion endpoint is exposed on. # Only used if `matrix_synapse_usage_exporter_proxying_enabled` is true. +# +# The metrics endpoint is exposed separately. +# See `matrix_synapse_usage_exporter_metrics_proxying_enabled` and friends. matrix_synapse_usage_exporter_hostname: "{{ matrix_server_fqn_matrix }}" matrix_synapse_usage_exporter_path_prefix: /report-usage-stats/push @@ -32,7 +35,6 @@ matrix_synapse_usage_exporter_container_image_registry_prefix: "{{ 'localhost/' matrix_synapse_usage_exporter_container_image_registry_prefix_upstream: "{{ matrix_synapse_usage_exporter_container_image_registry_prefix_upstream_default }}" matrix_synapse_usage_exporter_container_image_registry_prefix_upstream_default: "docker.io/" matrix_synapse_usage_exporter_container_image_tag: "{{ 'main' if matrix_synapse_usage_exporter_container_image_self_build else 'latest' }}" -matrix_synapse_usage_exporter_container_image_force_pull: "{{ matrix_synapse_usage_exporter_container_image.endswith(':latest') }}" matrix_synapse_usage_exporter_base_path: "{{ matrix_base_data_path }}/{{ matrix_synapse_usage_exporter_identifier }}" matrix_synapse_usage_exporter_docker_src_files_path: "{{ matrix_synapse_usage_exporter_base_path }}/docker-src" @@ -57,19 +59,34 @@ matrix_synapse_usage_exporter_container_additional_networks: [] # Extra arguments for the Docker container matrix_synapse_usage_exporter_container_extra_arguments: [] -# Controls whether the synapse-usage-exporter's web services should be proxied (exposed publicly). +# Controls whether the synapse-usage-exporter's usage-stats ingestion endpoint should be proxied (exposed publicly). # # Exposure happens on `matrix.example.com/report-usage-stats/push` by default. # See: `matrix_synapse_usage_exporter_hostname` and `matrix_synapse_usage_exporter_path_prefix`. +# +# This variable does not affect the metrics endpoint in any way. +# Metrics are always served on the container network (which is enough for a local Prometheus to scrape them) +# and are exposed publicly via `matrix_synapse_usage_exporter_metrics_proxying_enabled`. matrix_synapse_usage_exporter_proxying_enabled: false +# Controls whether synapse-usage-exporter metrics should be proxied (exposed) on `matrix.example.com/metrics/synapse-usage-exporter`. +# +# Metrics are always served by the service on the container network, so a local (in-container) Prometheus +# can scrape them without any of this. Exposing them publicly is only necessary +# if metrics need to be consumed by another (external) Prometheus server. +matrix_synapse_usage_exporter_metrics_proxying_enabled: false +matrix_synapse_usage_exporter_metrics_proxying_hostname: '' +matrix_synapse_usage_exporter_metrics_proxying_path: /metrics/synapse-usage-exporter + # matrix_synapse_usage_exporter_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. # See `../templates/labels.j2` for details. # # To inject your own other container labels, see `matrix_synapse_usage_exporter_container_labels_additional_labels`. -matrix_synapse_usage_exporter_container_labels_traefik_enabled: "{{ matrix_synapse_usage_exporter_proxying_enabled }}" +matrix_synapse_usage_exporter_container_labels_traefik_enabled: true matrix_synapse_usage_exporter_container_labels_traefik_docker_network: "{{ matrix_synapse_usage_exporter_container_network }}" +# Controls whether labels will be added that expose the usage-stats ingestion endpoint (see `matrix_synapse_usage_exporter_proxying_enabled`) +matrix_synapse_usage_exporter_container_labels_traefik_usage_stats_enabled: "{{ matrix_synapse_usage_exporter_proxying_enabled }}" matrix_synapse_usage_exporter_container_labels_traefik_path_prefix: "{{ matrix_synapse_usage_exporter_path_prefix }}" matrix_synapse_usage_exporter_container_labels_traefik_rule: "Host(`{{ matrix_synapse_usage_exporter_hostname }}`) && PathPrefix(`{{ matrix_synapse_usage_exporter_container_labels_traefik_path_prefix }}`)" matrix_synapse_usage_exporter_container_labels_traefik_priority: 0 @@ -77,6 +94,19 @@ matrix_synapse_usage_exporter_container_labels_traefik_entrypoints: "web-secure" matrix_synapse_usage_exporter_container_labels_traefik_tls: "{{ matrix_synapse_usage_exporter_container_labels_traefik_entrypoints != 'web' }}" matrix_synapse_usage_exporter_container_labels_traefik_tls_certResolver: default # noqa var-naming +# Controls whether labels will be added that expose the metrics endpoint (see `matrix_synapse_usage_exporter_metrics_proxying_enabled`) +matrix_synapse_usage_exporter_container_labels_traefik_metrics_enabled: "{{ matrix_synapse_usage_exporter_metrics_proxying_enabled }}" +matrix_synapse_usage_exporter_container_labels_traefik_metrics_path: "{{ matrix_synapse_usage_exporter_metrics_proxying_path }}" +matrix_synapse_usage_exporter_container_labels_traefik_metrics_rule: "Host(`{{ matrix_synapse_usage_exporter_metrics_proxying_hostname }}`) && Path(`{{ matrix_synapse_usage_exporter_container_labels_traefik_metrics_path }}`)" +matrix_synapse_usage_exporter_container_labels_traefik_metrics_priority: 0 +matrix_synapse_usage_exporter_container_labels_traefik_metrics_entrypoints: "{{ matrix_synapse_usage_exporter_container_labels_traefik_entrypoints }}" +matrix_synapse_usage_exporter_container_labels_traefik_metrics_tls: "{{ matrix_synapse_usage_exporter_container_labels_traefik_metrics_entrypoints != 'web' }}" +matrix_synapse_usage_exporter_container_labels_traefik_metrics_tls_certResolver: "{{ matrix_synapse_usage_exporter_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +matrix_synapse_usage_exporter_container_labels_traefik_metrics_middleware_basic_auth_enabled: false +# See: https://doc.traefik.io/traefik/middlewares/http/basicauth/#users +matrix_synapse_usage_exporter_container_labels_traefik_metrics_middleware_basic_auth_users: '' + # matrix_synapse_usage_exporter_container_labels_additional_labels contains a multiline string with additional labels to add to the container label file. # See `../templates/labels.j2` for details. # diff --git a/roles/custom/matrix-synapse-usage-exporter/tasks/setup_install.yml b/roles/custom/matrix-synapse-usage-exporter/tasks/setup_install.yml index b34eb4188..32ff5a02e 100644 --- a/roles/custom/matrix-synapse-usage-exporter/tasks/setup_install.yml +++ b/roles/custom/matrix-synapse-usage-exporter/tasks/setup_install.yml @@ -32,11 +32,9 @@ register: matrix_synapse_usage_exporter_support_files_result - name: Ensure synapse-usage-exporter Docker image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_synapse_usage_exporter_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_synapse_usage_exporter_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_synapse_usage_exporter_container_image_force_pull }}" + pull: always when: "not matrix_synapse_usage_exporter_container_image_self_build | bool" register: matrix_synapse_usage_exporter_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -45,6 +43,15 @@ - when: "matrix_synapse_usage_exporter_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure synapse-usage-exporter repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_synapse_usage_exporter_docker_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + - name: Ensure synapse-usage-exporter repository is present on self-build ansible.builtin.git: repo: "{{ matrix_synapse_usage_exporter_container_image_self_build_repo }}" @@ -72,6 +79,7 @@ when: "matrix_synapse_usage_exporter_git_pull_results.changed | bool or matrix_synapse_usage_exporter_container_image_check_result.stdout == ''" - name: Ensure synapse-usage-exporter container network is created + when: matrix_synapse_usage_exporter_container_network != 'host' community.general.docker_network: name: "{{ matrix_synapse_usage_exporter_container_network }}" driver: bridge diff --git a/roles/custom/matrix-synapse-usage-exporter/tasks/validate_config.yml b/roles/custom/matrix-synapse-usage-exporter/tasks/validate_config.yml index 996b7c461..a1e184ac3 100644 --- a/roles/custom/matrix-synapse-usage-exporter/tasks/validate_config.yml +++ b/roles/custom/matrix-synapse-usage-exporter/tasks/validate_config.yml @@ -1,10 +1,19 @@ -# SPDX-FileCopyrightText: 2025 Slavi Pantaleev +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev # SPDX-FileCopyrightText: 2025 Suguru Hirahara # # SPDX-License-Identifier: AGPL-3.0-or-later --- +- name: Fail if required matrix-synapse-usage-exporter settings not defined + ansible.builtin.fail: + msg: > + You need to define a required configuration setting (`{{ item.name }}`). + when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" + with_items: + - {'name': 'matrix_synapse_usage_exporter_metrics_proxying_hostname', when: "{{ matrix_synapse_usage_exporter_metrics_proxying_enabled }}"} + - {'name': 'matrix_synapse_usage_exporter_metrics_proxying_path', when: "{{ matrix_synapse_usage_exporter_metrics_proxying_enabled }}"} + - name: (Deprecation) Catch and report renamed matrix-synapse-usage-exporter settings ansible.builtin.fail: msg: >- @@ -13,3 +22,4 @@ when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" with_items: - {'old': 'matrix_synapse_usage_exporter_docker_image_name_prefix', 'new': 'matrix_synapse_usage_exporter_container_image_registry_prefix'} + - {'old': 'matrix_synapse_usage_exporter_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} diff --git a/roles/custom/matrix-synapse-usage-exporter/templates/labels.j2 b/roles/custom/matrix-synapse-usage-exporter/templates/labels.j2 index 50c3ca82f..a50ad0923 100755 --- a/roles/custom/matrix-synapse-usage-exporter/templates/labels.j2 +++ b/roles/custom/matrix-synapse-usage-exporter/templates/labels.j2 @@ -1,5 +1,6 @@ {# SPDX-FileCopyrightText: 2024 Michael Hollister +SPDX-FileCopyrightText: 2026 Slavi Pantaleev SPDX-License-Identifier: AGPL-3.0-or-later #} @@ -13,6 +14,7 @@ traefik.docker.network={{ matrix_synapse_usage_exporter_container_labels_traefik traefik.http.services.matrix-synapse-usage-exporter.loadbalancer.server.port={{ matrix_synapse_usage_exporter_container_port }} +{% if matrix_synapse_usage_exporter_container_labels_traefik_usage_stats_enabled %} ############################################################ # # # Report Usage Stats (/report-usage-stats/push) # @@ -38,6 +40,46 @@ traefik.http.routers.matrix-synapse-usage-exporter.tls.certResolver={{ matrix_sy # /Report Usage Stats (/report-usage-stats/push) # # # ############################################################ +{% endif %} + +{% if matrix_synapse_usage_exporter_container_labels_traefik_metrics_enabled %} +############################################################ +# # +# Metrics # +# # +############################################################ + +{% set metricsMiddlewares = [] %} + +{% if matrix_synapse_usage_exporter_container_labels_traefik_metrics_middleware_basic_auth_enabled %} +{% set metricsMiddlewares = metricsMiddlewares + ['matrix-synapse-usage-exporter-metrics-basic-auth'] %} +traefik.http.middlewares.matrix-synapse-usage-exporter-metrics-basic-auth.basicauth.users={{ matrix_synapse_usage_exporter_container_labels_traefik_metrics_middleware_basic_auth_users }} +{% endif %} + +{% set metricsMiddlewares = metricsMiddlewares + ['matrix-synapse-usage-exporter-metrics-replace-path'] %} +traefik.http.middlewares.matrix-synapse-usage-exporter-metrics-replace-path.replacepath.path=/metrics + +traefik.http.routers.matrix-synapse-usage-exporter-metrics.rule={{ matrix_synapse_usage_exporter_container_labels_traefik_metrics_rule }} +traefik.http.routers.matrix-synapse-usage-exporter-metrics.middlewares={{ metricsMiddlewares | join(',') }} + +{% if matrix_synapse_usage_exporter_container_labels_traefik_metrics_priority | int > 0 %} +traefik.http.routers.matrix-synapse-usage-exporter-metrics.priority={{ matrix_synapse_usage_exporter_container_labels_traefik_metrics_priority }} +{% endif %} + +traefik.http.routers.matrix-synapse-usage-exporter-metrics.service=matrix-synapse-usage-exporter +traefik.http.routers.matrix-synapse-usage-exporter-metrics.entrypoints={{ matrix_synapse_usage_exporter_container_labels_traefik_metrics_entrypoints }} + +traefik.http.routers.matrix-synapse-usage-exporter-metrics.tls={{ matrix_synapse_usage_exporter_container_labels_traefik_metrics_tls | to_json }} +{% if matrix_synapse_usage_exporter_container_labels_traefik_metrics_tls %} +traefik.http.routers.matrix-synapse-usage-exporter-metrics.tls.certResolver={{ matrix_synapse_usage_exporter_container_labels_traefik_metrics_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Metrics # +# # +############################################################ +{% endif %} {% endif %} diff --git a/roles/custom/matrix-synapse-usage-exporter/templates/systemd/matrix-synapse-usage-exporter.service.j2 b/roles/custom/matrix-synapse-usage-exporter/templates/systemd/matrix-synapse-usage-exporter.service.j2 index ad4fc342e..6a3c8d68f 100644 --- a/roles/custom/matrix-synapse-usage-exporter/templates/systemd/matrix-synapse-usage-exporter.service.j2 +++ b/roles/custom/matrix-synapse-usage-exporter/templates/systemd/matrix-synapse-usage-exporter.service.j2 @@ -30,9 +30,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_synapse_usage_exporter_container_image }} +{% if matrix_synapse_usage_exporter_container_network != 'host' %} {% for network in matrix_synapse_usage_exporter_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_synapse_usage_exporter_identifier }} {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_synapse_usage_exporter_identifier }} diff --git a/roles/custom/matrix-synapse/defaults/main.yml b/roles/custom/matrix-synapse/defaults/main.yml index 095a5a13b..ff186c432 100644 --- a/roles/custom/matrix-synapse/defaults/main.yml +++ b/roles/custom/matrix-synapse/defaults/main.yml @@ -16,7 +16,7 @@ matrix_synapse_enabled: true matrix_synapse_github_org_and_repo: element-hq/synapse # renovate: datasource=docker depName=ghcr.io/element-hq/synapse -matrix_synapse_version: v1.150.0 +matrix_synapse_version: v1.160.0 matrix_synapse_username: '' matrix_synapse_uid: '' @@ -86,7 +86,6 @@ matrix_synapse_container_image_customizations_dockerfile_body_custom: '' matrix_synapse_container_image: "{{ matrix_synapse_container_image_registry_prefix }}{{ matrix_synapse_container_image_name }}:{{ matrix_synapse_container_image_tag }}" matrix_synapse_container_image_name: "{{ matrix_synapse_github_org_and_repo }}" matrix_synapse_container_image_tag: "{{ matrix_synapse_version }}" -matrix_synapse_container_image_force_pull: "{{ matrix_synapse_container_image.endswith(':latest') }}" matrix_synapse_container_image_registry_prefix: "{{ 'localhost/' if matrix_synapse_container_image_self_build else matrix_synapse_container_image_registry_prefix_upstream }}" matrix_synapse_container_image_registry_prefix_upstream: "{{ matrix_synapse_container_image_registry_prefix_upstream_default }}" matrix_synapse_container_image_registry_prefix_upstream_default: "ghcr.io/" @@ -538,7 +537,7 @@ matrix_synapse_federation_rr_transactions_per_room_per_second: 50 # Controls the rate limit for delayed event management. # -# This is only applied if `matrix_synapse_experimental_features_msc4140_enabled` is set to `true`. +# This is only applied if `matrix_synapse_delayed_events_enabled` is set to `true`. matrix_synapse_rc_delayed_event_mgmt: per_second: 1 burst_count: 20 @@ -574,7 +573,10 @@ matrix_synapse_federation_listener_resource_names: "{{ ['federation'] if matrix_ matrix_synapse_report_stats: false # The endpoint to report homeserver usage statistics to. -matrix_synapse_report_stats_endpoint: "https://matrix.org/report-usage-stats/push" +matrix_synapse_report_stats_endpoint: "{{ matrix_synapse_report_stats_endpoint_default }}" + +# The default endpoint to report homeserver usage statistics to (the one operated by matrix.org). +matrix_synapse_report_stats_endpoint_default: "https://matrix.org/report-usage-stats/push" # Controls whether the Matrix server will track presence status (online, offline, unavailable) for users. # If users participate in large rooms with many other servers, @@ -950,6 +952,7 @@ matrix_synapse_workers_presets: # Keep disabled by default: MSC4306/4308 thread subscriptions are unstable # and disabled in upstream Synapse unless explicitly opted in. stream_writer_thread_subscriptions_stream_workers_count: 0 + stream_writer_quarantined_media_changes_stream_workers_count: 0 one-of-each: room_workers_count: 0 sync_workers_count: 0 @@ -973,6 +976,7 @@ matrix_synapse_workers_presets: # Keep disabled by default: MSC4306/4308 thread subscriptions are unstable # and disabled in upstream Synapse unless explicitly opted in. stream_writer_thread_subscriptions_stream_workers_count: 0 + stream_writer_quarantined_media_changes_stream_workers_count: 1 specialized-workers: room_workers_count: 1 sync_workers_count: 1 @@ -996,6 +1000,7 @@ matrix_synapse_workers_presets: # Keep disabled by default: MSC4306/4308 thread subscriptions are unstable # and disabled in upstream Synapse unless explicitly opted in. stream_writer_thread_subscriptions_stream_workers_count: 0 + stream_writer_quarantined_media_changes_stream_workers_count: 1 # Controls whether the matrix-synapse container exposes the various worker ports # (see `port` and `metrics_port` in `matrix_synapse_workers_enabled_list`) outside of the container. @@ -1102,6 +1107,10 @@ matrix_synapse_workers_stream_writer_device_lists_stream_workers_count: "{{ matr # More than 1 worker is also supported of this type. matrix_synapse_workers_stream_writer_thread_subscriptions_stream_workers_count: "{{ matrix_synapse_workers_presets[matrix_synapse_workers_preset]['stream_writer_thread_subscriptions_stream_workers_count'] }}" +# matrix_synapse_workers_stream_writer_quarantined_media_changes_stream_workers_count controls how many stream writers that handle the `quarantined_media_changes` stream to spawn. +# More than 1 worker is also supported of this type. +matrix_synapse_workers_stream_writer_quarantined_media_changes_stream_workers_count: "{{ matrix_synapse_workers_presets[matrix_synapse_workers_preset]['stream_writer_quarantined_media_changes_stream_workers_count'] }}" + # A list of stream writer workers to enable. This list is built automatically based on other variables. # You're encouraged to enable/disable stream writer workers by setting `matrix_synapse_workers_stream_writer_*_stream_workers_count` variables, instead of adjusting this list manually. matrix_synapse_workers_stream_writers: | @@ -1125,6 +1134,8 @@ matrix_synapse_workers_stream_writers: | ([{'stream': 'device_lists'}] * matrix_synapse_workers_stream_writer_device_lists_stream_workers_count | int) + ([{'stream': 'thread_subscriptions'}] * matrix_synapse_workers_stream_writer_thread_subscriptions_stream_workers_count | int) + + + ([{'stream': 'quarantined_media_changes'}] * matrix_synapse_workers_stream_writer_quarantined_media_changes_stream_workers_count | int) }} matrix_synapse_workers_stream_writers_container_arguments: [] @@ -1231,6 +1242,25 @@ matrix_synapse_workers_background_workers_container_arguments: [] # `run_background_tasks_on` is meant to point to a worker, which is dedicated to processing background tasks. matrix_synapse_run_background_tasks_on: "{{ (matrix_synapse_workers_enabled_list | selectattr('type', 'equalto', 'background') | list)[0].name if (matrix_synapse_workers_enabled and matrix_synapse_workers_enabled_list | selectattr('type', 'equalto', 'background') | list | length > 0) else '' }}" +# matrix_synapse_workers_total_count reflects the total number of Synapse worker processes that the `matrix_synapse_workers_*_count` variables ask for. +# This is useful for sizing resources that depend on the number of Synapse processes (e.g. the maximum number of Postgres connections). +# Note: if `matrix_synapse_workers_enabled_list` is populated manually (instead of via the count variables), this count does not reflect it. +matrix_synapse_workers_total_count: | + {{ + (matrix_synapse_workers_room_workers_count | int) + + (matrix_synapse_workers_sync_workers_count | int) + + (matrix_synapse_workers_client_reader_workers_count | int) + + (matrix_synapse_workers_federation_reader_workers_count | int) + + (matrix_synapse_workers_generic_workers_count | int) + + (matrix_synapse_workers_pusher_workers_count | int) + + (matrix_synapse_workers_federation_sender_workers_count | int) + + (matrix_synapse_workers_media_repository_workers_count | int) + + (matrix_synapse_workers_appservice_workers_count | int) + + (matrix_synapse_workers_user_dir_workers_count | int) + + (matrix_synapse_workers_background_workers_count | int) + + (matrix_synapse_workers_stream_writers | length) + }} + # Default list of workers to spawn. # # Unless you populate this manually, this list is dynamically generated @@ -1329,6 +1359,9 @@ matrix_synapse_database_host: '' matrix_synapse_database_port: 5432 matrix_synapse_database_cp_min: 5 matrix_synapse_database_cp_max: 10 +matrix_synapse_database_keepalives_idle: null +matrix_synapse_database_keepalives_interval: null +matrix_synapse_database_keepalives_count: null matrix_synapse_database_user: "synapse" matrix_synapse_database_password: "" matrix_synapse_database_database: "synapse" @@ -1405,16 +1438,7 @@ matrix_synapse_experimental_features_msc4108_enabled: false ################################################################################ -# Controls whether to enable the "room summary API" experimental feature. -# See https://github.com/matrix-org/matrix-spec-proposals/pull/3266 -# Despite being experimental, this feature is mandatory for the next-generation Element X clients, which is why it is enabled by default: -# https://github.com/element-hq/element-x-ios/issues/3713#issuecomment-2620958291 -# If you're worried about the privacy implications of this unauthenticated API, see: -# https://github.com/deepbluev7/matrix-doc/blob/room-summaries/proposals/3266-room-summary.md#client-server-api -# Set this to false if you still want to disable to API for some reason. Note that doing so breaks Element X compatibility though. -matrix_synapse_experimental_features_msc3266_enabled: true - -# Controls whether to enable the "Delayed Events" experimental feature. +# Controls whether to enable the "Delayed Events" feature (MSC4140). # Delayed events are required for proper call (Element Call) participation signalling. # If disabled it is very likely that you end up with stuck calls in Matrix rooms. # @@ -1423,19 +1447,52 @@ matrix_synapse_experimental_features_msc3266_enabled: true # - `matrix_synapse_rc_delayed_event_mgmt` # # See https://github.com/matrix-org/matrix-spec-proposals/pull/4140 -matrix_synapse_experimental_features_msc4140_enabled: false +matrix_synapse_delayed_events_enabled: false # Controls the maximum allowed duration by which sent events can be delayed, as per MSC4140. +# Synapse enables delayed events based on this configuration setting being present. # -# See `matrix_synapse_experimental_features_msc4140_enabled`. +# This is only applied if `matrix_synapse_delayed_events_enabled` is set to `true`. matrix_synapse_max_event_delay_duration: 24h # Controls whether to enable the MSC4143 experimental feature (RTC transports). # # This is used by MatrixRTC clients to discover the unstable RTC transports API. # +# This follows `matrix_synapse_matrix_rtc_transports`, because serving the RTC transports API without any transports configured +# breaks MatrixRTC (Element Call) for clients which consult this API. +# Such clients treat the API response as authoritative and do not fall back to the `org.matrix.msc4143.rtc_foci` property in the client well-known. +# # See https://github.com/matrix-org/matrix-spec-proposals/pull/4143 -matrix_synapse_experimental_features_msc4143_enabled: false +matrix_synapse_experimental_features_msc4143_enabled: "{{ matrix_synapse_matrix_rtc_transports | length > 0 }}" + +# Controls the `matrix_rtc.transports` setting - the list of MatrixRTC transports advertised via the RTC transports API (MSC4143). +# +# The API serving this list is only enabled when `matrix_synapse_experimental_features_msc4143_enabled` is set to `true`. +# Otherwise, this setting is parsed by Synapse, but remains unused. +matrix_synapse_matrix_rtc_transports: "{{ matrix_synapse_matrix_rtc_transports_default + matrix_synapse_matrix_rtc_transports_auto + matrix_synapse_matrix_rtc_transports_custom }}" + +# Holds the default MatrixRTC transports list, driven by `matrix_synapse_matrix_rtc_transports_livekit_url`. +matrix_synapse_matrix_rtc_transports_default: |- + {{ + ( + [{'type': 'livekit', 'livekit_service_url': matrix_synapse_matrix_rtc_transports_livekit_url}] if matrix_synapse_matrix_rtc_transports_livekit_url != '' else [] + ) + }} + +# Holds MatrixRTC transports entries that a playbook may inject automatically, based on the state of other services. +# +# This variable is not meant to be redefined by users. +# To inject your own entries, use `matrix_synapse_matrix_rtc_transports_custom`. +matrix_synapse_matrix_rtc_transports_auto: [] + +# Holds additional MatrixRTC transports entries that you may wish to inject. +matrix_synapse_matrix_rtc_transports_custom: [] + +# Controls the MatrixRTC LiveKit URL auto-added to `matrix_synapse_matrix_rtc_transports`. +# +# This is set automatically if you are using the playbook's MatrixRTC stack. +matrix_synapse_matrix_rtc_transports_livekit_url: '' # Controls whether to enable the MSC4222 experimental feature (adding `state_after` to sync v2). # @@ -1462,6 +1519,46 @@ matrix_synapse_experimental_features_msc4306_enabled: false # See https://github.com/matrix-org/matrix-spec-proposals/pull/4354 matrix_synapse_experimental_features_msc4354_enabled: false +# Holds the final `experimental_features` configuration for the Synapse homeserver. +# +# This is constructed from various other variables and is not meant to be redefined directly. +# To influence it, use the various `matrix_synapse_experimental_features_msc*_enabled` variables or add your own configuration to `matrix_synapse_experimental_features_custom`. +matrix_synapse_experimental_features: "{{ matrix_synapse_experimental_features_default | combine(matrix_synapse_experimental_features_auto, recursive=True) | combine(matrix_synapse_experimental_features_custom, recursive=True) }}" + +# Holds the default `experimental_features` configuration, driven by the various `matrix_synapse_experimental_features_msc*_enabled` variables. +# +# Flags are only included when enabled, because Synapse changes flag defaults (or removes flags) across versions and we don't wish to interfere. +# The end result is always a mapping (potentially an empty one), never `null`, because Synapse (v1.157.0+) does not tolerate `experimental_features` being `null`. +matrix_synapse_experimental_features_default: | + {{ + { + 'msc2409_to_device_messages_enabled': matrix_synapse_experimental_features_msc2409_to_device_messages_enabled | bool, + 'msc3202_transaction_extensions': matrix_synapse_experimental_features_msc3202_transaction_extensions_enabled | bool, + 'msc4108_enabled': matrix_synapse_experimental_features_msc4108_enabled | bool, + 'msc4143_enabled': matrix_synapse_experimental_features_msc4143_enabled | bool, + 'msc4222_enabled': matrix_synapse_experimental_features_msc4222_enabled | bool, + 'msc4306_enabled': matrix_synapse_experimental_features_msc4306_enabled | bool, + 'msc4354_enabled': matrix_synapse_experimental_features_msc4354_enabled | bool, + } + | dict2items + | selectattr('value') + | list + | items2dict + }} + +# Holds `experimental_features` configuration that this playbook enables automatically, based on the state of other services. +# +# This variable is meant to be used by the playbook (see `group_vars/matrix_servers`) and is not meant to be redefined by users. +# To inject your own configuration, use `matrix_synapse_experimental_features_custom`. +matrix_synapse_experimental_features_auto: {} + +# Holds additional `experimental_features` configuration that you may wish to inject. +# +# Example: +# matrix_synapse_experimental_features_custom: +# msc9999_enabled: true +matrix_synapse_experimental_features_custom: {} + # Enable this to activate the REST auth password provider module. # See: https://github.com/ma1uta/matrix-synapse-rest-password-provider matrix_synapse_ext_password_provider_rest_auth_enabled: false @@ -1544,7 +1641,7 @@ matrix_synapse_ext_spam_checker_mjolnir_antispam_config: matrix_synapse_ext_synapse_http_antispam_enabled: false matrix_synapse_ext_synapse_http_antispam_git_repository_url: "https://github.com/maunium/synapse-http-antispam" # renovate: datasource=github-releases depName=maunium/synapse-http-antispam -matrix_synapse_ext_synapse_http_antispam_git_version: "v0.5.0" +matrix_synapse_ext_synapse_http_antispam_git_version: "v0.5.1" # Where Synapse can locate the consumer of the antispam API. Currently # Draupnir is the only consumer of this API that is playbook supported. # But https://github.com/maunium/meowlnir also supports the API. @@ -1605,7 +1702,7 @@ matrix_synapse_ext_encryption_config_yaml: | # Enabling this will enable customizations and inject the appropriate Dockerfile clauses for installing synapse-s3-storage-provider. matrix_synapse_ext_synapse_s3_storage_provider_enabled: false # renovate: datasource=github-releases depName=matrix-org/synapse-s3-storage-provider -matrix_synapse_ext_synapse_s3_storage_provider_version: 1.6.0 +matrix_synapse_ext_synapse_s3_storage_provider_version: 1.7.0 # Controls whether media from this (local) server is stored in s3-storage-provider matrix_synapse_ext_synapse_s3_storage_provider_store_local: true # Controls whether media from remote servers is stored in s3-storage-provider @@ -1658,7 +1755,6 @@ matrix_s3_goofys_container_image: "{{ matrix_s3_goofys_container_image_registry_ matrix_s3_goofys_container_image_registry_prefix: "{{ matrix_s3_goofys_container_image_registry_prefix_upstream }}" matrix_s3_goofys_container_image_registry_prefix_upstream: "{{ matrix_s3_goofys_container_image_registry_prefix_upstream_default }}" matrix_s3_goofys_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_s3_goofys_container_image_force_pull: "{{ matrix_s3_goofys_container_image.endswith(':latest') }}" matrix_s3_media_store_custom_endpoint: "your-custom-endpoint" matrix_s3_media_store_bucket_name: "your-bucket-name" matrix_s3_media_store_aws_access_key: "your-aws-access-key" @@ -1776,7 +1872,6 @@ matrix_synapse_rust_synapse_compress_state_container_image_version: v0.0.3 matrix_synapse_rust_synapse_compress_state_container_image_registry_prefix: "{{ matrix_synapse_rust_synapse_compress_state_container_image_registry_prefix_upstream }}" matrix_synapse_rust_synapse_compress_state_container_image_registry_prefix_upstream: "{{ matrix_synapse_rust_synapse_compress_state_container_image_registry_prefix_upstream_default }}" matrix_synapse_rust_synapse_compress_state_container_image_registry_prefix_upstream_default: "registry.gitlab.com/" -matrix_synapse_rust_synapse_compress_state_container_image_force_pull: "{{ matrix_synapse_rust_synapse_compress_state_container_image.endswith(':stable') or matrix_synapse_rust_synapse_compress_state_container_image.endswith(':latest') }}" matrix_synapse_rust_synapse_compress_state_base_path: "{{ matrix_base_data_path }}/rust-synapse-compress-state" matrix_synapse_rust_synapse_compress_state_synapse_compress_state_in_container_path: "/usr/local/bin/synapse_compress_state" @@ -1835,7 +1930,7 @@ matrix_synapse_register_user_script_matrix_authentication_service_path: "" matrix_synapse_reverse_proxy_companion_enabled: "{{ matrix_synapse_enabled and matrix_synapse_workers_enabled }}" # renovate: datasource=docker depName=nginx -matrix_synapse_reverse_proxy_companion_version: 1.29.7-alpine +matrix_synapse_reverse_proxy_companion_version: 1.31.5-alpine matrix_synapse_reverse_proxy_companion_base_path: "{{ matrix_synapse_base_path }}/reverse-proxy-companion" matrix_synapse_reverse_proxy_companion_confd_path: "{{ matrix_synapse_reverse_proxy_companion_base_path }}/conf.d" @@ -1858,7 +1953,6 @@ matrix_synapse_reverse_proxy_companion_container_image_registry_prefix: "{{ matr matrix_synapse_reverse_proxy_companion_container_image_registry_prefix_upstream: "{{ matrix_synapse_reverse_proxy_companion_container_image_registry_prefix_upstream_default }}" matrix_synapse_reverse_proxy_companion_container_image_registry_prefix_upstream_default: "docker.io/" matrix_synapse_reverse_proxy_companion_container_image_tag: "{{ matrix_synapse_reverse_proxy_companion_version }}" -matrix_synapse_reverse_proxy_companion_container_image_force_pull: "{{ matrix_synapse_reverse_proxy_companion_container_image.endswith(':latest') }}" matrix_synapse_reverse_proxy_companion_container_network: "{{ matrix_synapse_container_network }}" @@ -2102,6 +2196,7 @@ matrix_synapse_reverse_proxy_companion_synapse_stream_writer_presence_stream_wor matrix_synapse_reverse_proxy_companion_synapse_stream_writer_push_rules_stream_worker_client_server_locations: "{{ matrix_synapse_workers_stream_writer_push_rules_stream_worker_client_server_endpoints }}" matrix_synapse_reverse_proxy_companion_synapse_stream_writer_device_lists_stream_worker_client_server_locations: "{{ matrix_synapse_workers_stream_writer_device_lists_stream_worker_client_server_endpoints }}" matrix_synapse_reverse_proxy_companion_synapse_stream_writer_thread_subscriptions_stream_worker_client_server_locations: "{{ matrix_synapse_workers_stream_writer_thread_subscriptions_stream_worker_client_server_endpoints }}" +matrix_synapse_reverse_proxy_companion_synapse_stream_writer_quarantined_media_changes_stream_worker_client_server_locations: "{{ matrix_synapse_workers_stream_writer_quarantined_media_changes_stream_worker_client_server_endpoints }}" matrix_synapse_reverse_proxy_companion_synapse_media_repository_locations: "{{ matrix_synapse_workers_media_repository_endpoints | default([]) }}" matrix_synapse_reverse_proxy_companion_synapse_user_dir_locations: "{{ matrix_synapse_workers_user_dir_worker_client_server_endpoints | default([]) }}" matrix_synapse_reverse_proxy_companion_client_server_main_override_locations_regex: ^/_matrix/client/(api/v1|r0|v3|unstable)/(account/3pid/|directory/list/room/|rooms/[^/]+/(forget|upgrade|report)|register) diff --git a/roles/custom/matrix-synapse/molecule/default/converge.yml b/roles/custom/matrix-synapse/molecule/default/converge.yml new file mode 100644 index 000000000..ab59befde --- /dev/null +++ b/roles/custom/matrix-synapse/molecule/default/converge.yml @@ -0,0 +1,50 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Include roles for Synapse Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Include base roles for Synapse Molecule tests + ansible.builtin.include_role: + name: "{{ role_name }}" + public: true + loop: + - com.devture.ansible.role.playbook_help + - com.devture.ansible.role.systemd_docker_base + loop_control: + loop_var: role_name + + # The role's main task file also carries separately invoked maintenance actions + # (media/database imports, user management, and self-checks). Include the same + # initialization, validation, and installation files selected by setup-synapse. + - name: Include Synapse setup task files + ansible.builtin.include_role: + name: "custom/{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + public: true + tasks_from: "{{ role_task_file }}" + loop: + - init.yml + - validate_config.yml + - setup_install.yml + loop_control: + loop_var: role_task_file + +- name: Ensure Synapse is started + hosts: all + become: true + gather_facts: false + tasks: + - name: Ensure systemd daemon is reloaded + ansible.builtin.systemd_service: + daemon_reload: true + + - name: Ensure the Synapse systemd service is started + ansible.builtin.systemd_service: + name: matrix-synapse.service + state: started diff --git a/roles/custom/matrix-synapse/molecule/default/molecule.yml b/roles/custom/matrix-synapse/molecule/default/molecule.yml new file mode 100644 index 000000000..9e76918d8 --- /dev/null +++ b/roles/custom/matrix-synapse/molecule/default/molecule.yml @@ -0,0 +1,114 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +dependency: + name: galaxy + options: + requirements-file: requirements.yml + force: true +driver: + name: docker +platforms: + - name: synapse-${MOLECULE_DISTRO:-ubuntu2604}-default + image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2604}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + callback_result_format: yaml + inventory: + group_vars: + all: + # This first scenario deliberately exercises one main Synapse process. Workers and + # everything they bring with them belong in a separate topology-focused scenario. + matrix_synapse_workers_enabled: false + matrix_synapse_redis_enabled: false + matrix_synapse_reverse_proxy_companion_enabled: false + + matrix_synapse_username: matrix + matrix_synapse_uid: 1234 + matrix_synapse_gid: 1234 + matrix_synapse_container_network: synapse-molecule + + # The non-default listener is reached only over the container network. Override the + # upstream image's health command as well, because its default assumes port 8008. + matrix_synapse_container_client_api_port: 18008 + matrix_synapse_container_client_api_host_bind_port: '' + matrix_synapse_container_master_extra_arguments: + - "--health-cmd='curl -fSs http://localhost:18008/health'" + matrix_synapse_container_labels_traefik_enabled: false + matrix_synapse_container_labels_traefik_hostname: matrix.molecule.local + matrix_synapse_systemd_service_post_start_delay_seconds: 0 + + # Postgres is the normal deployment path. Distinct database and user names make the + # resulting Synapse schema evidence that these exact connection settings were used. + matrix_synapse_database_host: matrix-postgres-molecule + matrix_synapse_database_port: 5432 + matrix_synapse_database_user: molecule_synapse + matrix_synapse_database_password: molecule_synapse_pg_password_9b742d + matrix_synapse_database_database: molecule_synapse + matrix_synapse_database_cp_min: 2 + matrix_synapse_database_cp_max: 4 + + # Local scenario secrets only. They never authenticate to an external service. + matrix_synapse_macaroon_secret_key: molecule_synapse_macaroon_4b3f891d + matrix_synapse_registration_shared_secret: molecule_synapse_registration_27ed51a8 + matrix_synapse_form_secret: molecule_synapse_form_96a04c7b + matrix_synapse_password_config_pepper: molecule_synapse_pepper_c0f371e6 + + # These values differ from both role and upstream defaults and are safe to exercise + # without introducing any external dependency. + matrix_synapse_public_baseurl: http://matrix.molecule.local:18008/ + matrix_synapse_presence_enabled: false + matrix_synapse_max_upload_size_mb: 37 + matrix_synapse_url_preview_enabled: false + matrix_synapse_allow_public_rooms_over_federation: false + matrix_synapse_user_directory_search_all_users: true + matrix_synapse_user_directory_prefer_local_users: true + matrix_synapse_trusted_key_servers: [] + matrix_synapse_suppress_key_server_warning: true + + # Keep the scenario fully local and intentionally exclude optional integrations. + matrix_synapse_federation_enabled: false + matrix_synapse_federation_port_openid_resource_required: false + matrix_synapse_tls_federation_listener_enabled: false + matrix_synapse_metrics_enabled: false + matrix_synapse_email_enabled: false + matrix_synapse_matrix_authentication_service_enabled: false + matrix_authentication_service_migration_in_progress: false + matrix_synapse_ext_synapse_s3_storage_provider_enabled: false + matrix_s3_media_store_enabled: false + matrix_playbook_ssl_enabled: false + + # verify.yml is a separate play, so pin paths that otherwise come from role defaults. + # The component version is deliberately loaded from defaults/main.yml instead. + matrix_synapse_base_path: /matrix/synapse + matrix_synapse_config_dir_path: /matrix/synapse/config + matrix_synapse_storage_path: /matrix/synapse/storage + matrix_synapse_media_store_path: /matrix/synapse/storage/media-store + env: + # Workaround for https://github.com/ansible/molecule/issues/4391 + ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/../..:/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:${ANSIBLE_HOME:-~/.ansible}/roles +scenario: + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy +verifier: + name: ansible diff --git a/roles/custom/matrix-synapse/molecule/default/prepare.yml b/roles/custom/matrix-synapse/molecule/default/prepare.yml new file mode 100644 index 000000000..498c19002 --- /dev/null +++ b/roles/custom/matrix-synapse/molecule/default/prepare.yml @@ -0,0 +1,117 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +- name: Prepare Synapse Molecule tests + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: true + tasks: + - name: Ensure apt cache is updated + ansible.builtin.apt: + update_cache: true + cache_valid_time: 600 + when: ansible_facts['os_family'] == 'Debian' + + - name: Ensure required packages are installed + ansible.builtin.package: + name: + - python3-requests + - fuse-overlayfs + state: present + + # The production Synapse unit uses slave bind propagation for its media store. The + # privileged Molecule host must expose a shared parent mount to its nested Docker daemon. + - name: Ensure nested Docker can use Synapse media-store bind propagation + ansible.builtin.command: + argv: + - mount + - --make-rshared + - / + changed_when: false + + - name: Ensure Docker is installed + ansible.builtin.include_role: + name: ansible-role-docker + vars: + docker_daemon_options: + storage-driver: fuse-overlayfs + + - name: Ensure the matrix group exists + ansible.builtin.group: + name: "{{ matrix_group_name }}" + gid: "{{ matrix_user_gid }}" + state: present + + - name: Ensure the matrix user exists + ansible.builtin.user: + name: "{{ matrix_user_name }}" + uid: "{{ matrix_user_uid }}" + group: "{{ matrix_group_name }}" + create_home: false + system: true + state: present + + - name: Ensure the base data path exists + ansible.builtin.file: + path: "{{ matrix_base_data_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + mode: '0750' + + # Postgres must attach before the role creates this network during converge. + - name: Ensure the Synapse container network exists + ansible.builtin.command: + argv: + - docker + - network + - create + - "{{ matrix_synapse_container_network }}" + register: matrix_synapse_molecule_network + changed_when: matrix_synapse_molecule_network.rc == 0 + failed_when: + - matrix_synapse_molecule_network.rc != 0 + - "'already exists' not in matrix_synapse_molecule_network.stderr" + + - name: Ensure Postgres is running + ansible.builtin.include_tasks: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/tasks/postgres.yml" + vars: + molecule_shared_postgres_network: "{{ matrix_synapse_container_network }}" + molecule_shared_postgres_database: "{{ matrix_synapse_database_database }}" + molecule_shared_postgres_username: "{{ matrix_synapse_database_user }}" + molecule_shared_postgres_password: "{{ matrix_synapse_database_password }}" + + # Synapse intentionally refuses databases with locale-dependent collation. Recreate the + # helper's empty scenario database with the production-required C locale before startup. + - name: Remove the locale-dependent empty Synapse database + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_synapse_database_user }} + - --dbname=postgres + - --command=DROP DATABASE IF EXISTS "{{ matrix_synapse_database_database }}" + changed_when: true + + - name: Create the empty Synapse database with C collation + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_synapse_database_user }} + - --dbname=postgres + - >- + --command=CREATE DATABASE "{{ matrix_synapse_database_database }}" + OWNER "{{ matrix_synapse_database_user }}" TEMPLATE template0 + LC_COLLATE 'C' LC_CTYPE 'C' + changed_when: true diff --git a/roles/custom/matrix-synapse/molecule/default/requirements.yml b/roles/custom/matrix-synapse/molecule/default/requirements.yml new file mode 120000 index 000000000..1567a5392 --- /dev/null +++ b/roles/custom/matrix-synapse/molecule/default/requirements.yml @@ -0,0 +1 @@ +../../../../../molecule-shared/requirements.yml \ No newline at end of file diff --git a/roles/custom/matrix-synapse/molecule/default/verify.yml b/roles/custom/matrix-synapse/molecule/default/verify.yml new file mode 100644 index 000000000..450e1345d --- /dev/null +++ b/roles/custom/matrix-synapse/molecule/default/verify.yml @@ -0,0 +1,360 @@ +# SPDX-FileCopyrightText: 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Proves a single main Synapse process starts on the non-default listener the role +# rendered, serves real Matrix APIs, migrates the configured Postgres database, and +# carries no worker, Redis, S3, MAS, email, or other optional-integration topology. +- name: Verify Synapse + hosts: all + become: true + vars_files: + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/vars.yml" + - "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/../../../molecule-shared/playbook-context.yml" + gather_facts: false + vars: + matrix_synapse_config: "{{ matrix_synapse_config_file.content | b64decode | from_yaml }}" + matrix_synapse_http_listeners: >- + {{ matrix_synapse_config.listeners | selectattr('type', 'equalto', 'http') | list }} + matrix_synapse_http_listener: "{{ matrix_synapse_http_listeners | first | default({}) }}" + + tasks: + # The image version comes from the role, not from the scenario, so an assertion cannot + # remain green merely because both the scenario and runtime are pinned to the same typo. + - name: Load the role's defaults under a separate name + ansible.builtin.include_vars: + file: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/main.yml" + name: matrix_synapse_role_defaults + + - name: Wait for the Synapse service to become active + ansible.builtin.systemd_service: + name: matrix-synapse.service + register: matrix_synapse_service + until: matrix_synapse_service.status.ActiveState == 'active' + retries: 30 + delay: 5 + failed_when: false + + - name: Assert the Synapse service is stable + ansible.builtin.assert: + that: + - matrix_synapse_service.status.ActiveState == 'active' + - matrix_synapse_service.status.NRestarts is defined + - matrix_synapse_service.status.NRestarts | int == 0 + fail_msg: >- + matrix-synapse.service is + {{ matrix_synapse_service.status.ActiveState | default('unknown') }} after + {{ matrix_synapse_service.status.NRestarts | default('?') }} restart(s) + success_msg: "matrix-synapse.service is active and has not restarted" + + # Probe over the role's own network. No host port is published, matching deployment. + - name: Request the Synapse health endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_synapse_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-synapse:{{ matrix_synapse_container_client_api_port }}/health + register: matrix_synapse_health + changed_when: false + until: "'HTTP_STATUS=200' in matrix_synapse_health.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Request the Synapse Matrix versions endpoint + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_synapse_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --show-error + - --write-out + - "\nHTTP_STATUS=%{http_code}" + - http://matrix-synapse:{{ matrix_synapse_container_client_api_port }}/_matrix/client/versions + register: matrix_synapse_versions_response + changed_when: false + until: "'HTTP_STATUS=200' in matrix_synapse_versions_response.stdout" + retries: 24 + delay: 5 + failed_when: false + + - name: Assert Synapse serves its health endpoint + ansible.builtin.assert: + that: + - matrix_synapse_health.rc == 0 + - "'HTTP_STATUS=200' in matrix_synapse_health.stdout" + - matrix_synapse_health.stdout.startswith('OK') + fail_msg: >- + Synapse did not serve /health on port + {{ matrix_synapse_container_client_api_port }} + success_msg: "Synapse serves /health" + + - name: Assert Synapse serves its Matrix versions endpoint + ansible.builtin.assert: + that: + - matrix_synapse_versions_response.rc == 0 + - "'HTTP_STATUS=200' in matrix_synapse_versions_response.stdout" + fail_msg: >- + Synapse did not serve /_matrix/client/versions on port + {{ matrix_synapse_container_client_api_port }} + success_msg: "Synapse serves /_matrix/client/versions" + + - name: Parse the Matrix versions response + ansible.builtin.set_fact: + matrix_synapse_versions: >- + {{ matrix_synapse_versions_response.stdout + | regex_replace('\nHTTP_STATUS=200$', '') + | from_json }} + + - name: Assert the versions response is a real Matrix API document + ansible.builtin.assert: + that: + - matrix_synapse_versions.versions is sequence + - matrix_synapse_versions.versions | length > 0 + - "'v1.1' in matrix_synapse_versions.versions" + - matrix_synapse_versions.unstable_features is mapping + fail_msg: "The versions endpoint did not return a Matrix versions document" + success_msg: "The versions endpoint returns a Matrix versions document" + + # The role moved the listener away from 8008. Refusing the upstream default port proves + # the successful requests above did not accidentally hit an unchanged default listener. + - name: Request the upstream-default Synapse port + ansible.builtin.command: + argv: + - docker + - run + - --rm + - --network={{ matrix_synapse_container_network }} + - "{{ molecule_shared_image_curl }}" + - --silent + - --output + - /dev/null + - --connect-timeout + - '2' + - --max-time + - '3' + - http://matrix-synapse:8008/health + register: matrix_synapse_default_listener + changed_when: false + failed_when: false + + - name: Assert Synapse does not listen on the upstream-default port + ansible.builtin.assert: + that: + - matrix_synapse_default_listener.rc != 0 + fail_msg: "Synapse still answers on port 8008, so the non-default listener is not proven" + success_msg: "Only the role-configured client listener answers" + + - name: Read the homeserver configuration the role rendered + ansible.builtin.slurp: + src: "{{ matrix_synapse_config_dir_path }}/homeserver.yaml" + register: matrix_synapse_config_file + + - name: Read the homeserver configuration identity + ansible.builtin.stat: + path: "{{ matrix_synapse_config_dir_path }}/homeserver.yaml" + register: matrix_synapse_config_stat + + - name: Assert the parsed homeserver identity and behavior + ansible.builtin.assert: + that: + - matrix_synapse_config.server_name == matrix_domain + - matrix_synapse_config.public_baseurl == matrix_synapse_public_baseurl + - matrix_synapse_config.max_upload_size == (matrix_synapse_max_upload_size_mb | string) + 'M' + - not matrix_synapse_config.presence.enabled + - not matrix_synapse_config.url_preview_enabled + - not matrix_synapse_config.allow_public_rooms_over_federation + - matrix_synapse_config.user_directory.search_all_users + - matrix_synapse_config.user_directory.prefer_local_users + - matrix_synapse_config.trusted_key_servers == [] + fail_msg: "The parsed homeserver configuration does not carry the scenario's values" + success_msg: "The parsed homeserver configuration carries the scenario's values" + + - name: Assert the parsed homeserver secrets + ansible.builtin.assert: + that: + - matrix_synapse_config.macaroon_secret_key == matrix_synapse_macaroon_secret_key + - matrix_synapse_config.registration_shared_secret == matrix_synapse_registration_shared_secret + - matrix_synapse_config.form_secret == matrix_synapse_form_secret + - matrix_synapse_config.password_config.pepper == matrix_synapse_password_config_pepper + fail_msg: "The parsed homeserver configuration does not carry the scenario's secrets" + success_msg: "The parsed homeserver configuration carries the scenario's secrets" + no_log: true + + - name: Assert the parsed client listener topology + ansible.builtin.assert: + that: + - matrix_synapse_config.listeners | length == 1 + - matrix_synapse_http_listeners | length == 1 + - matrix_synapse_http_listener.port == matrix_synapse_container_client_api_port + - not matrix_synapse_http_listener.tls + - matrix_synapse_http_listener.bind_addresses == ['::'] + - matrix_synapse_http_listener.resources | length == 1 + - matrix_synapse_http_listener.resources[0].names == ['client'] + fail_msg: "The parsed homeserver configuration has an unexpected listener topology" + success_msg: "The parsed homeserver configuration has one non-default client listener" + + - name: Assert the parsed Postgres configuration + ansible.builtin.assert: + that: + - matrix_synapse_config.database.name == 'psycopg2' + - matrix_synapse_config.database.args.host == matrix_synapse_database_host + - matrix_synapse_config.database.args.port == matrix_synapse_database_port + - matrix_synapse_config.database.args.user == matrix_synapse_database_user + - matrix_synapse_config.database.args.password == matrix_synapse_database_password + - matrix_synapse_config.database.args.database == matrix_synapse_database_database + - matrix_synapse_config.database.args.cp_min == matrix_synapse_database_cp_min + - matrix_synapse_config.database.args.cp_max == matrix_synapse_database_cp_max + fail_msg: "The parsed homeserver configuration does not point at scenario Postgres" + success_msg: "The parsed homeserver configuration points at scenario Postgres" + no_log: true + + - name: Assert optional Synapse topology is absent + ansible.builtin.assert: + that: + - not matrix_synapse_config.redis.enabled + - matrix_synapse_config.media_storage_providers == [] + - matrix_synapse_config.modules == [] + - "'matrix_authentication_service' not in matrix_synapse_config" + - "'email' not in matrix_synapse_config" + - "'worker_app' not in matrix_synapse_config" + fail_msg: "An excluded worker, Redis, S3, MAS, email, or module integration is configured" + success_msg: "The configuration contains only the intended main-process topology" + + - name: Assert the homeserver configuration file identity + ansible.builtin.assert: + that: + - matrix_synapse_config_stat.stat.uid | int == matrix_user_uid | int + - matrix_synapse_config_stat.stat.gid | int == matrix_user_gid | int + - matrix_synapse_config_stat.stat.mode == '0644' + fail_msg: "homeserver.yaml has the wrong ownership or mode" + success_msg: "homeserver.yaml has the playbook identity and expected mode" + + # These tables appear only after hostname resolution, authentication, and genuine Synapse + # migrations against the exact non-default database prepared for the scenario. + - name: List the tables Synapse created in Postgres + ansible.builtin.command: + argv: + - docker + - exec + - matrix-postgres-molecule + - psql + - --username={{ matrix_synapse_database_user }} + - --dbname={{ matrix_synapse_database_database }} + - --tuples-only + - --no-align + - --command=SELECT tablename FROM pg_tables WHERE schemaname = 'public' + register: matrix_synapse_tables + changed_when: false + + - name: Assert Synapse migrated its Postgres schema + ansible.builtin.assert: + that: + - matrix_synapse_tables.rc == 0 + - "'schema_version' in matrix_synapse_table_names" + - "'users' in matrix_synapse_table_names" + - "'rooms' in matrix_synapse_table_names" + - "'events' in matrix_synapse_table_names" + - "'state_groups' in matrix_synapse_table_names" + - matrix_synapse_table_names | length > 50 + fail_msg: >- + Synapse did not migrate its schema in {{ matrix_synapse_database_database }} + (found {{ matrix_synapse_table_names | length }} table(s)) + success_msg: "Synapse genuinely migrated the configured Postgres database" + vars: + matrix_synapse_table_names: "{{ matrix_synapse_tables.stdout_lines | select | list }}" + + - name: Inspect the running Synapse container + ansible.builtin.command: + argv: + - docker + - container + - inspect + - matrix-synapse + register: matrix_synapse_container_inspect + changed_when: false + + - name: Parse the running Synapse container inspection + ansible.builtin.set_fact: + matrix_synapse_container: "{{ (matrix_synapse_container_inspect.stdout | from_json) | first }}" + + - name: Assert the running container uses the exact pinned image + ansible.builtin.assert: + that: + - matrix_synapse_container.Config.Image == 'ghcr.io/element-hq/synapse:' + matrix_synapse_role_defaults.matrix_synapse_version + fail_msg: "The running container does not use the exact image defaults/main.yml pins" + success_msg: "The running container uses the exact image defaults/main.yml pins" + + - name: Assert the running container uses the scenario identity + ansible.builtin.assert: + that: + - matrix_synapse_container.Config.User == (matrix_user_uid | string) + ':' + (matrix_user_gid | string) + fail_msg: "The running container does not use the playbook-supplied identity" + success_msg: "The running container uses the playbook-supplied identity" + + - name: Assert the running container security isolation + ansible.builtin.assert: + that: + - matrix_synapse_container.HostConfig.ReadonlyRootfs + - "'ALL' in matrix_synapse_container.HostConfig.CapDrop" + fail_msg: "The running container does not have read-only, capability-dropped isolation" + success_msg: "The running container has read-only, capability-dropped isolation" + + - name: Assert the running container has a read-only config mount + ansible.builtin.assert: + that: + - matrix_synapse_config_mount | length > 0 + - not matrix_synapse_config_mount.RW | default(true) + fail_msg: "The running container does not mount its configuration read-only" + success_msg: "The running container mounts its configuration read-only" + vars: + matrix_synapse_config_mount: >- + {{ matrix_synapse_container.Mounts + | selectattr('Destination', 'equalto', '/data') + | first | default({}) }} + + - name: Assert the running container has a writable storage mount + ansible.builtin.assert: + that: + - matrix_synapse_storage_mount | length > 0 + - matrix_synapse_storage_mount.RW | default(false) + fail_msg: "The running container does not mount its media storage writable" + success_msg: "The running container mounts its media storage writable" + vars: + matrix_synapse_storage_mount: >- + {{ matrix_synapse_container.Mounts + | selectattr('Destination', 'equalto', '/matrix-media-store-parent') + | first | default({}) }} + + - name: Assert the running container is healthy + ansible.builtin.assert: + that: + - matrix_synapse_container.State.Health.Status == 'healthy' + fail_msg: "The running container is not healthy" + success_msg: "The running container is healthy" + + - name: Assert the running container has only its private network + ansible.builtin.assert: + that: + - matrix_synapse_container_network in matrix_synapse_container.NetworkSettings.Networks + - matrix_synapse_container.NetworkSettings.Networks | length == 1 + fail_msg: "The running container has unexpected network attachments" + success_msg: "The running container has only its private network" + + - name: Assert the running container publishes no host ports + ansible.builtin.assert: + that: + - matrix_synapse_container.HostConfig.PortBindings | default({}, true) | length == 0 + fail_msg: "The running container unexpectedly publishes a host port" + success_msg: "The running container publishes no host ports" diff --git a/roles/custom/matrix-synapse/tasks/ext/mjolnir-antispam/setup_install.yml b/roles/custom/matrix-synapse/tasks/ext/mjolnir-antispam/setup_install.yml index d6c8429d5..0b3f191e4 100644 --- a/roles/custom/matrix-synapse/tasks/ext/mjolnir-antispam/setup_install.yml +++ b/roles/custom/matrix-synapse/tasks/ext/mjolnir-antispam/setup_install.yml @@ -12,11 +12,21 @@ name: git state: present +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure mjolnir-antispam repository ownership is correct + ansible.builtin.file: + path: "{{ matrix_synapse_ext_path }}/mjolnir" + state: directory + owner: "{{ matrix_synapse_uid }}" + group: "{{ matrix_synapse_gid }}" + recurse: true + - name: Clone mjolnir-antispam git repository ansible.builtin.git: repo: "{{ matrix_synapse_ext_spam_checker_mjolnir_antispam_git_repository_url }}" version: "{{ matrix_synapse_ext_spam_checker_mjolnir_antispam_git_version }}" dest: "{{ matrix_synapse_ext_path }}/mjolnir" + force: "yes" become: true become_user: "{{ matrix_synapse_username }}" diff --git a/roles/custom/matrix-synapse/tasks/ext/synapse-http-antispam/setup_install.yml b/roles/custom/matrix-synapse/tasks/ext/synapse-http-antispam/setup_install.yml index f7ce74096..56e7a1c5d 100644 --- a/roles/custom/matrix-synapse/tasks/ext/synapse-http-antispam/setup_install.yml +++ b/roles/custom/matrix-synapse/tasks/ext/synapse-http-antispam/setup_install.yml @@ -10,11 +10,21 @@ name: git state: present +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure synapse-http-antispam repository ownership is correct + ansible.builtin.file: + path: "{{ matrix_synapse_ext_path }}/synapse-http-antispam" + state: directory + owner: "{{ matrix_synapse_uid }}" + group: "{{ matrix_synapse_gid }}" + recurse: true + - name: Clone synapse-http-antispam git repository ansible.builtin.git: repo: "{{ matrix_synapse_ext_synapse_http_antispam_git_repository_url }}" version: "{{ matrix_synapse_ext_synapse_http_antispam_git_version }}" dest: "{{ matrix_synapse_ext_path }}/synapse-http-antispam" + force: "yes" become: true become_user: "{{ matrix_synapse_username }}" diff --git a/roles/custom/matrix-synapse/tasks/ext/synapse-simple-antispam/setup_install.yml b/roles/custom/matrix-synapse/tasks/ext/synapse-simple-antispam/setup_install.yml index 2a5a24b2b..13b587a9b 100644 --- a/roles/custom/matrix-synapse/tasks/ext/synapse-simple-antispam/setup_install.yml +++ b/roles/custom/matrix-synapse/tasks/ext/synapse-simple-antispam/setup_install.yml @@ -19,11 +19,21 @@ name: git state: present +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure synapse-simple-antispam repository ownership is correct + ansible.builtin.file: + path: "{{ matrix_synapse_ext_path }}/synapse-simple-antispam" + state: directory + owner: "{{ matrix_synapse_uid }}" + group: "{{ matrix_synapse_gid }}" + recurse: true + - name: Clone synapse-simple-antispam git repository ansible.builtin.git: repo: "{{ matrix_synapse_ext_spam_checker_synapse_simple_antispam_git_repository_url }}" version: "{{ matrix_synapse_ext_spam_checker_synapse_simple_antispam_git_version }}" dest: "{{ matrix_synapse_ext_path }}/synapse-simple-antispam" + force: "yes" become: true become_user: "{{ matrix_synapse_username }}" diff --git a/roles/custom/matrix-synapse/tasks/goofys/setup_install.yml b/roles/custom/matrix-synapse/tasks/goofys/setup_install.yml index 40a5b9602..e6af44fd1 100644 --- a/roles/custom/matrix-synapse/tasks/goofys/setup_install.yml +++ b/roles/custom/matrix-synapse/tasks/goofys/setup_install.yml @@ -15,11 +15,9 @@ tasks_from: ensure_fuse_installed - name: Ensure Goofys Docker image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_s3_goofys_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_s3_goofys_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_s3_goofys_container_image_force_pull }}" + pull: always register: matrix_goofys_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" diff --git a/roles/custom/matrix-synapse/tasks/reverse_proxy_companion/setup_install.yml b/roles/custom/matrix-synapse/tasks/reverse_proxy_companion/setup_install.yml index 1dd0116a8..ffefe8a5f 100644 --- a/roles/custom/matrix-synapse/tasks/reverse_proxy_companion/setup_install.yml +++ b/roles/custom/matrix-synapse/tasks/reverse_proxy_companion/setup_install.yml @@ -52,17 +52,16 @@ when: not matrix_synapse_reverse_proxy_companion_njs_enabled - name: Ensure matrix-synapse-reverse-proxy-companion nginx container image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_synapse_reverse_proxy_companion_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_synapse_reverse_proxy_companion_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_synapse_reverse_proxy_companion_container_image_force_pull }}" + pull: always register: matrix_synapse_reverse_proxy_companion_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_synapse_reverse_proxy_companion_container_image_pull_result is not failed - name: Ensure matrix-synapse-reverse-proxy-companion container network is created + when: matrix_synapse_reverse_proxy_companion_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_synapse_reverse_proxy_companion_container_network }}" diff --git a/roles/custom/matrix-synapse/tasks/rust-synapse-compress-state/main.yml b/roles/custom/matrix-synapse/tasks/rust-synapse-compress-state/main.yml index d074fd13e..a59b48443 100644 --- a/roles/custom/matrix-synapse/tasks/rust-synapse-compress-state/main.yml +++ b/roles/custom/matrix-synapse/tasks/rust-synapse-compress-state/main.yml @@ -51,11 +51,9 @@ group: "{{ matrix_synapse_gid }}" - name: Ensure rust-synapse-compress-state image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_synapse_rust_synapse_compress_state_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_synapse_rust_synapse_compress_state_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_synapse_rust_synapse_compress_state_container_image_force_pull }}" + pull: always register: result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" diff --git a/roles/custom/matrix-synapse/tasks/synapse/setup_install.yml b/roles/custom/matrix-synapse/tasks/synapse/setup_install.yml index 8a6bb6fdc..a5daf50a9 100644 --- a/roles/custom/matrix-synapse/tasks/synapse/setup_install.yml +++ b/roles/custom/matrix-synapse/tasks/synapse/setup_install.yml @@ -35,6 +35,15 @@ - when: "matrix_synapse_container_image_self_build | bool" block: + # A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. + - name: Ensure Synapse repository ownership is correct on self-build + ansible.builtin.file: + path: "{{ matrix_synapse_container_src_files_path }}" + state: directory + owner: "{{ matrix_synapse_uid }}" + group: "{{ matrix_synapse_gid }}" + recurse: true + - name: Ensure Synapse repository is present on self-build ansible.builtin.git: repo: "{{ matrix_synapse_container_image_self_build_repo }}" @@ -67,11 +76,9 @@ when: "matrix_synapse_git_pull_results.changed | bool or matrix_synapse_container_image_check_result.stdout == ''" - name: Ensure Synapse Docker image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_synapse_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_synapse_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_synapse_container_image_force_pull }}" + pull: always when: "not matrix_synapse_container_image_self_build" register: result retries: "{{ devture_playbook_help_container_retries_count }}" @@ -90,14 +97,14 @@ register: matrix_synapse_container_image_customizations_dockerfile_result - name: Ensure customized Docker image for Synapse is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_synapse_container_image_customized }}" - source: build - force_source: "{{ matrix_synapse_container_image_customizations_dockerfile_result.changed or matrix_synapse_container_image_customized_force_source }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_synapse_customized_container_src_files_path }}" - nocache: "{{ matrix_synapse_container_image_customized_build_nocache }}" + dockerfile: Dockerfile + path: "{{ matrix_synapse_customized_container_src_files_path }}" + pull: false + nocache: "{{ matrix_synapse_container_image_customized_build_nocache }}" + rebuild: "{{ 'always' if (matrix_synapse_container_image_customizations_dockerfile_result.changed | bool or matrix_synapse_container_image_customized_force_source | bool) else 'never' }}" + register: matrix_synapse_container_image_customized_build_result # We do this so that the signing key would get generated. # @@ -131,6 +138,7 @@ group: "{{ matrix_synapse_gid }}" - name: Ensure Synapse container network is created + when: matrix_synapse_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_synapse_container_network }}" diff --git a/roles/custom/matrix-synapse/tasks/validate_config.yml b/roles/custom/matrix-synapse/tasks/validate_config.yml index 47df0834b..a025268b3 100644 --- a/roles/custom/matrix-synapse/tasks/validate_config.yml +++ b/roles/custom/matrix-synapse/tasks/validate_config.yml @@ -74,7 +74,7 @@ - {'old': 'matrix_synapse_rust_synapse_compress_state_docker_image_registry_prefix_upstream', 'new': 'matrix_synapse_rust_synapse_compress_state_container_image_registry_prefix_upstream'} - {'old': 'matrix_synapse_rust_synapse_compress_state_docker_image_registry_prefix_upstream_default', 'new': 'matrix_synapse_rust_synapse_compress_state_container_image_registry_prefix_upstream_default'} - - {'old': 'matrix_synapse_experimental_features_msc3202_device_masquerading_enabled', 'new': '<removed - this feature is enabled by default now'} + - {'old': 'matrix_synapse_experimental_features_msc3202_device_masquerading_enabled', 'new': '<removed - this feature is enabled by default now>'} - {'old': 'matrix_synapse_experimental_features_msc3861_enabled', 'new': 'matrix_synapse_matrix_authentication_service_enabled'} - {'old': 'matrix_synapse_experimental_features_msc3861_issuer', 'new': '<superseded by matrix_synapse_matrix_authentication_service_endpoint>'} @@ -86,8 +86,17 @@ - {'old': 'matrix_synapse_experimental_features_msc4133_enabled', 'new': '<removed - this feature is enabled by default now>'} + - {'old': 'matrix_synapse_experimental_features_msc3266_enabled', 'new': '<removed - MSC3266 support was stabilized in Synapse v1.153.0 and the room summary API is now always enabled>'} + - {'old': 'matrix_synapse_experimental_features_msc4140_enabled', 'new': 'matrix_synapse_delayed_events_enabled'} + - {'old': 'matrix_synapse_experimental_features_msc4429_enabled', 'new': '<removed - Synapse does not actually support MSC4429 in any released version, so this flag never had any effect>'} + - {'old': 'matrix_synapse_container_image_customizations_s3_storage_provider_installation_old_boto_workaround_enabled', 'new': '<removed; see https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/4637>'} + - {'old': 'matrix_synapse_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_s3_goofys_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_synapse_rust_synapse_compress_state_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} + - {'old': 'matrix_synapse_reverse_proxy_companion_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} + - name: (Deprecation) Catch and report renamed settings in matrix_synapse_configuration_extension_yaml ansible.builtin.fail: msg: >- @@ -210,7 +219,7 @@ - name: Fail if OpenID Connect is enabled for Synapse when auth is delegated to Matrix Authentication Service ansible.builtin.fail: msg: "When Synapse is delegating authentication to Matrix Authentication Service (`matrix_synapse_matrix_authentication_service_enabled: true`), it doesn't make sense to enable OpenID Connect (`matrix_synapse_oidc_enabled: true`), because it is not Synapse that is handling authentication. Synapse will refuse to start otherwise." - when: matrix_synapse_matrix_authentication_service_enabled and matrix_synapse_oidc_enabled + when: matrix_synapse_matrix_authentication_service_enabled and matrix_synapse_oidc_enabled and not matrix_authentication_service_migration_in_progress - name: Fail if CAS config is enabled for Synapse when auth is delegated to Matrix Authentication Service ansible.builtin.fail: diff --git a/roles/custom/matrix-synapse/templates/reverse_proxy_companion/nginx/conf.d/matrix-synapse-reverse-proxy-companion.conf.j2 b/roles/custom/matrix-synapse/templates/reverse_proxy_companion/nginx/conf.d/matrix-synapse-reverse-proxy-companion.conf.j2 index ed9245bcb..e0b0efc87 100644 --- a/roles/custom/matrix-synapse/templates/reverse_proxy_companion/nginx/conf.d/matrix-synapse-reverse-proxy-companion.conf.j2 +++ b/roles/custom/matrix-synapse/templates/reverse_proxy_companion/nginx/conf.d/matrix-synapse-reverse-proxy-companion.conf.j2 @@ -13,6 +13,7 @@ {% set stream_writer_push_rules_stream_workers = matrix_synapse_reverse_proxy_companion_synapse_workers_list | selectattr('type', 'equalto', 'stream_writer') | selectattr('stream_writer_stream', 'equalto', 'push_rules') | list %} {% set stream_writer_device_lists_stream_workers = matrix_synapse_reverse_proxy_companion_synapse_workers_list | selectattr('type', 'equalto', 'stream_writer') | selectattr('stream_writer_stream', 'equalto', 'device_lists') | list %} {% set stream_writer_thread_subscriptions_stream_workers = matrix_synapse_reverse_proxy_companion_synapse_workers_list | selectattr('type', 'equalto', 'stream_writer') | selectattr('stream_writer_stream', 'equalto', 'thread_subscriptions') | list %} +{% set stream_writer_quarantined_media_changes_stream_workers = matrix_synapse_reverse_proxy_companion_synapse_workers_list | selectattr('type', 'equalto', 'stream_writer') | selectattr('stream_writer_stream', 'equalto', 'quarantined_media_changes') | list %} {% set media_repository_workers = matrix_synapse_reverse_proxy_companion_synapse_workers_list | selectattr('type', 'equalto', 'media_repository') | list %} {% set user_dir_workers = matrix_synapse_reverse_proxy_companion_synapse_workers_list | selectattr('type', 'equalto', 'user_dir') | list %} {% set stream_writer_client_server_routes = [ @@ -64,6 +65,12 @@ 'locations': matrix_synapse_reverse_proxy_companion_synapse_stream_writer_thread_subscriptions_stream_worker_client_server_locations, 'upstream': 'stream_writer_thread_subscriptions_stream_workers_upstream', }, + { + 'doc_url': 'https://element-hq.github.io/synapse/latest/workers.html#the-quarantined_media_changes-stream', + 'workers': stream_writer_quarantined_media_changes_stream_workers, + 'locations': matrix_synapse_reverse_proxy_companion_synapse_stream_writer_quarantined_media_changes_stream_worker_client_server_locations, + 'upstream': 'stream_writer_quarantined_media_changes_stream_workers_upstream', + }, ] %} {% macro render_worker_upstream(name, workers, load_balance) %} diff --git a/roles/custom/matrix-synapse/templates/reverse_proxy_companion/systemd/matrix-synapse-reverse-proxy-companion.service.j2 b/roles/custom/matrix-synapse/templates/reverse_proxy_companion/systemd/matrix-synapse-reverse-proxy-companion.service.j2 index 2f0aff36f..6a47dbf8f 100755 --- a/roles/custom/matrix-synapse/templates/reverse_proxy_companion/systemd/matrix-synapse-reverse-proxy-companion.service.j2 +++ b/roles/custom/matrix-synapse/templates/reverse_proxy_companion/systemd/matrix-synapse-reverse-proxy-companion.service.j2 @@ -45,9 +45,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_synapse_reverse_proxy_companion_container_image }} +{% if matrix_synapse_reverse_proxy_companion_container_network != 'host' %} {% for network in matrix_synapse_reverse_proxy_companion_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-synapse-reverse-proxy-companion {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-synapse-reverse-proxy-companion diff --git a/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 b/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 index 25585fafd..d3594380f 100644 --- a/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 +++ b/roles/custom/matrix-synapse/templates/synapse/homeserver.yaml.j2 @@ -868,6 +868,15 @@ database: port: {{ matrix_synapse_database_port }} cp_min: {{ matrix_synapse_database_cp_min | to_json }} cp_max: {{ matrix_synapse_database_cp_max | to_json }} +{% if matrix_synapse_database_keepalives_idle is not none %} + keepalives_idle: {{ matrix_synapse_database_keepalives_idle | to_json }} +{% endif %} +{% if matrix_synapse_database_keepalives_interval is not none %} + keepalives_interval: {{ matrix_synapse_database_keepalives_interval | to_json }} +{% endif %} +{% if matrix_synapse_database_keepalives_count is not none %} + keepalives_count: {{ matrix_synapse_database_keepalives_count | to_json }} +{% endif %} ## Logging ## @@ -2987,45 +2996,21 @@ background_updates: #default_batch_size: 50 -{% if matrix_synapse_matrix_authentication_service_enabled %} +{% if matrix_synapse_matrix_authentication_service_enabled and not matrix_authentication_service_migration_in_progress %} matrix_authentication_service: enabled: true endpoint: {{ matrix_synapse_matrix_authentication_service_endpoint | to_json }} secret: {{ matrix_synapse_matrix_authentication_service_secret | to_json }} {% endif %} -experimental_features: - {% if matrix_synapse_experimental_features_msc2409_to_device_messages_enabled %} - msc2409_to_device_messages_enabled: true - {% endif %} - {% if matrix_synapse_experimental_features_msc3202_transaction_extensions_enabled %} - msc3202_transaction_extensions: true - {% endif %} - {% if matrix_synapse_experimental_features_msc3266_enabled %} - msc3266_enabled: true - {% endif %} - {% if matrix_synapse_experimental_features_msc4108_enabled %} - msc4108_enabled: true - {% endif %} - {% if matrix_synapse_experimental_features_msc4140_enabled %} - msc4140_enabled: true - {% endif %} - {% if matrix_synapse_experimental_features_msc4143_enabled %} - msc4143_enabled: true - {% endif %} - {% if matrix_synapse_experimental_features_msc4222_enabled %} - msc4222_enabled: true - {% endif %} - {% if matrix_synapse_experimental_features_msc4306_enabled %} - msc4306_enabled: true - {% endif %} - {% if matrix_synapse_experimental_features_msc4354_enabled %} - msc4354_enabled: true - {% endif %} +experimental_features: {{ matrix_synapse_experimental_features | to_json }} -{% if matrix_synapse_experimental_features_msc4140_enabled %} +{% if matrix_synapse_delayed_events_enabled %} max_event_delay_duration: {{ matrix_synapse_max_event_delay_duration | to_json }} rc_delayed_event_mgmt: {{ matrix_synapse_rc_delayed_event_mgmt | to_json }} {% endif %} +matrix_rtc: + transports: {{ matrix_synapse_matrix_rtc_transports | to_json }} + # vim:ft=yaml diff --git a/roles/custom/matrix-synapse/templates/synapse/systemd/matrix-synapse-worker.service.j2 b/roles/custom/matrix-synapse/templates/synapse/systemd/matrix-synapse-worker.service.j2 index d75473f37..1ff0e9606 100644 --- a/roles/custom/matrix-synapse/templates/synapse/systemd/matrix-synapse-worker.service.j2 +++ b/roles/custom/matrix-synapse/templates/synapse/systemd/matrix-synapse-worker.service.j2 @@ -83,9 +83,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {{ matrix_synapse_container_image_final }} \ run -m synapse.app.{{ matrix_synapse_worker_details.app }} -c /data/homeserver.yaml -c /data/{{ matrix_synapse_worker_config_file_name }} +{% if matrix_synapse_container_network != 'host' %} {% for network in matrix_synapse_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_synapse_worker_container_name }} {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach {{ matrix_synapse_worker_container_name }} diff --git a/roles/custom/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 b/roles/custom/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 index 1516a718a..ecedbaecf 100644 --- a/roles/custom/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 +++ b/roles/custom/matrix-synapse/templates/synapse/systemd/matrix-synapse.service.j2 @@ -70,9 +70,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {{ matrix_synapse_container_image_final }} \ run -m synapse.app.homeserver -c /data/homeserver.yaml +{% if matrix_synapse_container_network != 'host' %} {% for network in matrix_synapse_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-synapse {% endfor %} +{% endif %} ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-synapse diff --git a/roles/custom/matrix-synapse/vars/main.yml b/roles/custom/matrix-synapse/vars/main.yml index 8935d8c45..af5aec1dc 100644 --- a/roles/custom/matrix-synapse/vars/main.yml +++ b/roles/custom/matrix-synapse/vars/main.yml @@ -140,6 +140,13 @@ matrix_synapse_workers_stream_writer_thread_subscriptions_stream_worker_client_s - ^/_matrix/client/unstable/io.element.msc4306/rooms/.*/thread/.*/subscription$ - ^/_matrix/client/unstable/io.element.msc4308/thread_subscriptions$ +# matrix_synapse_workers_stream_writer_quarantined_media_changes_stream_worker_client_server_endpoints contains the endpoints serviced by the `quarantined_media_changes` stream writer. +# Since Synapse v1.152, deployments which route `/_synapse/admin/v1/quarantine_media/` to a worker (rather than the main process) must declare those workers as +# `quarantined_media_changes` stream writers, otherwise quarantining media will not work. +# See: https://github.com/element-hq/synapse/blob/develop/docs/upgrade.md#upgrading-to-v11520 +matrix_synapse_workers_stream_writer_quarantined_media_changes_stream_worker_client_server_endpoints: + - ^/_synapse/admin/v1/quarantine_media/.*$ + # matrix_synapse_workers_user_dir_worker_client_server_endpoints contains the endpoints serviced by the `type = user_dir` (`app = generic_worker`) worker. # See: https://matrix-org.github.io/synapse/latest/workers.html#updating-the-user-directory matrix_synapse_workers_user_dir_worker_client_server_endpoints: @@ -148,11 +155,11 @@ matrix_synapse_workers_user_dir_worker_client_server_endpoints: # matrix_synapse_workers_known_stream_writer_stream_types contains the list of stream writer stream types that the playbook recognizes. # This is used for validation purposes. If adding support for a new type, besides adding it to this list, # don't forget to actually configure it where appropriate (see worker.yaml.j2`, the nginx proxy configuration, etc). -matrix_synapse_workers_known_stream_writer_stream_types: ['events', 'typing', 'to_device', 'account_data', 'receipts', 'presence', 'push_rules', 'device_lists', 'thread_subscriptions'] +matrix_synapse_workers_known_stream_writer_stream_types: ['events', 'typing', 'to_device', 'account_data', 'receipts', 'presence', 'push_rules', 'device_lists', 'thread_subscriptions', 'quarantined_media_changes'] # matrix_synapse_workers_webserving_stream_writer_types contains a list of stream writer types that serve web (client) requests. # Not all stream writers serve web requests. Some just perform background tasks. -matrix_synapse_workers_webserving_stream_writer_types: ['typing', 'to_device', 'account_data', 'receipts', 'presence', 'push_rules', 'device_lists', 'thread_subscriptions'] +matrix_synapse_workers_webserving_stream_writer_types: ['typing', 'to_device', 'account_data', 'receipts', 'presence', 'push_rules', 'device_lists', 'thread_subscriptions', 'quarantined_media_changes'] # matrix_synapse_workers_systemd_services_list contains a list of systemd services (one for each worker systemd service which serves web requests). # This list is built during runtime. @@ -338,8 +345,10 @@ matrix_synapse_workers_media_repository_endpoints: - ^/_synapse/admin/v1/room/.*/media.*$ - ^/_synapse/admin/v1/user/.*/media.*$ - ^/_synapse/admin/v1/media/.*$ - - ^/_synapse/admin/v1/quarantine_media/.*$ - ^/_synapse/admin/v1/users/.*/media$ + # `^/_synapse/admin/v1/quarantine_media/.*$` is intentionally not listed here: + # Synapse v1.152+ requires its worker to also be a `quarantined_media_changes` stream writer, + # so it's now handled by `matrix_synapse_workers_stream_writer_quarantined_media_changes_stream_worker_client_server_endpoints` instead. matrix_synapse_workers_user_dir_endpoints: # Handles searches in the user directory. It can handle REST endpoints matching diff --git a/roles/custom/matrix-tuwunel/defaults/main.yml b/roles/custom/matrix-tuwunel/defaults/main.yml new file mode 100644 index 000000000..e238d5fe9 --- /dev/null +++ b/roles/custom/matrix-tuwunel/defaults/main.yml @@ -0,0 +1,408 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- +# Tuwunel is a Matrix homeserver, the official successor to conduwuit. +# Project source code URL: https://github.com/matrix-construct/tuwunel +# See: https://matrix-construct.github.io/tuwunel/ + +matrix_tuwunel_enabled: true + +matrix_tuwunel_hostname: '' + +# renovate: datasource=docker depName=ghcr.io/matrix-construct/tuwunel +matrix_tuwunel_version: v1.9.0 + +matrix_tuwunel_container_image: "{{ matrix_tuwunel_container_image_registry_prefix }}matrix-construct/tuwunel:{{ matrix_tuwunel_container_image_tag }}" +matrix_tuwunel_container_image_tag: "{{ matrix_tuwunel_version }}" +matrix_tuwunel_container_image_registry_prefix: "{{ matrix_tuwunel_container_image_registry_prefix_upstream }}" +matrix_tuwunel_container_image_registry_prefix_upstream: "{{ matrix_tuwunel_container_image_registry_prefix_upstream_default }}" +matrix_tuwunel_container_image_registry_prefix_upstream_default: ghcr.io/ + +matrix_tuwunel_base_path: "{{ matrix_base_data_path }}/tuwunel" +matrix_tuwunel_config_path: "{{ matrix_tuwunel_base_path }}/config" +matrix_tuwunel_data_path: "{{ matrix_tuwunel_base_path }}/data" + +matrix_tuwunel_config_port_number: 6167 + +matrix_tuwunel_tmp_directory_size_mb: 500 + +# List of systemd services that matrix-tuwunel.service depends on +matrix_tuwunel_systemd_required_services_list: "{{ matrix_tuwunel_systemd_required_services_list_default + matrix_tuwunel_systemd_required_services_list_auto + matrix_tuwunel_systemd_required_services_list_custom }}" +matrix_tuwunel_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}" +matrix_tuwunel_systemd_required_services_list_auto: [] +matrix_tuwunel_systemd_required_services_list_custom: [] + +# List of systemd services that matrix-tuwunel.service wants +matrix_tuwunel_systemd_wanted_services_list: "{{ matrix_tuwunel_systemd_wanted_services_list_default + matrix_tuwunel_systemd_wanted_services_list_auto + matrix_tuwunel_systemd_wanted_services_list_custom }}" +matrix_tuwunel_systemd_wanted_services_list_default: [] +matrix_tuwunel_systemd_wanted_services_list_auto: [] +matrix_tuwunel_systemd_wanted_services_list_custom: [] + +# Controls how long to sleep for after starting the matrix-tuwunel container, +# so that subsequent services that depend on it can start after the homeserver +# is fully up. +# +# Set to 0 to remove the delay. +matrix_tuwunel_systemd_service_post_start_delay_seconds: 3 + +# The base container network. It will be auto-created by this role if it doesn't exist already. +matrix_tuwunel_container_network: "" + +# A list of additional container networks that the container would be connected to. +# The role does not create these networks, so make sure they already exist. +# Use this to expose this container to another reverse proxy, which runs in a different container network. +matrix_tuwunel_container_additional_networks: "{{ matrix_tuwunel_container_additional_networks_auto + matrix_tuwunel_container_additional_networks_custom }}" +matrix_tuwunel_container_additional_networks_auto: [] +matrix_tuwunel_container_additional_networks_custom: [] + +# matrix_tuwunel_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container. +# See `../templates/labels.j2` for details. +# +# To inject your own other container labels, see `matrix_tuwunel_container_labels_additional_labels`. +matrix_tuwunel_container_labels_traefik_enabled: true +matrix_tuwunel_container_labels_traefik_docker_network: "{{ matrix_tuwunel_container_network }}" +matrix_tuwunel_container_labels_traefik_entrypoints: web-secure +matrix_tuwunel_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added for handling the root (/) path on a public Traefik entrypoint. +matrix_tuwunel_container_labels_public_client_root_enabled: true +matrix_tuwunel_container_labels_public_client_root_traefik_hostname: "{{ matrix_tuwunel_hostname }}" +matrix_tuwunel_container_labels_public_client_root_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_client_root_traefik_hostname }}`) && Path(`/`)" +matrix_tuwunel_container_labels_public_client_root_traefik_priority: 0 +matrix_tuwunel_container_labels_public_client_root_traefik_entrypoints: "{{ matrix_tuwunel_container_labels_traefik_entrypoints }}" +matrix_tuwunel_container_labels_public_client_root_traefik_tls: "{{ matrix_tuwunel_container_labels_public_client_root_traefik_entrypoints != 'web' }}" +matrix_tuwunel_container_labels_public_client_root_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming +matrix_tuwunel_container_labels_public_client_root_redirection_enabled: false +matrix_tuwunel_container_labels_public_client_root_redirection_url: "" + +# Controls whether labels will be added that expose the Client-Server API on a public Traefik entrypoint. +matrix_tuwunel_container_labels_public_client_api_enabled: true +matrix_tuwunel_container_labels_public_client_api_traefik_hostname: "{{ matrix_tuwunel_hostname }}" +matrix_tuwunel_container_labels_public_client_api_traefik_path_prefix: /_matrix +matrix_tuwunel_container_labels_public_client_api_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_client_api_traefik_hostname }}`) && PathPrefix(`{{ matrix_tuwunel_container_labels_public_client_api_traefik_path_prefix }}`)" +matrix_tuwunel_container_labels_public_client_api_traefik_priority: 0 +matrix_tuwunel_container_labels_public_client_api_traefik_entrypoints: "{{ matrix_tuwunel_container_labels_traefik_entrypoints }}" +matrix_tuwunel_container_labels_public_client_api_traefik_tls: "{{ matrix_tuwunel_container_labels_public_client_api_traefik_entrypoints != 'web' }}" +matrix_tuwunel_container_labels_public_client_api_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# Controls whether labels will be added that expose the Client-Server API on the internal Traefik entrypoint. +matrix_tuwunel_container_labels_internal_client_api_enabled: false +matrix_tuwunel_container_labels_internal_client_api_traefik_path_prefix: "{{ matrix_tuwunel_container_labels_public_client_api_traefik_path_prefix }}" +matrix_tuwunel_container_labels_internal_client_api_traefik_rule: "PathPrefix(`{{ matrix_tuwunel_container_labels_internal_client_api_traefik_path_prefix }}`)" +matrix_tuwunel_container_labels_internal_client_api_traefik_priority: "{{ matrix_tuwunel_container_labels_public_client_api_traefik_priority }}" +matrix_tuwunel_container_labels_internal_client_api_traefik_entrypoints: "" + +# Controls whether labels will be added that expose the Server-Server (Federation) API on a public Traefik entrypoint. +matrix_tuwunel_container_labels_public_federation_api_enabled: "{{ matrix_tuwunel_config_allow_federation }}" +matrix_tuwunel_container_labels_public_federation_api_traefik_hostname: "{{ matrix_tuwunel_hostname }}" +matrix_tuwunel_container_labels_public_federation_api_traefik_path_prefix: /_matrix +matrix_tuwunel_container_labels_public_federation_api_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_federation_api_traefik_hostname }}`) && PathPrefix(`{{ matrix_tuwunel_container_labels_public_federation_api_traefik_path_prefix }}`)" +matrix_tuwunel_container_labels_public_federation_api_traefik_priority: 0 +matrix_tuwunel_container_labels_public_federation_api_traefik_entrypoints: '' +# TLS is force-enabled because the spec (https://spec.matrix.org/latest/server-server-api/#tls) requires the federation API use HTTPS. +matrix_tuwunel_container_labels_public_federation_api_traefik_tls: true +matrix_tuwunel_container_labels_public_federation_api_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# Controls whether labels will be added that expose Tuwunel's first-party API (`/_tuwunel`) on a public Traefik entrypoint. +# This namespace carries ad-hoc routes such as `/_tuwunel/server_version` and `/_tuwunel/local_user_count`, as well as the +# native OpenID Connect provider endpoints (`/_tuwunel/oidc/...`) that clients use when Tuwunel performs OIDC login itself. +# It is enabled by default because the reverse proxy must route it for those features to work. +matrix_tuwunel_container_labels_public_tuwunel_api_enabled: true +matrix_tuwunel_container_labels_public_tuwunel_api_traefik_hostname: "{{ matrix_tuwunel_hostname }}" +matrix_tuwunel_container_labels_public_tuwunel_api_traefik_path_prefix: /_tuwunel +matrix_tuwunel_container_labels_public_tuwunel_api_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_tuwunel_api_traefik_hostname }}`) && PathPrefix(`{{ matrix_tuwunel_container_labels_public_tuwunel_api_traefik_path_prefix }}`)" +matrix_tuwunel_container_labels_public_tuwunel_api_traefik_priority: 0 +matrix_tuwunel_container_labels_public_tuwunel_api_traefik_entrypoints: "{{ matrix_tuwunel_container_labels_traefik_entrypoints }}" +matrix_tuwunel_container_labels_public_tuwunel_api_traefik_tls: "{{ matrix_tuwunel_container_labels_public_tuwunel_api_traefik_entrypoints != 'web' }}" +matrix_tuwunel_container_labels_public_tuwunel_api_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# Controls whether labels will be added that expose Tuwunel's first-party API (`/_tuwunel`) on the internal Traefik entrypoint. +matrix_tuwunel_container_labels_internal_tuwunel_api_enabled: false +matrix_tuwunel_container_labels_internal_tuwunel_api_traefik_path_prefix: /_tuwunel +matrix_tuwunel_container_labels_internal_tuwunel_api_traefik_rule: "PathPrefix(`{{ matrix_tuwunel_container_labels_internal_tuwunel_api_traefik_path_prefix }}`)" +matrix_tuwunel_container_labels_internal_tuwunel_api_traefik_priority: 0 +matrix_tuwunel_container_labels_internal_tuwunel_api_traefik_entrypoints: "" + +# Controls whether labels will be added that expose the Synapse-compatible Administration API (`/_synapse/admin`) on a public Traefik entrypoint. +# Tuwunel serves this API so that administration dashboards (synapse-admin, ketesa) and moderation bots (Draupnir, Meowlnir) work against it. +# Every endpoint requires an administrator access token. It is disabled by default; you may prefer to expose it only on the internal entrypoint below. +matrix_tuwunel_container_labels_public_client_synapse_admin_api_enabled: false +matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_hostname: "{{ matrix_tuwunel_hostname }}" +matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_path_prefix: /_synapse/admin +matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_hostname }}`) && PathPrefix(`{{ matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_path_prefix }}`)" +matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_priority: 0 +matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_entrypoints: "{{ matrix_tuwunel_container_labels_traefik_entrypoints }}" +matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_tls: "{{ matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_entrypoints != 'web' }}" +matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# Controls whether labels will be added that expose the Synapse-compatible Administration API (`/_synapse/admin`) on the internal Traefik entrypoint. +matrix_tuwunel_container_labels_internal_client_synapse_admin_api_enabled: false +matrix_tuwunel_container_labels_internal_client_synapse_admin_api_traefik_path_prefix: /_synapse/admin +matrix_tuwunel_container_labels_internal_client_synapse_admin_api_traefik_rule: "PathPrefix(`{{ matrix_tuwunel_container_labels_internal_client_synapse_admin_api_traefik_path_prefix }}`)" +matrix_tuwunel_container_labels_internal_client_synapse_admin_api_traefik_priority: 0 +matrix_tuwunel_container_labels_internal_client_synapse_admin_api_traefik_entrypoints: "" + +# Additional Docker container labels (multiline string) appended verbatim to the label file. +# See `../templates/labels.j2`. +matrix_tuwunel_container_labels_additional_labels: '' + +# Extra arguments for the Docker container +matrix_tuwunel_container_extra_arguments: [] + +# Specifies which template files to use when configuring tuwunel. +# To override the rendered config wholesale, copy the template into your inventory and point this at it: +# matrix_tuwunel_template_tuwunel_config: "{{ playbook_dir }}/inventory/host_vars/matrix.example.com/tuwunel.toml.j2" +matrix_tuwunel_template_tuwunel_config: "{{ role_path }}/templates/tuwunel.toml.j2" + +# The pretty server name used as a suffix on user/room IDs. Cannot be changed after first start without a database wipe. +matrix_tuwunel_config_server_name: "{{ matrix_domain }}" + +# Max size for uploads, in bytes +matrix_tuwunel_config_max_request_size: 20000000 + +# Enables open registration. If false, no users can register on this server. +matrix_tuwunel_config_allow_registration: false + +# When registration is enabled, set a strong token to protect the endpoint from abuse. +# Generate one with e.g. `pwgen -s 64 1`. If left empty AND `allow_registration` is true, +# you must explicitly opt in via the open-registration acknowledgement variable below. +matrix_tuwunel_config_registration_token: '' + +# Acknowledgement required to allow registration with no token. +# Maps to tuwunel's `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse`. +matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse: false + +# Suffix appended to new-user displaynames upon registration. Empty disables it. +# Upstream defaults to a flag glyph; we keep MDAD homeserver behavior consistent and leave this empty. +matrix_tuwunel_config_new_user_displayname_suffix: "" + +# Emergency password to grant access to the admin user when locked out. Empty disables. +matrix_tuwunel_config_emergency_password: '' + +# Trusted notary servers used for key verification. +matrix_tuwunel_config_trusted_servers: + - "matrix.org" + +# Logging directives in `tracing-subscriber` env-filter syntax. +matrix_tuwunel_config_log: "info,state_res=warn" + +# TURN integration +matrix_tuwunel_config_turn_uris: [] +matrix_tuwunel_config_turn_secret: '' +matrix_tuwunel_config_turn_username: '' +matrix_tuwunel_config_turn_password: '' + +# Self-check toggles +matrix_tuwunel_self_check_validate_certificates: true + +# Encryption / room creation policy +matrix_tuwunel_config_allow_encryption: true +matrix_tuwunel_config_allow_room_creation: true + +# Default room version newly created rooms will use. +matrix_tuwunel_config_default_room_version: '12' + +# Rooms newly registered users will be auto-joined to. +# Must be rooms this server has joined at least once and that are public. +matrix_tuwunel_config_auto_join_rooms: [] + +# (De)federation toggles +matrix_tuwunel_config_allow_federation: true +matrix_tuwunel_config_allowed_remote_server_names: [] +matrix_tuwunel_config_forbidden_remote_server_names: [] +matrix_tuwunel_config_forbidden_remote_room_directory_server_names: [] +matrix_tuwunel_config_prevent_media_downloads_from: [] + +# List of IPv4/IPv6 CIDR ranges tuwunel refuses to send outbound requests to (SSRF protection). +# This applies to push gateway delivery, URL previews, and remote media fetches. +# Bridges/appservices use a separate resolver and are not affected. +# +# The default mirrors tuwunel's own upstream default, which denies RFC1918, +# loopback, multicast, and other unroutable/testnet ranges. +# +# To deny additional ranges, append to `matrix_tuwunel_config_ip_range_denylist_custom`. +# To permit a range that the default denies (e.g. if you run a push gateway like a +# localhost Sygnal or a LAN ntfy/UnifiedPush server on a private/loopback address, to +# which push delivery would otherwise be silently blocked), override +# `matrix_tuwunel_config_ip_range_denylist_default` with a trimmed list. +# Set the whole list to `[]` to disable denylisting entirely. +matrix_tuwunel_config_ip_range_denylist: "{{ matrix_tuwunel_config_ip_range_denylist_default + matrix_tuwunel_config_ip_range_denylist_auto + matrix_tuwunel_config_ip_range_denylist_custom }}" +matrix_tuwunel_config_ip_range_denylist_default: + - '127.0.0.0/8' + - '10.0.0.0/8' + - '172.16.0.0/12' + - '192.168.0.0/16' + - '100.64.0.0/10' + - '192.0.0.0/24' + - '169.254.0.0/16' + - '192.88.99.0/24' + - '198.18.0.0/15' + - '192.0.2.0/24' + - '198.51.100.0/24' + - '203.0.113.0/24' + - '224.0.0.0/4' + - '::1/128' + - 'fe80::/10' + - 'fc00::/7' + - '2001:db8::/32' + - 'ff00::/8' + - 'fec0::/10' +matrix_tuwunel_config_ip_range_denylist_auto: [] +matrix_tuwunel_config_ip_range_denylist_custom: [] + +# MSC4284 policy server enforcement. +# When enabled, rooms with a valid `m.room.policy` state event will have +# outgoing events signed by the configured policy server before federation. +# Refusal aborts the local request; transient network or timeout failures +# fail open with a warn log so a policy-server outage does not silently +# take the room offline. +matrix_tuwunel_config_enable_policy_servers: false + +# Timeout (in seconds) for outbound `/sign` calls and inbound +# signature-fetches against a room's policy server. +matrix_tuwunel_config_policy_server_request_timeout: 5 + +# Whether tuwunel evaluates MSC3664 related-event push conditions itself. +# The default `.im.nheko.msc3664.reply` rule needs this to affect notification counts and pusher delivery. +# Clients implementing MSC3664 evaluate the rule locally either way. +# Enabling it costs an extra event lookup for every event carrying a relation. +matrix_tuwunel_config_msc3664_related_event_match: false + +# Outgoing presence is heavy on CPU and network and almost no clients use it. Off by default. +matrix_tuwunel_config_allow_outgoing_presence: false + +# URL preview gating +matrix_tuwunel_config_url_preview_domain_contains_allowlist: [] +matrix_tuwunel_config_url_preview_domain_explicit_allowlist: [] +matrix_tuwunel_config_url_preview_check_root_domain: false + +# Well-known overrides +# Maps to `[global.well_known] client = "..."` and `server = "host:port"`. +matrix_tuwunel_config_well_known_client: '' +matrix_tuwunel_config_well_known_server: '' +matrix_tuwunel_config_well_known_support_page: '' +matrix_tuwunel_config_well_known_support_email: '' +matrix_tuwunel_config_well_known_support_mxid: '' + +# MatrixRTC foci served via /_matrix/client/v1/rtc/transports (MSC4143) +matrix_tuwunel_config_well_known_livekit_url: '' + +# RocksDB tuning. Empty values let tuwunel auto-pick. +matrix_tuwunel_config_rocksdb_compression_algo: 'zstd' # one of: zstd, lz4, bz2, none +matrix_tuwunel_config_rocksdb_compression_level: '' +matrix_tuwunel_config_rocksdb_bottommost_compression_level: '' +matrix_tuwunel_config_rocksdb_direct_io: false +matrix_tuwunel_config_rocksdb_parallelism_threads: 0 +matrix_tuwunel_config_rocksdb_max_log_file_size: '' +matrix_tuwunel_config_rocksdb_log_time_to_roll: '' +matrix_tuwunel_config_database_backup_path: '' +matrix_tuwunel_config_database_backups_to_keep: 1 + +# Cache sizing. Empty values let tuwunel auto-pick (scaled by CPU count). +matrix_tuwunel_config_cache_capacity_modifier: '' +matrix_tuwunel_config_db_cache_capacity_mb: '' +matrix_tuwunel_config_db_write_buffer_capacity_mb: '' + +# Admin room +matrix_tuwunel_config_create_admin_room: true +matrix_tuwunel_config_federate_admin_room: false +matrix_tuwunel_config_grant_admin_to_first_user: true + +# Sentry crash/error reporting (off by default) +matrix_tuwunel_config_sentry_enabled: false +matrix_tuwunel_config_sentry_endpoint: '' +matrix_tuwunel_config_sentry_send_server_name: false +matrix_tuwunel_config_sentry_traces_sample_rate: 0.15 + +# Blurhashing for image previews +matrix_tuwunel_config_blurhashing_enabled: true +matrix_tuwunel_config_blurhashing_components_x: 4 +matrix_tuwunel_config_blurhashing_components_y: 3 +matrix_tuwunel_config_blurhashing_max_raw_size: 33554432 + +# Native TLS (use only when reverse-proxying is not desired) +matrix_tuwunel_config_tls_certs: '' +matrix_tuwunel_config_tls_key: '' +matrix_tuwunel_config_tls_dual_protocol: false + +# LDAP authentication ([global.ldap] in tuwunel.toml). +# See: https://matrix-construct.github.io/tuwunel/authentication/providers.html +matrix_tuwunel_config_ldap_enabled: false +matrix_tuwunel_config_ldap_uri: '' +matrix_tuwunel_config_ldap_base_dn: '' +matrix_tuwunel_config_ldap_bind_dn: '' +matrix_tuwunel_config_ldap_bind_password_file: '' +matrix_tuwunel_config_ldap_filter: '(objectClass=*)' +matrix_tuwunel_config_ldap_uid_attribute: 'uid' +matrix_tuwunel_config_ldap_admin_base_dn: '' +matrix_tuwunel_config_ldap_admin_filter: '' + +# JWT authentication ([global.jwt] in tuwunel.toml). +matrix_tuwunel_config_jwt_enabled: false +matrix_tuwunel_config_jwt_key: '' +matrix_tuwunel_config_jwt_format: 'HMAC' # one of: HMAC, B64HMAC, ECDSA, EDDSA +matrix_tuwunel_config_jwt_algorithm: 'HS256' +matrix_tuwunel_config_jwt_register_user: true +matrix_tuwunel_config_jwt_audience: [] +matrix_tuwunel_config_jwt_issuer: [] +matrix_tuwunel_config_jwt_require_exp: false +matrix_tuwunel_config_jwt_require_nbf: false +matrix_tuwunel_config_jwt_validate_exp: true +matrix_tuwunel_config_jwt_validate_nbf: true + +# OAuth2/OIDC identity providers. +# +# Each entry becomes a `[[global.identity_provider]]` block. Only fields you set are emitted; +# tuwunel applies brand-aware defaults for known providers (Google, GitHub, Keycloak, MAS, etc). +# +# Example: +# matrix_tuwunel_config_identity_providers: +# - brand: keycloak +# client_id: matrix +# client_secret: '...' +# issuer_url: https://sso.example.com/realms/matrix +# callback_url: https://matrix.example.com/_matrix/client/unstable/login/sso/callback/matrix +# trusted: true +# - brand: github +# client_id: '...' +# client_secret: '...' +# +# See: https://matrix-construct.github.io/tuwunel/authentication/providers.html +matrix_tuwunel_config_identity_providers: [] + +# Media storage providers. +# +# Each entry maps an ID to a backend. `kind` is `local` or `s3`; remaining keys map directly +# to fields under `[global.storage_provider.<ID>.<kind>]`. +# +# Examples: +# matrix_tuwunel_config_storage_providers: +# - id: primary +# kind: local +# base_path: /var/lib/tuwunel/media +# - id: archive +# kind: s3 +# url: s3://my-bucket/media +# region: us-east-1 +# key: AKIA... +# secret: '...' +# +# See: https://matrix-construct.github.io/tuwunel/media/storage.html +matrix_tuwunel_config_storage_providers: [] + +# Additional environment variables to pass to the container, one per line. +# Environment variables override the rendered config file. +# +# Example: +# matrix_tuwunel_environment_variables_extension: | +# TUWUNEL_REQUEST_TIMEOUT=60 +# TUWUNEL_DNS_CACHE_SIZE=131072 +matrix_tuwunel_environment_variables_extension: '' + +# matrix_tuwunel_restart_necessary controls whether the service will be restarted (when true) +# or merely started (when false) by the systemd service-manager role when conditional restart +# is enabled. Computed during installation based on whether config / unit / image changed. +matrix_tuwunel_restart_necessary: false diff --git a/roles/custom/matrix-tuwunel/tasks/install.yml b/roles/custom/matrix-tuwunel/tasks/install.yml new file mode 100644 index 000000000..4068f67d8 --- /dev/null +++ b/roles/custom/matrix-tuwunel/tasks/install.yml @@ -0,0 +1,77 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Ensure tuwunel config path exists + ansible.builtin.file: + path: "{{ matrix_tuwunel_config_path }}" + state: directory + mode: '0750' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + +- name: Ensure tuwunel data path exists + ansible.builtin.file: + path: "{{ matrix_tuwunel_data_path }}" + state: directory + mode: '0770' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + +- name: Ensure tuwunel configuration installed + ansible.builtin.template: + src: "{{ matrix_tuwunel_template_tuwunel_config }}" + dest: "{{ matrix_tuwunel_config_path }}/tuwunel.toml" + mode: '0644' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + register: matrix_tuwunel_config_result + +- name: Ensure tuwunel support files installed + ansible.builtin.template: + src: "{{ role_path }}/templates/{{ item }}.j2" + dest: "{{ matrix_tuwunel_base_path }}/{{ item }}" + mode: '0640' + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + with_items: + - labels + - env + register: matrix_tuwunel_support_files_result + +- name: Ensure tuwunel container network is created + when: matrix_tuwunel_container_network != 'host' + community.general.docker_network: + enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" + name: "{{ matrix_tuwunel_container_network }}" + driver: bridge + driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}" + +- name: Ensure tuwunel container image is pulled + community.docker.docker_image_pull: + name: "{{ matrix_tuwunel_container_image }}" + pull: always + register: matrix_tuwunel_container_image_pull_result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: matrix_tuwunel_container_image_pull_result is not failed + +- name: Ensure matrix-tuwunel.service installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-tuwunel.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-tuwunel.service" + mode: '0644' + register: matrix_tuwunel_systemd_service_result + +- name: Determine whether tuwunel needs a restart + ansible.builtin.set_fact: + matrix_tuwunel_restart_necessary: >- + {{ + matrix_tuwunel_config_result.changed | default(false) + or matrix_tuwunel_support_files_result.changed | default(false) + or matrix_tuwunel_systemd_service_result.changed | default(false) + or matrix_tuwunel_container_image_pull_result.changed | default(false) + }} diff --git a/roles/custom/matrix-tuwunel/tasks/main.yml b/roles/custom/matrix-tuwunel/tasks/main.yml new file mode 100644 index 000000000..9f81c2bcc --- /dev/null +++ b/roles/custom/matrix-tuwunel/tasks/main.yml @@ -0,0 +1,40 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- tags: + - setup-all + - setup-tuwunel + - install-all + - install-tuwunel + block: + - when: matrix_tuwunel_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml" + + - when: matrix_tuwunel_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/install.yml" + +- tags: + - setup-all + - setup-tuwunel + block: + - when: not matrix_tuwunel_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/uninstall.yml" + +- tags: + - self-check + block: + - when: matrix_tuwunel_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/self_check_client_api.yml" + + - when: matrix_tuwunel_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/self_check_federation_api.yml" + +- tags: + - tuwunel-migrate-from-conduwuit + block: + - when: matrix_tuwunel_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/migrate_from_conduwuit.yml" diff --git a/roles/custom/matrix-tuwunel/tasks/migrate_from_conduwuit.yml b/roles/custom/matrix-tuwunel/tasks/migrate_from_conduwuit.yml new file mode 100644 index 000000000..4b18a2f9c --- /dev/null +++ b/roles/custom/matrix-tuwunel/tasks/migrate_from_conduwuit.yml @@ -0,0 +1,83 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +# Migrates from the conduwuit server implementation (`/matrix/conduwuit`) to tuwunel (`/matrix/tuwunel`). +# Tuwunel is the official successor to conduwuit and reads conduwuit's RocksDB layout directly. +# We back up the freshly generated tuwunel directory, copy conduwuit's data into it, +# rename the config file, restore tuwunel's labels file, and start the new service. + +- name: Check existence of conduwuit directory + ansible.builtin.stat: + path: "{{ matrix_base_data_path }}/conduwuit" + register: matrix_removed_conduwuit_directory_stat + +- name: Check existence of tuwunel directory + ansible.builtin.stat: + path: "{{ matrix_base_data_path }}/tuwunel" + register: matrix_tuwunel_directory_stat + +- when: > + matrix_removed_conduwuit_directory_stat.stat.exists | bool and + matrix_tuwunel_directory_stat.stat.exists | bool + block: + - name: Ensure matrix-tuwunel.service systemd service is stopped + ansible.builtin.systemd: + name: matrix-tuwunel + state: stopped + enabled: false + daemon_reload: true + + - name: Ensure tuwunel directory is backed up + ansible.builtin.command: + cmd: "mv {{ matrix_base_data_path }}/tuwunel {{ matrix_base_data_path }}/tuwunel_old" + creates: "{{ matrix_base_data_path }}/tuwunel_old" + removes: "{{ matrix_base_data_path }}/tuwunel" + + - name: Ensure conduwuit directory contents are copied to tuwunel + ansible.builtin.copy: + src: "{{ matrix_base_data_path }}/conduwuit/" + dest: "{{ matrix_base_data_path }}/tuwunel" + remote_src: true + mode: preserve + + - name: Ensure conduwuit.toml file is renamed + ansible.builtin.command: + cmd: "mv {{ matrix_base_data_path }}/tuwunel/config/conduwuit.toml {{ matrix_base_data_path }}/tuwunel/config/tuwunel.toml" + removes: "{{ matrix_base_data_path }}/tuwunel/config/conduwuit.toml" + + - name: Ensure tuwunel labels are restored + ansible.builtin.copy: + src: "{{ matrix_base_data_path }}/tuwunel_old/labels" + dest: "{{ matrix_base_data_path }}/tuwunel/labels" + remote_src: true + force: true + mode: preserve + + - name: Ensure directories ownership is set + block: + - name: Set tuwunel ownership + ansible.builtin.file: + path: "{{ matrix_base_data_path }}/tuwunel" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + + - name: Set tuwunel_old ownership + ansible.builtin.file: + path: "{{ matrix_base_data_path }}/tuwunel_old" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + + - name: Ensure matrix-tuwunel.service systemd service is started + ansible.builtin.systemd: + name: matrix-tuwunel + state: started + enabled: true + daemon_reload: true diff --git a/roles/custom/matrix-tuwunel/tasks/self_check_client_api.yml b/roles/custom/matrix-tuwunel/tasks/self_check_client_api.yml new file mode 100644 index 000000000..76b4fbae8 --- /dev/null +++ b/roles/custom/matrix-tuwunel/tasks/self_check_client_api.yml @@ -0,0 +1,28 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Check Matrix Client API + ansible.builtin.uri: + url: "{{ matrix_tuwunel_client_api_url_endpoint_public }}" + follow_redirects: none + validate_certs: "{{ matrix_tuwunel_self_check_validate_certificates }}" + register: result_matrix_tuwunel_client_api + ignore_errors: true + check_mode: false + when: matrix_tuwunel_enabled | bool + delegate_to: 127.0.0.1 + become: false + +- name: Fail if Matrix Client API not working + ansible.builtin.fail: + msg: "Failed checking Matrix Client API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_client_api_url_endpoint_public }}`). Is tuwunel running? Is port 443 open in your firewall? Full error: {{ result_matrix_tuwunel_client_api }}" + when: "matrix_tuwunel_enabled | bool and (result_matrix_tuwunel_client_api.failed or 'json' not in result_matrix_tuwunel_client_api)" + +- name: Report working Matrix Client API + ansible.builtin.debug: + msg: "The Matrix Client API at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_client_api_url_endpoint_public }}`) is working" + when: matrix_tuwunel_enabled | bool diff --git a/roles/custom/matrix-tuwunel/tasks/self_check_federation_api.yml b/roles/custom/matrix-tuwunel/tasks/self_check_federation_api.yml new file mode 100644 index 000000000..250e2309b --- /dev/null +++ b/roles/custom/matrix-tuwunel/tasks/self_check_federation_api.yml @@ -0,0 +1,33 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Check Matrix Federation API + ansible.builtin.uri: + url: "{{ matrix_tuwunel_federation_api_url_endpoint_public }}" + follow_redirects: none + validate_certs: "{{ matrix_tuwunel_self_check_validate_certificates }}" + register: result_matrix_tuwunel_federation_api + ignore_errors: true + check_mode: false + when: matrix_tuwunel_enabled | bool + delegate_to: 127.0.0.1 + become: false + +- name: Fail if Matrix Federation API not working + ansible.builtin.fail: + msg: "Failed checking Matrix Federation API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_federation_api_url_endpoint_public }}`). Is tuwunel running? Is port {{ matrix_federation_public_port }} open in your firewall? Full error: {{ result_matrix_tuwunel_federation_api }}" + when: "matrix_tuwunel_enabled | bool and matrix_tuwunel_config_allow_federation | bool and (result_matrix_tuwunel_federation_api.failed or 'json' not in result_matrix_tuwunel_federation_api)" + +- name: Fail if Matrix Federation API unexpectedly enabled + ansible.builtin.fail: + msg: "Matrix Federation API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_federation_api_url_endpoint_public }}`) despite being disabled." + when: "matrix_tuwunel_enabled | bool and not matrix_tuwunel_config_allow_federation | bool and not result_matrix_tuwunel_federation_api.failed" + +- name: Report working Matrix Federation API + ansible.builtin.debug: + msg: "The Matrix Federation API at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_federation_api_url_endpoint_public }}`) is working" + when: "matrix_tuwunel_enabled | bool and matrix_tuwunel_config_allow_federation | bool" diff --git a/roles/custom/matrix-tuwunel/tasks/setup_install.yml b/roles/custom/matrix-tuwunel/tasks/setup_install.yml new file mode 100644 index 000000000..ad902b413 --- /dev/null +++ b/roles/custom/matrix-tuwunel/tasks/setup_install.yml @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- ansible.builtin.include_tasks: "{{ role_path }}/tasks/install.yml" diff --git a/roles/custom/matrix-tuwunel/tasks/setup_uninstall.yml b/roles/custom/matrix-tuwunel/tasks/setup_uninstall.yml new file mode 100644 index 000000000..ffa4482df --- /dev/null +++ b/roles/custom/matrix-tuwunel/tasks/setup_uninstall.yml @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- ansible.builtin.include_tasks: "{{ role_path }}/tasks/uninstall.yml" diff --git a/roles/custom/matrix-tuwunel/tasks/uninstall.yml b/roles/custom/matrix-tuwunel/tasks/uninstall.yml new file mode 100644 index 000000000..af62b7589 --- /dev/null +++ b/roles/custom/matrix-tuwunel/tasks/uninstall.yml @@ -0,0 +1,24 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: Check existence of matrix-tuwunel service + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-tuwunel.service" + register: matrix_tuwunel_service_stat + +- when: matrix_tuwunel_service_stat.stat.exists | bool + block: + - name: Ensure matrix-tuwunel is stopped + ansible.builtin.systemd: + name: matrix-tuwunel + state: stopped + daemon_reload: true + + - name: Ensure matrix-tuwunel.service doesn't exist + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-tuwunel.service" + state: absent diff --git a/roles/custom/matrix-tuwunel/tasks/validate_config.yml b/roles/custom/matrix-tuwunel/tasks/validate_config.yml new file mode 100644 index 000000000..7a1c52cad --- /dev/null +++ b/roles/custom/matrix-tuwunel/tasks/validate_config.yml @@ -0,0 +1,53 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +- name: (Deprecation) Catch and report renamed tuwunel variables + ansible.builtin.fail: + msg: >- + Your configuration contains a variable, which now has a different name. + Please rename the variable (`{{ item.old }}` -> `{{ item.new }}`) on your configuration file (vars.yml). + when: "lookup('ansible.builtin.varnames', ('^' + item.old + '$'), wantlist=True) | length > 0" + with_items: + - {'old': 'matrix_tuwunel_config_ldap_name_attribute', 'new': '<removed> (tuwunel v1.9.0 dropped the option; the localpart must appear in the attribute named by `matrix_tuwunel_config_ldap_uid_attribute`)'} + +- name: Fail if required tuwunel settings not defined + ansible.builtin.fail: + msg: >- + You need to define a required configuration setting (`{{ item.name }}`). + when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0" + with_items: + - {'name': 'matrix_tuwunel_hostname', when: true} + - {'name': 'matrix_tuwunel_container_network', when: true} + - {'name': 'matrix_tuwunel_container_labels_internal_client_api_traefik_entrypoints', when: "{{ matrix_tuwunel_container_labels_internal_client_api_enabled }}"} + +- name: Fail if registration is enabled without a token or explicit acknowledgement + ansible.builtin.fail: + msg: >- + `matrix_tuwunel_config_allow_registration` is true, but neither + `matrix_tuwunel_config_registration_token` nor + `matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse` + is set. Set a registration token (recommended) or explicitly opt in to open registration. + when: >- + matrix_tuwunel_config_allow_registration | bool + and (matrix_tuwunel_config_registration_token | length == 0) + and not (matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse | bool) + +- name: Fail if a storage provider is missing required fields + ansible.builtin.fail: + msg: >- + Storage provider `{{ item.id | default('?') }}` is missing required fields. + Each entry must define both `id` and `kind` (one of: local, s3). + when: "(item.id | default('') | length == 0) or (item.kind | default('') not in ['local', 's3'])" + with_items: "{{ matrix_tuwunel_config_storage_providers }}" + +- name: Fail if an identity provider is missing required fields + ansible.builtin.fail: + msg: >- + Identity provider entry is missing both `client_id` and `brand`. + At minimum one of these is required for tuwunel to identify the provider. + when: "(item.client_id | default('') | length == 0) and (item.brand | default('') | length == 0)" + with_items: "{{ matrix_tuwunel_config_identity_providers }}" diff --git a/roles/custom/matrix-tuwunel/templates/env.j2 b/roles/custom/matrix-tuwunel/templates/env.j2 new file mode 100644 index 000000000..1ad68e77f --- /dev/null +++ b/roles/custom/matrix-tuwunel/templates/env.j2 @@ -0,0 +1 @@ +{{ matrix_tuwunel_environment_variables_extension }} diff --git a/roles/custom/matrix-tuwunel/templates/env.j2.license b/roles/custom/matrix-tuwunel/templates/env.j2.license new file mode 100644 index 000000000..d9e39e34f --- /dev/null +++ b/roles/custom/matrix-tuwunel/templates/env.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-tuwunel/templates/labels.j2 b/roles/custom/matrix-tuwunel/templates/labels.j2 new file mode 100644 index 000000000..f68586a25 --- /dev/null +++ b/roles/custom/matrix-tuwunel/templates/labels.j2 @@ -0,0 +1,247 @@ +{# +SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later +#} + +{% if matrix_tuwunel_container_labels_traefik_enabled %} +traefik.enable=true + +{% if matrix_tuwunel_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_tuwunel_container_labels_traefik_docker_network }} +{% endif %} + +traefik.http.services.matrix-tuwunel.loadbalancer.server.port={{ matrix_tuwunel_config_port_number }} + + +{% if matrix_tuwunel_container_labels_public_client_root_enabled %} +############################################################ +# # +# Public Root path (/) # +# # +############################################################ + +{% set client_root_middlewares = [] %} + +{% if matrix_tuwunel_container_labels_public_client_root_redirection_enabled %} +{% set client_root_middlewares = client_root_middlewares + ['matrix-tuwunel-client-root-redirect'] %} +traefik.http.middlewares.matrix-tuwunel-client-root-redirect.redirectregex.regex=(.*) +traefik.http.middlewares.matrix-tuwunel-client-root-redirect.redirectregex.replacement={{ matrix_tuwunel_container_labels_public_client_root_redirection_url }} +{% endif %} + +traefik.http.routers.matrix-tuwunel-public-client-root.rule={{ matrix_tuwunel_container_labels_public_client_root_traefik_rule }} + +traefik.http.routers.matrix-tuwunel-public-client-root.middlewares={{ client_root_middlewares | join(',') }} + +{% if matrix_tuwunel_container_labels_public_client_root_traefik_priority | int > 0 %} +traefik.http.routers.matrix-tuwunel-public-client-root.priority={{ matrix_tuwunel_container_labels_public_client_root_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-tuwunel-public-client-root.service=matrix-tuwunel +traefik.http.routers.matrix-tuwunel-public-client-root.entrypoints={{ matrix_tuwunel_container_labels_public_client_root_traefik_entrypoints }} +traefik.http.routers.matrix-tuwunel-public-client-root.tls={{ matrix_tuwunel_container_labels_public_client_root_traefik_tls | to_json }} + +{% if matrix_tuwunel_container_labels_public_client_root_traefik_tls %} +traefik.http.routers.matrix-tuwunel-public-client-root.tls.certResolver={{ matrix_tuwunel_container_labels_public_client_root_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Public Root path (/) # +# # +############################################################ +{% endif %} + + +{% if matrix_tuwunel_container_labels_public_client_api_enabled %} +############################################################ +# # +# Public Client-API (/_matrix) # +# # +############################################################ + +traefik.http.routers.matrix-tuwunel-public-client-api.rule={{ matrix_tuwunel_container_labels_public_client_api_traefik_rule }} + +{% if matrix_tuwunel_container_labels_public_client_api_traefik_priority | int > 0 %} +traefik.http.routers.matrix-tuwunel-public-client-api.priority={{ matrix_tuwunel_container_labels_public_client_api_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-tuwunel-public-client-api.service=matrix-tuwunel +traefik.http.routers.matrix-tuwunel-public-client-api.entrypoints={{ matrix_tuwunel_container_labels_public_client_api_traefik_entrypoints }} + +traefik.http.routers.matrix-tuwunel-public-client-api.tls={{ matrix_tuwunel_container_labels_public_client_api_traefik_tls | to_json }} +{% if matrix_tuwunel_container_labels_public_client_api_traefik_tls %} +traefik.http.routers.matrix-tuwunel-public-client-api.tls.certResolver={{ matrix_tuwunel_container_labels_public_client_api_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Public Client-API (/_matrix) # +# # +############################################################ +{% endif %} + + +{% if matrix_tuwunel_container_labels_internal_client_api_enabled %} +############################################################ +# # +# Internal Client-API (/_matrix) # +# # +############################################################ + +traefik.http.routers.matrix-tuwunel-internal-client-api.rule={{ matrix_tuwunel_container_labels_internal_client_api_traefik_rule }} + +{% if matrix_tuwunel_container_labels_internal_client_api_traefik_priority | int > 0 %} +traefik.http.routers.matrix-tuwunel-internal-client-api.priority={{ matrix_tuwunel_container_labels_internal_client_api_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-tuwunel-internal-client-api.service=matrix-tuwunel +traefik.http.routers.matrix-tuwunel-internal-client-api.entrypoints={{ matrix_tuwunel_container_labels_internal_client_api_traefik_entrypoints }} + +############################################################ +# # +# /Internal Client-API (/_matrix) # +# # +############################################################ +{% endif %} + + +{% if matrix_tuwunel_container_labels_public_federation_api_enabled %} +############################################################ +# # +# Public Federation-API (/_matrix) # +# # +############################################################ + +traefik.http.routers.matrix-tuwunel-public-federation-api.rule={{ matrix_tuwunel_container_labels_public_federation_api_traefik_rule }} + +{% if matrix_tuwunel_container_labels_public_federation_api_traefik_priority | int > 0 %} +traefik.http.routers.matrix-tuwunel-public-federation-api.priority={{ matrix_tuwunel_container_labels_public_federation_api_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-tuwunel-public-federation-api.service=matrix-tuwunel +traefik.http.routers.matrix-tuwunel-public-federation-api.entrypoints={{ matrix_tuwunel_container_labels_public_federation_api_traefik_entrypoints }} + +traefik.http.routers.matrix-tuwunel-public-federation-api.tls={{ matrix_tuwunel_container_labels_public_federation_api_traefik_tls | to_json }} +{% if matrix_tuwunel_container_labels_public_federation_api_traefik_tls %} +traefik.http.routers.matrix-tuwunel-public-federation-api.tls.certResolver={{ matrix_tuwunel_container_labels_public_federation_api_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Public Federation-API (/_matrix) # +# # +############################################################ +{% endif %} + + +{% if matrix_tuwunel_container_labels_public_tuwunel_api_enabled %} +############################################################ +# # +# Public Tuwunel API (/_tuwunel) # +# # +############################################################ + +traefik.http.routers.matrix-tuwunel-public-tuwunel-api.rule={{ matrix_tuwunel_container_labels_public_tuwunel_api_traefik_rule }} + +{% if matrix_tuwunel_container_labels_public_tuwunel_api_traefik_priority | int > 0 %} +traefik.http.routers.matrix-tuwunel-public-tuwunel-api.priority={{ matrix_tuwunel_container_labels_public_tuwunel_api_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-tuwunel-public-tuwunel-api.service=matrix-tuwunel +traefik.http.routers.matrix-tuwunel-public-tuwunel-api.entrypoints={{ matrix_tuwunel_container_labels_public_tuwunel_api_traefik_entrypoints }} + +traefik.http.routers.matrix-tuwunel-public-tuwunel-api.tls={{ matrix_tuwunel_container_labels_public_tuwunel_api_traefik_tls | to_json }} +{% if matrix_tuwunel_container_labels_public_tuwunel_api_traefik_tls %} +traefik.http.routers.matrix-tuwunel-public-tuwunel-api.tls.certResolver={{ matrix_tuwunel_container_labels_public_tuwunel_api_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Public Tuwunel API (/_tuwunel) # +# # +############################################################ +{% endif %} + + +{% if matrix_tuwunel_container_labels_internal_tuwunel_api_enabled %} +############################################################ +# # +# Internal Tuwunel API (/_tuwunel) # +# # +############################################################ + +traefik.http.routers.matrix-tuwunel-internal-tuwunel-api.rule={{ matrix_tuwunel_container_labels_internal_tuwunel_api_traefik_rule }} + +{% if matrix_tuwunel_container_labels_internal_tuwunel_api_traefik_priority | int > 0 %} +traefik.http.routers.matrix-tuwunel-internal-tuwunel-api.priority={{ matrix_tuwunel_container_labels_internal_tuwunel_api_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-tuwunel-internal-tuwunel-api.service=matrix-tuwunel +traefik.http.routers.matrix-tuwunel-internal-tuwunel-api.entrypoints={{ matrix_tuwunel_container_labels_internal_tuwunel_api_traefik_entrypoints }} + +############################################################ +# # +# /Internal Tuwunel API (/_tuwunel) # +# # +############################################################ +{% endif %} + + +{% if matrix_tuwunel_container_labels_public_client_synapse_admin_api_enabled %} +############################################################ +# # +# Public Synapse Admin API (/_synapse/admin) # +# # +############################################################ + +traefik.http.routers.matrix-tuwunel-public-client-synapse-admin-api.rule={{ matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_rule }} + +{% if matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_priority | int > 0 %} +traefik.http.routers.matrix-tuwunel-public-client-synapse-admin-api.priority={{ matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-tuwunel-public-client-synapse-admin-api.service=matrix-tuwunel +traefik.http.routers.matrix-tuwunel-public-client-synapse-admin-api.entrypoints={{ matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_entrypoints }} + +traefik.http.routers.matrix-tuwunel-public-client-synapse-admin-api.tls={{ matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_tls | to_json }} +{% if matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_tls %} +traefik.http.routers.matrix-tuwunel-public-client-synapse-admin-api.tls.certResolver={{ matrix_tuwunel_container_labels_public_client_synapse_admin_api_traefik_tls_certResolver }} +{% endif %} + +############################################################ +# # +# /Public Synapse Admin API (/_synapse/admin) # +# # +############################################################ +{% endif %} + + +{% if matrix_tuwunel_container_labels_internal_client_synapse_admin_api_enabled %} +############################################################ +# # +# Internal Synapse Admin API (/_synapse/admin) # +# # +############################################################ + +traefik.http.routers.matrix-tuwunel-internal-client-synapse-admin-api.rule={{ matrix_tuwunel_container_labels_internal_client_synapse_admin_api_traefik_rule }} + +{% if matrix_tuwunel_container_labels_internal_client_synapse_admin_api_traefik_priority | int > 0 %} +traefik.http.routers.matrix-tuwunel-internal-client-synapse-admin-api.priority={{ matrix_tuwunel_container_labels_internal_client_synapse_admin_api_traefik_priority }} +{% endif %} + +traefik.http.routers.matrix-tuwunel-internal-client-synapse-admin-api.service=matrix-tuwunel +traefik.http.routers.matrix-tuwunel-internal-client-synapse-admin-api.entrypoints={{ matrix_tuwunel_container_labels_internal_client_synapse_admin_api_traefik_entrypoints }} + +############################################################ +# # +# /Internal Synapse Admin API (/_synapse/admin) # +# # +############################################################ +{% endif %} + + +{% endif %} + +{{ matrix_tuwunel_container_labels_additional_labels }} diff --git a/roles/custom/matrix-tuwunel/templates/systemd/matrix-tuwunel.service.j2 b/roles/custom/matrix-tuwunel/templates/systemd/matrix-tuwunel.service.j2 new file mode 100644 index 000000000..05af8f7ab --- /dev/null +++ b/roles/custom/matrix-tuwunel/templates/systemd/matrix-tuwunel.service.j2 @@ -0,0 +1,57 @@ +#jinja2: lstrip_blocks: True +[Unit] +Description=Tuwunel Matrix homeserver +{% for service in matrix_tuwunel_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_tuwunel_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} + +[Service] +Type=simple +Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-tuwunel 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-tuwunel 2>/dev/null || true' + +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ + --rm \ + --name=matrix-tuwunel \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_tuwunel_tmp_directory_size_mb }}m \ + --network={{ matrix_tuwunel_container_network }} \ + --env-file={{ matrix_tuwunel_base_path }}/env \ + --env TUWUNEL_CONFIG=/etc/tuwunel/tuwunel.toml \ + --label-file={{ matrix_tuwunel_base_path }}/labels \ + --mount type=bind,src={{ matrix_tuwunel_data_path }},dst=/var/lib/tuwunel \ + --mount type=bind,src={{ matrix_tuwunel_config_path }},dst=/etc/tuwunel,ro \ + {% for arg in matrix_tuwunel_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_tuwunel_container_image }} + +{% if matrix_tuwunel_container_network != 'host' %} +{% for network in matrix_tuwunel_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-tuwunel +{% endfor %} +{% endif %} + +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-tuwunel + +{% if matrix_tuwunel_systemd_service_post_start_delay_seconds != 0 %} +ExecStartPost=-{{ matrix_host_command_sleep }} {{ matrix_tuwunel_systemd_service_post_start_delay_seconds }} +{% endif %} + +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-tuwunel 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-tuwunel 2>/dev/null || true' +ExecReload={{ devture_systemd_docker_base_host_command_docker }} exec matrix-tuwunel /bin/sh -c 'kill -HUP 1' +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-tuwunel + +[Install] +WantedBy=multi-user.target diff --git a/roles/custom/matrix-tuwunel/templates/systemd/matrix-tuwunel.service.j2.license b/roles/custom/matrix-tuwunel/templates/systemd/matrix-tuwunel.service.j2.license new file mode 100644 index 000000000..d9e39e34f --- /dev/null +++ b/roles/custom/matrix-tuwunel/templates/systemd/matrix-tuwunel.service.j2.license @@ -0,0 +1,4 @@ +SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2 b/roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2 new file mode 100644 index 000000000..a1c381039 --- /dev/null +++ b/roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2 @@ -0,0 +1,243 @@ +{# +SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev + +SPDX-License-Identifier: AGPL-3.0-or-later +#} +### Tuwunel configuration rendered by matrix-docker-ansible-deploy. +### +### This file only emits options exposed as Ansible variables. All other knobs +### keep tuwunel's upstream defaults. To override anything not surfaced here, +### use `matrix_tuwunel_environment_variables_extension` (env vars override TOML) +### or replace the template via `matrix_tuwunel_template_tuwunel_config`. +### +### Reference: https://matrix-construct.github.io/tuwunel/configuration.html + +[global] +server_name = {{ matrix_tuwunel_config_server_name | to_json }} +address = "0.0.0.0" +port = {{ matrix_tuwunel_config_port_number }} +database_path = "/var/lib/tuwunel" + +max_request_size = {{ matrix_tuwunel_config_max_request_size }} + +new_user_displayname_suffix = {{ matrix_tuwunel_config_new_user_displayname_suffix | to_json }} + +allow_registration = {{ matrix_tuwunel_config_allow_registration | to_json }} +{% if matrix_tuwunel_config_registration_token | length > 0 %} +registration_token = {{ matrix_tuwunel_config_registration_token | to_json }} +{% endif %} +{% if matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse | bool %} +yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true +{% endif %} + +{% if matrix_tuwunel_config_emergency_password | length > 0 %} +emergency_password = {{ matrix_tuwunel_config_emergency_password | to_json }} +{% endif %} + +allow_encryption = {{ matrix_tuwunel_config_allow_encryption | to_json }} +allow_room_creation = {{ matrix_tuwunel_config_allow_room_creation | to_json }} +default_room_version = {{ matrix_tuwunel_config_default_room_version | to_json }} +{% if matrix_tuwunel_config_auto_join_rooms | length > 0 %} +auto_join_rooms = {{ matrix_tuwunel_config_auto_join_rooms | to_json }} +{% endif %} + +allow_federation = {{ matrix_tuwunel_config_allow_federation | to_json }} +trusted_servers = {{ matrix_tuwunel_config_trusted_servers | to_json }} +{% if matrix_tuwunel_config_allowed_remote_server_names | length > 0 %} +allowed_remote_server_names_experimental = {{ matrix_tuwunel_config_allowed_remote_server_names | to_json }} +{% endif %} +{% if matrix_tuwunel_config_forbidden_remote_server_names | length > 0 %} +forbidden_remote_server_names = {{ matrix_tuwunel_config_forbidden_remote_server_names | to_json }} +{% endif %} +{% if matrix_tuwunel_config_forbidden_remote_room_directory_server_names | length > 0 %} +forbidden_remote_room_directory_server_names = {{ matrix_tuwunel_config_forbidden_remote_room_directory_server_names | to_json }} +{% endif %} +{% if matrix_tuwunel_config_prevent_media_downloads_from | length > 0 %} +prevent_media_downloads_from = {{ matrix_tuwunel_config_prevent_media_downloads_from | to_json }} +{% endif %} +ip_range_denylist = {{ matrix_tuwunel_config_ip_range_denylist | to_json }} + +enable_policy_servers = {{ matrix_tuwunel_config_enable_policy_servers | to_json }} +policy_server_request_timeout = {{ matrix_tuwunel_config_policy_server_request_timeout }} + +msc3664_related_event_match = {{ matrix_tuwunel_config_msc3664_related_event_match | to_json }} + +allow_outgoing_presence = {{ matrix_tuwunel_config_allow_outgoing_presence | to_json }} + +{% if matrix_tuwunel_config_url_preview_domain_contains_allowlist | length > 0 %} +url_preview_domain_contains_allowlist = {{ matrix_tuwunel_config_url_preview_domain_contains_allowlist | to_json }} +{% endif %} +{% if matrix_tuwunel_config_url_preview_domain_explicit_allowlist | length > 0 %} +url_preview_domain_explicit_allowlist = {{ matrix_tuwunel_config_url_preview_domain_explicit_allowlist | to_json }} +{% endif %} +url_preview_check_root_domain = {{ matrix_tuwunel_config_url_preview_check_root_domain | to_json }} + +create_admin_room = {{ matrix_tuwunel_config_create_admin_room | to_json }} +federate_admin_room = {{ matrix_tuwunel_config_federate_admin_room | to_json }} +grant_admin_to_first_user = {{ matrix_tuwunel_config_grant_admin_to_first_user | to_json }} + +log = {{ matrix_tuwunel_config_log | to_json }} + +{% if matrix_tuwunel_config_turn_uris | length > 0 %} +turn_uris = {{ matrix_tuwunel_config_turn_uris | to_json }} +{% endif %} +{% if matrix_tuwunel_config_turn_secret | length > 0 %} +turn_secret = {{ matrix_tuwunel_config_turn_secret | to_json }} +{% endif %} +{% if matrix_tuwunel_config_turn_username | length > 0 %} +turn_username = {{ matrix_tuwunel_config_turn_username | to_json }} +{% endif %} +{% if matrix_tuwunel_config_turn_password | length > 0 %} +turn_password = {{ matrix_tuwunel_config_turn_password | to_json }} +{% endif %} + +{% if matrix_tuwunel_config_rocksdb_compression_algo | length > 0 %} +rocksdb_compression_algo = {{ matrix_tuwunel_config_rocksdb_compression_algo | to_json }} +{% endif %} +{% if matrix_tuwunel_config_rocksdb_compression_level | string | length > 0 %} +rocksdb_compression_level = {{ matrix_tuwunel_config_rocksdb_compression_level }} +{% endif %} +{% if matrix_tuwunel_config_rocksdb_bottommost_compression_level | string | length > 0 %} +rocksdb_bottommost_compression_level = {{ matrix_tuwunel_config_rocksdb_bottommost_compression_level }} +{% endif %} +rocksdb_direct_io = {{ matrix_tuwunel_config_rocksdb_direct_io | to_json }} +{% if matrix_tuwunel_config_rocksdb_parallelism_threads | int > 0 %} +rocksdb_parallelism_threads = {{ matrix_tuwunel_config_rocksdb_parallelism_threads }} +{% endif %} +{% if matrix_tuwunel_config_rocksdb_max_log_file_size | string | length > 0 %} +rocksdb_max_log_file_size = {{ matrix_tuwunel_config_rocksdb_max_log_file_size }} +{% endif %} +{% if matrix_tuwunel_config_rocksdb_log_time_to_roll | string | length > 0 %} +rocksdb_log_time_to_roll = {{ matrix_tuwunel_config_rocksdb_log_time_to_roll }} +{% endif %} +{% if matrix_tuwunel_config_database_backup_path | length > 0 %} +database_backup_path = {{ matrix_tuwunel_config_database_backup_path | to_json }} +database_backups_to_keep = {{ matrix_tuwunel_config_database_backups_to_keep }} +{% endif %} + +{% if matrix_tuwunel_config_cache_capacity_modifier | string | length > 0 %} +cache_capacity_modifier = {{ matrix_tuwunel_config_cache_capacity_modifier }} +{% endif %} +{% if matrix_tuwunel_config_db_cache_capacity_mb | string | length > 0 %} +db_cache_capacity_mb = {{ matrix_tuwunel_config_db_cache_capacity_mb }} +{% endif %} +{% if matrix_tuwunel_config_db_write_buffer_capacity_mb | string | length > 0 %} +db_write_buffer_capacity_mb = {{ matrix_tuwunel_config_db_write_buffer_capacity_mb }} +{% endif %} + +{% if matrix_tuwunel_config_sentry_enabled | bool %} +sentry = true +{% if matrix_tuwunel_config_sentry_endpoint | length > 0 %} +sentry_endpoint = {{ matrix_tuwunel_config_sentry_endpoint | to_json }} +{% endif %} +sentry_send_server_name = {{ matrix_tuwunel_config_sentry_send_server_name | to_json }} +sentry_traces_sample_rate = {{ matrix_tuwunel_config_sentry_traces_sample_rate }} +{% endif %} + +{% if (matrix_tuwunel_config_tls_certs | length > 0) and (matrix_tuwunel_config_tls_key | length > 0) %} + +[global.tls] +certs = {{ matrix_tuwunel_config_tls_certs | to_json }} +key = {{ matrix_tuwunel_config_tls_key | to_json }} +dual_protocol = {{ matrix_tuwunel_config_tls_dual_protocol | to_json }} +{% endif %} + +{% set well_known_keys = [ + matrix_tuwunel_config_well_known_client, + matrix_tuwunel_config_well_known_server, + matrix_tuwunel_config_well_known_support_page, + matrix_tuwunel_config_well_known_support_email, + matrix_tuwunel_config_well_known_support_mxid, + matrix_tuwunel_config_well_known_livekit_url, +] %} +{% if well_known_keys | select | list | length > 0 %} + +[global.well_known] +{% if matrix_tuwunel_config_well_known_client | length > 0 %} +client = {{ matrix_tuwunel_config_well_known_client | to_json }} +{% endif %} +{% if matrix_tuwunel_config_well_known_server | length > 0 %} +server = {{ matrix_tuwunel_config_well_known_server | to_json }} +{% endif %} +{% if matrix_tuwunel_config_well_known_support_page | length > 0 %} +support_page = {{ matrix_tuwunel_config_well_known_support_page | to_json }} +{% endif %} +{% if matrix_tuwunel_config_well_known_support_email | length > 0 %} +support_email = {{ matrix_tuwunel_config_well_known_support_email | to_json }} +{% endif %} +{% if matrix_tuwunel_config_well_known_support_mxid | length > 0 %} +support_mxid = {{ matrix_tuwunel_config_well_known_support_mxid | to_json }} +{% endif %} +{% if matrix_tuwunel_config_well_known_livekit_url | length > 0 %} +livekit_url = {{ matrix_tuwunel_config_well_known_livekit_url | to_json }} +{% endif %} +{% endif %} + +{% if matrix_tuwunel_config_blurhashing_enabled | bool %} + +[global.blurhashing] +components_x = {{ matrix_tuwunel_config_blurhashing_components_x }} +components_y = {{ matrix_tuwunel_config_blurhashing_components_y }} +blurhash_max_raw_size = {{ matrix_tuwunel_config_blurhashing_max_raw_size }} +{% endif %} + +{% if matrix_tuwunel_config_ldap_enabled | bool %} + +[global.ldap] +enable = true +uri = {{ matrix_tuwunel_config_ldap_uri | to_json }} +base_dn = {{ matrix_tuwunel_config_ldap_base_dn | to_json }} +{% if matrix_tuwunel_config_ldap_bind_dn | length > 0 %} +bind_dn = {{ matrix_tuwunel_config_ldap_bind_dn | to_json }} +{% endif %} +{% if matrix_tuwunel_config_ldap_bind_password_file | length > 0 %} +bind_password_file = {{ matrix_tuwunel_config_ldap_bind_password_file | to_json }} +{% endif %} +filter = {{ matrix_tuwunel_config_ldap_filter | to_json }} +uid_attribute = {{ matrix_tuwunel_config_ldap_uid_attribute | to_json }} +{% if matrix_tuwunel_config_ldap_admin_base_dn | length > 0 %} +admin_base_dn = {{ matrix_tuwunel_config_ldap_admin_base_dn | to_json }} +{% endif %} +{% if matrix_tuwunel_config_ldap_admin_filter | length > 0 %} +admin_filter = {{ matrix_tuwunel_config_ldap_admin_filter | to_json }} +{% endif %} +{% endif %} + +{% if matrix_tuwunel_config_jwt_enabled | bool %} + +[global.jwt] +enable = true +{% if matrix_tuwunel_config_jwt_key | length > 0 %} +key = {{ matrix_tuwunel_config_jwt_key | to_json }} +{% endif %} +format = {{ matrix_tuwunel_config_jwt_format | to_json }} +algorithm = {{ matrix_tuwunel_config_jwt_algorithm | to_json }} +register_user = {{ matrix_tuwunel_config_jwt_register_user | to_json }} +{% if matrix_tuwunel_config_jwt_audience | length > 0 %} +audience = {{ matrix_tuwunel_config_jwt_audience | to_json }} +{% endif %} +{% if matrix_tuwunel_config_jwt_issuer | length > 0 %} +issuer = {{ matrix_tuwunel_config_jwt_issuer | to_json }} +{% endif %} +require_exp = {{ matrix_tuwunel_config_jwt_require_exp | to_json }} +require_nbf = {{ matrix_tuwunel_config_jwt_require_nbf | to_json }} +validate_exp = {{ matrix_tuwunel_config_jwt_validate_exp | to_json }} +validate_nbf = {{ matrix_tuwunel_config_jwt_validate_nbf | to_json }} +{% endif %} + +{% for idp in matrix_tuwunel_config_identity_providers %} + +[[global.identity_provider]] +{% for key, value in idp.items() %} +{{ key }} = {{ value | to_json }} +{% endfor %} +{% endfor %} + +{% for sp in matrix_tuwunel_config_storage_providers %} + +[global.storage_provider.{{ sp.id }}.{{ sp.kind }}] +{% for key, value in sp.items() if key not in ['id', 'kind'] %} +{{ key }} = {{ value | to_json }} +{% endfor %} +{% endfor %} diff --git a/roles/custom/matrix-tuwunel/vars/main.yml b/roles/custom/matrix-tuwunel/vars/main.yml new file mode 100644 index 000000000..22924cc4a --- /dev/null +++ b/roles/custom/matrix-tuwunel/vars/main.yml @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: 2025 - 2026 MDAD project contributors +# SPDX-FileCopyrightText: 2025 - 2026 Slavi Pantaleev +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +--- + +matrix_tuwunel_client_api_url_endpoint_public: "{{ 'https' if matrix_playbook_ssl_enabled else 'http' }}://{{ matrix_tuwunel_hostname }}/_matrix/client/versions" +matrix_tuwunel_federation_api_url_endpoint_public: "{{ 'https' if matrix_playbook_ssl_enabled else 'http' }}://{{ matrix_tuwunel_hostname }}:{{ matrix_federation_public_port }}/_matrix/federation/v1/version" diff --git a/roles/custom/matrix-user-verification-service/defaults/main.yml b/roles/custom/matrix-user-verification-service/defaults/main.yml index bff5c1ca3..7e3bc963f 100644 --- a/roles/custom/matrix-user-verification-service/defaults/main.yml +++ b/roles/custom/matrix-user-verification-service/defaults/main.yml @@ -18,7 +18,7 @@ matrix_user_verification_service_enabled: true matrix_user_verification_service_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" matrix_user_verification_service_container_image_self_build_repo: "https://github.com/matrix-org/matrix-user-verification-service" -matrix_user_verification_service_container_image_self_build_branch: "{{ 'master' if matrix_registration_version == 'latest' else matrix_user_verification_service_version }}" +matrix_user_verification_service_container_image_self_build_branch: "{{ matrix_user_verification_service_version }}" # renovate: datasource=docker depName=matrixdotorg/matrix-user-verification-service matrix_user_verification_service_version: "v3.0.0" @@ -34,7 +34,6 @@ matrix_user_verification_service_container_image: "{{ matrix_user_verification_s matrix_user_verification_service_container_image_registry_prefix: "{{ 'localhost/' if matrix_user_verification_service_container_image_self_build else matrix_user_verification_service_container_image_registry_prefix_upstream }}" matrix_user_verification_service_container_image_registry_prefix_upstream: "{{ matrix_user_verification_service_container_image_registry_prefix_upstream_default }}" matrix_user_verification_service_container_image_registry_prefix_upstream_default: "docker.io/" -matrix_user_verification_service_container_image_force_pull: "{{ matrix_user_verification_service_container_image.endswith(':latest') }}" # The base container network. It will be auto-created by this role if it doesn't exist already. matrix_user_verification_service_container_network: "" diff --git a/roles/custom/matrix-user-verification-service/tasks/setup_install.yml b/roles/custom/matrix-user-verification-service/tasks/setup_install.yml index d0d2dd656..533380c7c 100644 --- a/roles/custom/matrix-user-verification-service/tasks/setup_install.yml +++ b/roles/custom/matrix-user-verification-service/tasks/setup_install.yml @@ -19,17 +19,25 @@ when: item.when | bool - name: Ensure Matrix User Verification Service image is pulled - community.docker.docker_image: + community.docker.docker_image_pull: name: "{{ matrix_user_verification_service_container_image }}" - source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" - force_source: "{{ matrix_user_verification_service_container_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_user_verification_service_container_image_force_pull }}" + pull: always register: matrix_user_verification_service_container_image_pull_result retries: "{{ devture_playbook_help_container_retries_count }}" delay: "{{ devture_playbook_help_container_retries_delay }}" until: matrix_user_verification_service_container_image_pull_result is not failed when: "not matrix_user_verification_service_container_image_self_build | bool" +# A checkout owned by a different user (a uid change, an earlier clone by another user, etc.) would make the git task below fail on ownership or permissions. +- name: Ensure Matrix User Verification Service repository ownership is correct when self-building + ansible.builtin.file: + path: "{{ matrix_user_verification_service_container_src_files_path }}" + state: directory + owner: "{{ matrix_user_name }}" + group: "{{ matrix_group_name }}" + recurse: true + when: "matrix_user_verification_service_container_image_self_build | bool" + - name: Ensure Matrix User Verification Service repository is present when self-building ansible.builtin.git: repo: "{{ matrix_user_verification_service_container_image_self_build_repo }}" @@ -42,16 +50,14 @@ when: "matrix_user_verification_service_container_image_self_build | bool" - name: Ensure Matrix User Verification Service image is built - community.docker.docker_image: + community.docker.docker_image_build: name: "{{ matrix_user_verification_service_container_image }}" - source: build - force_source: "{{ matrix_user_verification_service_git_pull_results.changed if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" - force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_user_verification_service_git_pull_results.changed }}" - build: - dockerfile: Dockerfile - path: "{{ matrix_user_verification_service_container_src_files_path }}" - pull: true + dockerfile: Dockerfile + path: "{{ matrix_user_verification_service_container_src_files_path }}" + pull: true + rebuild: "{{ 'always' if matrix_user_verification_service_git_pull_results.changed | bool else 'never' }}" when: "matrix_user_verification_service_container_image_self_build | bool" + register: matrix_user_verification_service_container_image_build_result - name: Ensure Matrix User Verification Service env file installed ansible.builtin.template: @@ -63,6 +69,7 @@ register: matrix_user_verification_service_config_result - name: Ensure matrix-user-verification-service container network is created + when: matrix_user_verification_service_container_network != 'host' community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" name: "{{ matrix_user_verification_service_container_network }}" @@ -83,4 +90,5 @@ matrix_user_verification_service_config_result.changed | default(false) or matrix_user_verification_service_systemd_service_result.changed | default(false) or matrix_user_verification_service_container_image_pull_result.changed | default(false) + or matrix_user_verification_service_container_image_build_result.changed | default(false) }} diff --git a/roles/custom/matrix-user-verification-service/tasks/validate_config.yml b/roles/custom/matrix-user-verification-service/tasks/validate_config.yml index 6d7d9f04d..d39fa6b35 100644 --- a/roles/custom/matrix-user-verification-service/tasks/validate_config.yml +++ b/roles/custom/matrix-user-verification-service/tasks/validate_config.yml @@ -19,6 +19,7 @@ - {'old': 'matrix_user_verification_service_docker_image_registry_prefix_upstream', 'new': 'matrix_user_verification_service_container_image_registry_prefix_upstream'} - {'old': 'matrix_user_verification_service_docker_image_registry_prefix_upstream_default', 'new': 'matrix_user_verification_service_container_image_registry_prefix_upstream_default'} - {'old': 'matrix_user_verification_service_docker_src_files_path', 'new': 'matrix_user_verification_service_container_src_files_path'} + - {'old': 'matrix_user_verification_service_container_image_force_pull', 'new': '<removed> (the new community.docker.docker_image_pull module handles this natively)'} - name: Verify homeserver_url is not empty ansible.builtin.assert: diff --git a/roles/custom/matrix-user-verification-service/templates/systemd/matrix-user-verification-service.service.j2 b/roles/custom/matrix-user-verification-service/templates/systemd/matrix-user-verification-service.service.j2 index a75f489e9..4be4b6446 100644 --- a/roles/custom/matrix-user-verification-service/templates/systemd/matrix-user-verification-service.service.j2 +++ b/roles/custom/matrix-user-verification-service/templates/systemd/matrix-user-verification-service.service.j2 @@ -35,9 +35,11 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ {% endfor %} {{ matrix_user_verification_service_container_image }} +{% if matrix_user_verification_service_container_network != 'host' %} {% for network in matrix_user_verification_service_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} {{ matrix_user_verification_service_container_name }} {% endfor %} +{% endif %} ExecStart=/usr/bin/env docker start --attach matrix-user-verification-service ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} {{ matrix_user_verification_service_container_name }} 2>/dev/null' diff --git a/roles/custom/matrix_playbook_migration/defaults/main.yml b/roles/custom/matrix_playbook_migration/defaults/main.yml index 2432996ae..ad6107c41 100644 --- a/roles/custom/matrix_playbook_migration/defaults/main.yml +++ b/roles/custom/matrix_playbook_migration/defaults/main.yml @@ -14,10 +14,22 @@ matrix_playbook_migration_validated_version: '' # The version that the playbook expects the user to have validated against. # This is bumped whenever a breaking change is introduced. # The value configured here needs to exist in `matrix_playbook_migration_breaking_changes` as well. -matrix_playbook_migration_expected_version: "v2026.03.23.0" +matrix_playbook_migration_expected_version: "v2026.05.18.0" # A list of breaking changes, used to inform users what changed between their validated version and the expected version. matrix_playbook_migration_breaking_changes: + - version: "v2026.05.18.0" + summary: "LiveKit Server has been upgraded to v1.12.0 — TURN no longer relays to restricted peer CIDRs (loopback, link-local, multicast, private, unspecified) by default; TURN credentials now carry a TTL (300s)" + changelog_url: "https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md#2026-05-18" + - version: "v2026.04.24.0" + summary: "(BC Break) mautrix-telegram has been rewritten in Go (bridgev2) — the web-based login endpoint, old-style relaybot and several variables have been removed" + changelog_url: "https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md#2026-04-24" + - version: "v2026.04.03.0" + summary: "(BC Break) Synapse Admin is now Ketesa — role renamed and all variables changed from matrix_synapse_admin_* to matrix_ketesa_*" + changelog_url: "https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md#2026-04-03" + - version: "v2026.04.02.0" + summary: "(BC Break) Draupnir-for-all self-service provisioning is now disabled by default" + changelog_url: "https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md#2026-04-02" - version: "v2026.03.23.0" summary: "Initial migration validation system" changelog_url: "https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md#2026-03-22" @@ -58,8 +70,11 @@ matrix_playbook_migration_matrix_aux_migration_validation_enabled: true # Controls if (`matrix_jitsi` -> `jitsi`) validation will run. matrix_playbook_migration_matrix_jitsi_migration_validation_enabled: true -# Controls if (`matrix_bot_postmoogle_` -> `matrix_postmoogle_`) validation will run. -matrix_playbook_migration_matrix_postmoogle_migration_validation_enabled: true +# Controls if (`matrix_bot_postmoogle_` -> `matrix_bridge_postmoogle_`) validation will run. +matrix_playbook_migration_matrix_bridge_postmoogle_migration_validation_enabled: true + +# Controls if validation for the July 2026 bridge variable prefix renames (e.g. `matrix_mautrix_telegram_` -> `matrix_bridge_mautrix_telegram_`) will run. +matrix_playbook_migration_bridge_prefix_rename_validation_enabled: true # Controls if the old apt repository (likely without a `signed-by` option) on Debian-based systems will be removed. # @@ -87,6 +102,8 @@ matrix_playbook_migration_debian_signedby_migration_repository_path: "/etc/apt/s matrix_playbook_migration_docker_trusted_gpg_d_migration_enabled: true matrix_playbook_migration_docker_trusted_gpg_d_migration_repository_path: "/etc/apt/sources.list.d/docker.list" +matrix_playbook_migration_matrix_synapse_admin_ketesa_variable_transition_checks_enabled: true + # Controls if variable transition checks (related to the matrix-nginx-proxy elimination) will run. # If you'd like to keep some `matrix_nginx_proxy` and other variables around and not be warned about them, disable this. # Note: this is not just about `matrix_nginx_proxy_*` variables, but about various other variables that were removed diff --git a/roles/custom/matrix_playbook_migration/tasks/validate_config.yml b/roles/custom/matrix_playbook_migration/tasks/validate_config.yml index c778c5023..8111d2846 100644 --- a/roles/custom/matrix_playbook_migration/tasks/validate_config.yml +++ b/roles/custom/matrix_playbook_migration/tasks/validate_config.yml @@ -188,7 +188,7 @@ After renaming them, please do not forget to fetch the Ansible role. See docs/maintenance-upgrading-services.md for details about how to do so. - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_matrix_prometheus_postgres_exporter_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_matrix_prometheus_postgres_exporter_migration_vars | join(', ') }} when: "matrix_playbook_migration_matrix_prometheus_postgres_exporter_migration_vars | length > 0" - when: matrix_playbook_migration_matrix_backup_borg_migration_validation_enabled | bool @@ -207,7 +207,7 @@ After renaming them, please do not forget to fetch the Ansible role. See docs/maintenance-upgrading-services.md for details about how to do so. - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_backup_borg_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_backup_borg_migration_vars | join(', ') }} when: "matrix_playbook_migration_backup_borg_migration_vars | length > 0" - when: matrix_playbook_migration_matrix_grafana_migration_validation_enabled | bool @@ -226,7 +226,7 @@ After renaming them, please do not forget to fetch the Ansible role. See docs/maintenance-upgrading-services.md for details about how to do so. - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_grafana_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_grafana_migration_vars | join(', ') }} when: "matrix_playbook_migration_grafana_migration_vars | length > 0" - when: matrix_playbook_migration_matrix_ntfy_migration_validation_enabled | bool @@ -245,7 +245,7 @@ After renaming them, please do not forget to fetch the Ansible role. See docs/maintenance-upgrading-services.md for details about how to do so. - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_ntfy_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_ntfy_migration_vars | join(', ') }} when: "matrix_playbook_migration_ntfy_migration_vars | length > 0" - when: matrix_playbook_migration_matrix_redis_migration_validation_enabled | bool @@ -264,16 +264,16 @@ After renaming them, please do not forget to fetch the Ansible role. See docs/maintenance-upgrading-services.md for details about how to do so. - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_redis_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_redis_migration_vars | join(', ') }} when: "matrix_playbook_migration_redis_migration_vars | length > 0" - when: matrix_playbook_migration_redis_valkey_migration_validation_enabled | bool block: - ansible.builtin.set_fact: - matrix_playbook_migration_redis_migration_vars: |- + matrix_playbook_migration_redis_valkey_migration_vars: |- {{ lookup('ansible.builtin.varnames', '^redis_.+', wantlist=True) }} - - name: (Deprecation) Catch and report matrix_redis variables + - name: (Deprecation) Catch and report redis variables ansible.builtin.fail: msg: >- The Redis role that used to be part of this playbook has been superseded by https://github.com/mother-of-all-self-hosting/ansible-role-valkey. @@ -282,8 +282,8 @@ After renaming them, please do not forget to fetch the Ansible role. See docs/maintenance-upgrading-services.md for details about how to do so. - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_redis_migration_vars.keys() | join(', ') }} - when: "matrix_playbook_migration_redis_migration_vars | length > 0" + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_redis_valkey_migration_vars | join(', ') }} + when: "matrix_playbook_migration_redis_valkey_migration_vars | length > 0" - when: matrix_playbook_migration_keydb_valkey_migration_validation_enabled | bool block: @@ -291,7 +291,7 @@ matrix_playbook_migration_keydb_migration_vars: |- {{ lookup('ansible.builtin.varnames', '^keydb_.+', wantlist=True) }} - - name: (Deprecation) Catch and report matrix_redis variables + - name: (Deprecation) Catch and report keydb variables ansible.builtin.fail: msg: >- The KeyDB role that used to be part of this playbook has been superseded by https://github.com/mother-of-all-self-hosting/ansible-role-valkey. @@ -300,7 +300,7 @@ After renaming them, please do not forget to fetch the Ansible role. See docs/maintenance-upgrading-services.md for details about how to do so. - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_keydb_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_keydb_migration_vars | join(', ') }} when: "matrix_playbook_migration_keydb_migration_vars | length > 0" - when: matrix_playbook_migration_matrix_etherpad_migration_validation_enabled | bool @@ -319,7 +319,7 @@ After renaming them, please do not forget to fetch the Ansible role. See docs/maintenance-upgrading-services.md for details about how to do so. - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_etherpad_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_etherpad_migration_vars | join(', ') }} when: "matrix_playbook_migration_etherpad_migration_vars | length > 0" - when: matrix_playbook_migration_matrix_aux_migration_validation_enabled | bool @@ -338,7 +338,7 @@ After renaming them, please do not forget to fetch the Ansible role. See docs/maintenance-upgrading-services.md for details about how to do so. - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_aux_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_aux_migration_vars | join(', ') }} when: "matrix_playbook_migration_aux_migration_vars | length > 0" - when: matrix_playbook_migration_matrix_jitsi_migration_validation_enabled | bool @@ -357,10 +357,10 @@ After renaming them, please do not forget to fetch the Ansible role. See docs/maintenance-upgrading-services.md for details about how to do so. - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_jitsi_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_jitsi_migration_vars | join(', ') }} when: "matrix_playbook_migration_jitsi_migration_vars | length > 0" -- when: matrix_playbook_migration_matrix_postmoogle_migration_validation_enabled | bool +- when: matrix_playbook_migration_matrix_bridge_postmoogle_migration_validation_enabled | bool block: - ansible.builtin.set_fact: matrix_playbook_migration_postmoogle_migration_vars: |- @@ -371,9 +371,9 @@ msg: >- Your configuration contains a variable, which now has a different name. - Please rename all variables (`matrix_bot_postmoogle_` -> `matrix_postmoogle_`) on your configuration file (vars.yml). + Please rename all variables (`matrix_bot_postmoogle_` -> `matrix_bridge_postmoogle_`) on your configuration file (vars.yml). - The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_postmoogle_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be renamed: {{ matrix_playbook_migration_postmoogle_migration_vars | join(', ') }} when: "matrix_playbook_migration_postmoogle_migration_vars | length > 0" - when: matrix_playbook_migration_matrix_nginx_proxy_elimination_variable_transition_checks_enabled | bool @@ -479,7 +479,7 @@ You should remove all its variables (`matrix_nginx_proxy_*`) from your configuration file (vars.yml). - The following variables in your configuration should be renamed: {{ matrix_playbook_migration_nginx_proxy_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be removed: {{ matrix_playbook_migration_nginx_proxy_migration_vars | join(', ') }} when: "matrix_playbook_migration_nginx_proxy_migration_vars | length > 0" - when: matrix_playbook_migration_matrix_ssl_leftover_variable_checks_enabled | bool @@ -495,7 +495,7 @@ You should remove all its variables (`matrix_ssl_*`) from your configuration file (vars.yml). - The following variables in your configuration should be renamed: {{ matrix_playbook_migration_ssl_migration_vars.keys() | join(', ') }} + The following variables in your configuration need to be removed: {{ matrix_playbook_migration_ssl_migration_vars | join(', ') }} when: "matrix_playbook_migration_ssl_migration_vars | length > 0" - block: @@ -503,10 +503,10 @@ matrix_playbook_migration_matrix_synapse_container_labels_public_client_synapse_oidc_vars: |- {{ lookup('ansible.builtin.varnames', '^matrix_synapse_container_labels_public_client_synapse_oidc_.+', wantlist=True) }} - - name: (Deprecation) Catch and report matrix_ssl variables + - name: (Deprecation) Catch and report matrix_synapse_container_labels_public_client_synapse_oidc variables ansible.builtin.fail: msg: >- - We found usage of the following variables which are now removed: {{ matrix_playbook_migration_matrix_synapse_container_labels_public_client_synapse_oidc_vars.keys() | join(', ') }} + We found usage of the following variables which are now removed: {{ matrix_playbook_migration_matrix_synapse_container_labels_public_client_synapse_oidc_vars | join(', ') }} when: "matrix_playbook_migration_matrix_synapse_container_labels_public_client_synapse_oidc_vars | length > 0" - block: @@ -514,10 +514,10 @@ matrix_playbook_migration_matrix_synapse_reverse_proxy_companion_container_labels_public_client_synapse_oidc_vars: |- {{ lookup('ansible.builtin.varnames', '^matrix_synapse_reverse_proxy_companion_container_labels_public_client_synapse_oidc_.+', wantlist=True) }} - - name: (Deprecation) Catch and report matrix_ssl variables + - name: (Deprecation) Catch and report matrix_synapse_reverse_proxy_companion_container_labels_public_client_synapse_oidc variables ansible.builtin.fail: msg: >- - We found usage of the following variables which are now removed: {{ matrix_playbook_migration_matrix_synapse_reverse_proxy_companion_container_labels_public_client_synapse_oidc_vars.keys() | join(', ') }} + We found usage of the following variables which are now removed: {{ matrix_playbook_migration_matrix_synapse_reverse_proxy_companion_container_labels_public_client_synapse_oidc_vars | join(', ') }} when: "matrix_playbook_migration_matrix_synapse_reverse_proxy_companion_container_labels_public_client_synapse_oidc_vars | length > 0" - name: (Deprecation) Catch and report devture_postgres_backup variables @@ -585,6 +585,18 @@ The following variables in your configuration need to be renamed: {{ lookup('ansible.builtin.varnames', '^devture_container_socket_proxy_.+', wantlist=True) | join(', ') }} when: "lookup('ansible.builtin.varnames', '^devture_container_socket_proxy_.+', wantlist=True) | length > 0" +- name: (Deprecation) Catch and report Go-NEB variables + ansible.builtin.fail: + msg: |- + Go-NEB was completely removed from the playbook in May 2026. + + Please remove all `matrix_bot_go_neb_*` variables from your configuration file (vars.yml). + + You may also wish to uninstall the bot manually. See `docs/configuring-playbook-bot-go-neb.md` for more information. + + The following variables in your configuration need to be removed: {{ lookup('ansible.builtin.varnames', '^matrix_bot_go_neb_.+', wantlist=True) | join(', ') }} + when: "lookup('ansible.builtin.varnames', '^matrix_bot_go_neb_.+', wantlist=True) | length > 0" + - name: (Deprecation) Catch and report ma1sd variables ansible.builtin.fail: msg: |- @@ -699,6 +711,42 @@ The following variables in your configuration need to be renamed: {{ lookup('ansible.builtin.varnames', '^matrix_dynamic_dns_.+', wantlist=True) | join(', ') }} when: "lookup('ansible.builtin.varnames', '^matrix_dynamic_dns_.+', wantlist=True) | length > 0" +- name: (Deprecation) Catch and report matrix-registration-bot variables + ansible.builtin.fail: + msg: |- + matrix-registration-bot was completely removed from the playbook in July 2026. + + Please remove all `matrix_bot_matrix_registration_bot_*` variables from your configuration file (vars.yml). + + You may also wish to uninstall the component manually. See `docs/configuring-playbook-bot-matrix-registration-bot.md` for more information. + + The following variables in your configuration need to be removed: {{ lookup('ansible.builtin.varnames', '^matrix_bot_matrix_registration_bot_.+', wantlist=True) | join(', ') }} + when: "lookup('ansible.builtin.varnames', '^matrix_bot_matrix_registration_bot_.+', wantlist=True) | length > 0" + +- name: (Deprecation) Catch and report matrix-appservice-kakaotalk variables + ansible.builtin.fail: + msg: |- + matrix-appservice-kakaotalk was completely removed from the playbook in July 2026, because its upstream repository became unreachable and the component could only be installed by self-building it. + + Please remove all `matrix_appservice_kakaotalk_*` variables from your configuration file (vars.yml). + + You may also wish to uninstall the component manually. See `docs/configuring-playbook-bridge-appservice-kakaotalk.md` for more information. + + The following variables in your configuration need to be removed: {{ lookup('ansible.builtin.varnames', '^matrix_appservice_kakaotalk_.+', wantlist=True) | join(', ') }} + when: "lookup('ansible.builtin.varnames', '^matrix_appservice_kakaotalk_.+', wantlist=True) | length > 0" + +- name: (Deprecation) Catch and report matrix-ldap-registration-proxy variables + ansible.builtin.fail: + msg: |- + matrix-ldap-registration-proxy was completely removed from the playbook in May 2026. + + Please remove all `matrix_ldap_registration_proxy_*` variables from your configuration file (vars.yml). + + You may also wish to uninstall the component manually. See `docs/configuring-playbook-matrix-ldap-registration-proxy.md` for more information. + + The following variables in your configuration need to be removed: {{ lookup('ansible.builtin.varnames', '^matrix_ldap_registration_proxy_.+', wantlist=True) | join(', ') }} + when: "lookup('ansible.builtin.varnames', '^matrix_ldap_registration_proxy_.+', wantlist=True) | length > 0" + - name: (Deprecation) Catch and report mautrix-facebook variables ansible.builtin.fail: msg: |- @@ -820,6 +868,18 @@ The following variables in your configuration need to be removed: {{ lookup('ansible.builtin.varnames', '^matrix_go_skype_bridge_.+', wantlist=True) | join(', ') }} when: "lookup('ansible.builtin.varnames', '^matrix_go_skype_bridge_.+', wantlist=True) | length > 0" +- name: (Deprecation) Catch and report matrix-registration variables + ansible.builtin.fail: + msg: |- + The matrix-registration service was completely removed from the playbook in May 2026. + + Please remove all `matrix_registration_*` variables from your configuration file (vars.yml). + + You may also wish to uninstall the component manually. See `docs/configuring-playbook-matrix-registration.md` for more information. + + The following variables in your configuration need to be removed: {{ lookup('ansible.builtin.varnames', '^matrix_registration_.+', wantlist=True) | join(', ') }} + when: "lookup('ansible.builtin.varnames', '^matrix_registration_.+', wantlist=True) | length > 0" + - name: (Deprecation) Catch and report the Sliding Sync proxy variables ansible.builtin.fail: msg: |- @@ -843,3 +903,44 @@ The following variables in your configuration need to be removed: {{ lookup('ansible.builtin.varnames', '^matrix_synapse_ext_synapse_auto_accept_invite_.+', wantlist=True) | join(', ') }} when: "lookup('ansible.builtin.varnames', '^matrix_synapse_ext_synapse_auto_accept_invite_.+', wantlist=True) | length > 0" + +# Note: we intentionally do NOT use a blanket `^matrix_synapse_admin_.+` pattern here. +# The matrix-synapse role has its own `matrix_synapse_admin_contact` variable (and others like +# `matrix_synapse_container_labels_*_synapse_admin_api_*`) that share the same prefix but relate +# to the Synapse Admin HTTP API, not the Ketesa web UI. A blanket match would produce false positives. +- name: (Deprecation) Catch and report matrix-synapse-admin variables renamed to matrix-ketesa + ansible.builtin.fail: + msg: |- + Synapse Admin has been rebranded to Ketesa. The `matrix-synapse-admin` role has been renamed to `matrix-ketesa`. + + All `matrix_synapse_admin_*` variables must be renamed to `matrix_ketesa_*` in your configuration file (vars.yml). + + Additionally, note that the Docker image changed from `ghcr.io/etkecc/synapse-admin` to `ghcr.io/etkecc/ketesa`. + + See `docs/configuring-playbook-ketesa.md` for more information. + + The following variables in your configuration need to be renamed: {{ lookup('ansible.builtin.varnames', '^matrix_synapse_admin_(enabled|base_path|config|container|hostname|path_prefix|http_|floc_|hsts_|restart_|systemd_)', wantlist=True) | join(', ') }} + when: + - matrix_playbook_migration_matrix_synapse_admin_ketesa_variable_transition_checks_enabled | bool + - "lookup('ansible.builtin.varnames', '^matrix_synapse_admin_(enabled|base_path|config|container|hostname|path_prefix|http_|floc_|hsts_|restart_|systemd_)', wantlist=True) | length > 0" + +# In July 2026, all bridge roles (`roles/custom/matrix-bridge-*`) had their variable prefixes renamed to a uniform scheme, +# where the variable prefix matches the role directory name (e.g. `matrix_mautrix_telegram_` -> `matrix_bridge_mautrix_telegram_`). +# This catches all old-style prefixes at once and points people to the CHANGELOG, which contains the full rename map. +# Prefixes of bridges removed from the playbook before this rename (e.g. `matrix_mautrix_facebook_`) are intentionally not matched here. +# They are caught by their own dedicated tasks above, which ask for removal instead of renaming. +- name: (Deprecation) Catch and report bridge variables that use pre-rename prefixes + ansible.builtin.fail: + msg: |- + Your configuration contains bridge variables which now have different names. + + All bridge variables were renamed so that each variable prefix matches its role directory name (`matrix_bridge_*`). + For example, `matrix_mautrix_telegram_enabled` is now `matrix_bridge_mautrix_telegram_enabled`. + + Please rename all such variables in your configuration file (vars.yml). + See the `Bridge variables have been renamed` entry in the CHANGELOG (https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md) for the full rename map. + + The following variables in your configuration need to be renamed: {{ lookup('ansible.builtin.varnames', '^matrix_(appservice_discord|appservice_irc|beeper_linkedin|heisenbridge|hookshot|mautrix_androidsms|mautrix_bluesky|mautrix_discord|mautrix_gmessages|mautrix_googlechat|mautrix_gvoice|mautrix_imessage|mautrix_meta_instagram|mautrix_meta_messenger|mautrix_signal|mautrix_slack|mautrix_telegram|mautrix_twitter|mautrix_whatsapp|mautrix_wsproxy|meshtastic_relay|mx_puppet_groupme|mx_puppet_steam|postmoogle|rustpush_bridge|sms_bridge|steam_bridge|wechat)_.+', wantlist=True) | join(', ') }} + when: + - matrix_playbook_migration_bridge_prefix_rename_validation_enabled | bool + - "lookup('ansible.builtin.varnames', '^matrix_(appservice_discord|appservice_irc|beeper_linkedin|heisenbridge|hookshot|mautrix_androidsms|mautrix_bluesky|mautrix_discord|mautrix_gmessages|mautrix_googlechat|mautrix_gvoice|mautrix_imessage|mautrix_meta_instagram|mautrix_meta_messenger|mautrix_signal|mautrix_slack|mautrix_telegram|mautrix_twitter|mautrix_whatsapp|mautrix_wsproxy|meshtastic_relay|mx_puppet_groupme|mx_puppet_steam|postmoogle|rustpush_bridge|sms_bridge|steam_bridge|wechat)_.+', wantlist=True) | length > 0" diff --git a/setup.yml b/setup.yml index 60e926916..09667ad94 100644 --- a/setup.yml +++ b/setup.yml @@ -56,8 +56,8 @@ - custom/matrix-alertmanager-receiver - custom/matrix-bridge-appservice-discord - custom/matrix-bridge-appservice-irc - - custom/matrix-bridge-appservice-kakaotalk - custom/matrix-bridge-beeper-linkedin + - custom/matrix-bridge-beeper-line - custom/matrix-bridge-wechat - custom/matrix-bridge-mautrix-twitter - custom/matrix-bridge-mautrix-googlechat @@ -66,11 +66,14 @@ - custom/matrix-bridge-mautrix-telegram - custom/matrix-bridge-mautrix-signal - custom/matrix-bridge-mautrix-gmessages + - custom/matrix-bridge-mautrix-gvoice + - custom/matrix-bridge-mautrix-linkedin - custom/matrix-bridge-mautrix-whatsapp - custom/matrix-bridge-mautrix-wsproxy - custom/matrix-bridge-mautrix-discord - custom/matrix-bridge-mautrix-slack - custom/matrix-bridge-mautrix-bluesky + - custom/matrix-bridge-rustpush - custom/matrix-bridge-mx-puppet-groupme - custom/matrix-bridge-mx-puppet-steam - custom/matrix-bridge-postmoogle @@ -78,13 +81,12 @@ - custom/matrix-bridge-steam - custom/matrix-bridge-heisenbridge - custom/matrix-bridge-hookshot + - custom/matrix-bridge-meshtastic-relay - custom/matrix-bot-matrix-reminder-bot - - custom/matrix-bot-matrix-registration-bot - custom/matrix-bot-maubot - custom/matrix-bot-buscarron - custom/matrix-bot-baibot - custom/matrix-bot-honoroit - - custom/matrix-bot-go-neb - custom/matrix-bot-mjolnir - custom/matrix-bot-draupnir - custom/matrix-cactus-comments @@ -96,7 +98,12 @@ - custom/matrix-dendrite - custom/matrix-conduit - custom/matrix-continuwuity - - custom/matrix-synapse-admin + - custom/matrix-tuwunel + # Meowlnir deliberately runs after the homeserver roles, unlike the other bots. + # Its `ensure-matrix-users-created` tasks may need to restart the homeserver so that it picks up Meowlnir's appservice registration, + # which only helps once the homeserver's configuration has been brought up to date by its own role. + - custom/matrix-bot-meowlnir + - custom/matrix-ketesa - custom/matrix-synapse-usage-exporter - galaxy/prometheus_nginxlog_exporter - galaxy/prometheus_node_exporter @@ -104,7 +111,6 @@ - galaxy/prometheus - galaxy/grafana - custom/matrix-prometheus-services-connect - - custom/matrix-registration - custom/matrix-client-element - custom/matrix-client-commet - galaxy/hydrogen @@ -114,7 +120,6 @@ - custom/matrix-client-fluffychat - galaxy/jitsi - custom/matrix-user-verification-service - - custom/matrix-ldap-registration-proxy - galaxy/etherpad - custom/matrix-sygnal - galaxy/ntfy