mirror of
https://github.com/spantaleev/matrix-docker-ansible-deploy.git
synced 2026-08-02 02:06:00 +10:00
e5b8de8c2b
6b4b7647e fixed this for synapse-usage-exporter only. A checkout owned by
a different user makes the git task fail from then on, either with a
permission error or with git's dubious-ownership protection, until
someone removes the directory on the host by hand. It gets into that
state when the matrix user's uid changes (a server migration or a restore
onto a differently numbered user), when an earlier clone ran as another
user, or when someone runs git as root inside the checkout.
Every other role cloning a repository onto the server was open to the
same failure, so ensure the checkout's ownership recursively before
updating it at the remaining 54 sites.
The three matrix-synapse ext clones also gain force=yes. They were the
only on-server clones without it, which left a checkout that an
interrupted run had half-written wedged, instead of repaired on the next
run.
matrix-matrixto used to clone as root into a directory that nothing ever
chowned, unlike every other role. It now becomes the matrix user too.
The Element Web and SchildiChat Web theme checkouts live on the Ansible
controller, where correcting ownership is not ours to do, so they merely
mark the checkout as a safe directory for git.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
291 lines
13 KiB
YAML
291 lines
13 KiB
YAML
# SPDX-FileCopyrightText: 2019 - 2022 MDAD project contributors
|
|
# SPDX-FileCopyrightText: 2019 - 2026 Slavi Pantaleev
|
|
# SPDX-FileCopyrightText: 2025 - 2026 Thom Wiggers
|
|
# SPDX-FileCopyrightText: 2019 Dan Arnfield
|
|
# SPDX-FileCopyrightText: 2020 Chris van Dijk
|
|
# SPDX-FileCopyrightText: 2021 Panagiotis Georgiadis
|
|
# 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.include_role:
|
|
name: custom/matrix-base
|
|
tasks_from: ensure_openssl_installed
|
|
|
|
- name: Ensure Appservice IRC 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_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_bridge_appservice_irc_base_path }}/passkey.pem"
|
|
register: matrix_bridge_appservice_irc_stat_passkey
|
|
|
|
- when: "matrix_bridge_appservice_irc_stat_passkey.stat.exists"
|
|
block:
|
|
- name: (Data relocation) Ensure matrix-appservice-irc.service is stopped
|
|
ansible.builtin.service:
|
|
name: matrix-appservice-irc
|
|
state: stopped
|
|
daemon_reload: true
|
|
failed_when: false
|
|
|
|
- name: (Data relocation) Move AppService IRC passkey.pem file to ./data directory
|
|
ansible.builtin.command:
|
|
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_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_bridge_appservice_irc_migration_requires_restart: false
|
|
|
|
- when: "matrix_bridge_appservice_irc_database_engine == 'postgres'"
|
|
block:
|
|
- name: Check if a nedb database already exists
|
|
ansible.builtin.stat:
|
|
path: "{{ matrix_bridge_appservice_irc_data_path }}/users.db"
|
|
register: matrix_bridge_appservice_irc_nedb_database_path_local_stat_result
|
|
|
|
- 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_bridge_appservice_irc_migration_requires_restart: true
|
|
|
|
- name: Ensure Appservice IRC image is pulled
|
|
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_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_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_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_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_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_bridge_appservice_irc_config_result
|
|
|
|
- name: Ensure Matrix Appservice IRC labels file installed
|
|
ansible.builtin.template:
|
|
src: "{{ role_path }}/templates/labels.j2"
|
|
dest: "{{ matrix_bridge_appservice_irc_base_path }}/labels"
|
|
mode: '0644'
|
|
owner: "{{ matrix_user_name }}"
|
|
group: "{{ matrix_group_name }}"
|
|
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_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_bridge_appservice_irc_data_path }}/auth-media.jwk"
|
|
register: matrix_bridge_appservice_irc_stat_auth_media_key
|
|
|
|
- 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_bridge_appservice_irc_container_image }}"
|
|
cleanup: true
|
|
network_mode: none
|
|
entrypoint: "/usr/local/bin/node"
|
|
command: >
|
|
-e "const webcrypto = require('node:crypto');
|
|
async function main() {
|
|
const key = await webcrypto.subtle.generateKey({
|
|
name: 'HMAC',
|
|
hash: 'SHA-512',
|
|
}, true, ['sign', 'verify']);
|
|
console.log(JSON.stringify(await webcrypto.subtle.exportKey('jwk', key), undefined, 4));
|
|
}
|
|
main().then(() => process.exit(0)).catch(err => { throw err });"
|
|
detach: false
|
|
register: matrix_bridge_appservice_irc_jwk_result
|
|
|
|
- name: Write auth media signing key to file
|
|
ansible.builtin.copy:
|
|
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 }}"
|
|
|
|
# In the past, we used to generate the passkey.pem file with root, so permissions may not be okay.
|
|
# Fix it.
|
|
- name: (Migration) Ensure Appservice IRC passkey permissions are okay
|
|
ansible.builtin.file:
|
|
path: "{{ matrix_bridge_appservice_irc_data_path }}/passkey.pem"
|
|
mode: '0644'
|
|
owner: "{{ matrix_user_name }}"
|
|
group: "{{ matrix_group_name }}"
|
|
|
|
# Ideally, we'd like to generate the final registration.yaml file by ourselves.
|
|
#
|
|
# However, the IRC bridge supports multiple servers, which leads to multiple
|
|
# users/aliases/rooms rules in the registration file.
|
|
#
|
|
# Generating a proper file by ourselves is complicated and may lead to deviation
|
|
# from what the bridge is doing.
|
|
#
|
|
# Instead, we do another hacky thing - asking the bridge to generate a template,
|
|
# and then we parse it and fix it up with our own AS/HS token.
|
|
# We need to do this, because:
|
|
# - we'd like to have an up-to-date registration file
|
|
# - we can achieve this by asking the bridge to rebuild it each time
|
|
# - however, the bridge insists on regenerating all tokens each time
|
|
# - .. which is not friendly for integrating with the homeserver
|
|
#
|
|
# So we have a hybrid approach. We ask the bridge to always generate
|
|
# an up-to-date file, and we fix it up with some static values later on,
|
|
# to produce a final registration.yaml file, as we desire.
|
|
- name: Generate Appservice IRC registration-template.yaml
|
|
ansible.builtin.shell: >-
|
|
{{ 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_bridge_appservice_irc_config_path }},dst=/config
|
|
--mount type=bind,src={{ matrix_bridge_appservice_irc_data_path }},dst=/data
|
|
--entrypoint=/bin/bash
|
|
{{ matrix_bridge_appservice_irc_container_image }}
|
|
-c
|
|
'node app.js
|
|
-r
|
|
-f /config/registration-template.yaml
|
|
-u "http://matrix-appservice-irc:9999"
|
|
-c /config/config.yaml
|
|
-l irc_bot'
|
|
changed_when: false
|
|
|
|
- name: Read Appservice IRC registration-template.yaml
|
|
ansible.builtin.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_bridge_appservice_irc_config_path }}/registration-template.yaml"
|
|
state: absent
|
|
changed_when: false
|
|
|
|
- name: Parse registration-template.yaml
|
|
ansible.builtin.set_fact:
|
|
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_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_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_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_bridge_appservice_irc_container_network }}"
|
|
driver: bridge
|
|
driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}"
|
|
|
|
- name: Ensure matrix-appservice-irc.service installed
|
|
ansible.builtin.template:
|
|
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_bridge_appservice_irc_systemd_service_result
|
|
|
|
- name: Determine whether matrix-appservice-irc needs a restart
|
|
ansible.builtin.set_fact:
|
|
matrix_bridge_appservice_irc_restart_necessary: >-
|
|
{{
|
|
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
|
|
ansible.builtin.service:
|
|
name: "matrix-appservice-irc.service"
|
|
state: restarted
|
|
daemon_reload: true
|
|
when: "matrix_bridge_appservice_irc_migration_requires_restart | bool"
|