From cea437c84440c6841eb32923c9e3a46d72214d48 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Mon, 23 Dec 2024 08:36:18 +0200 Subject: [PATCH] Expose mautrix-discord's avatar proxy Possibly fixes https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3900 This patch hasn't been tested. --- group_vars/matrix_servers | 11 +++- .../defaults/main.yml | 38 +++++++++++- .../tasks/setup_install.yml | 10 ++++ .../tasks/validate_config.yml | 2 + .../templates/labels.j2 | 58 +++++++++++++++++++ .../systemd/matrix-mautrix-discord.service.j2 | 1 + 6 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 roles/custom/matrix-bridge-mautrix-discord/templates/labels.j2 diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index 4331a7a8387..9cd2edbd0c0 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -1103,9 +1103,16 @@ matrix_mautrix_discord_container_additional_networks_auto: |- ([] if matrix_addons_homeserver_container_network == '' else [matrix_addons_homeserver_container_network]) + ([postgres_container_network] if postgres_enabled and matrix_mautrix_facebook_database_hostname == postgres_connection_hostname else []) + + + ([matrix_playbook_reverse_proxyable_services_additional_network] if (matrix_playbook_reverse_proxyable_services_additional_network and matrix_mautrix_discord_container_labels_traefik_enabled) else []) ) | unique }} +matrix_mautrix_discord_container_labels_traefik_enabled: "{{ matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] }}" +matrix_mautrix_discord_container_labels_traefik_docker_network: "{{ matrix_playbook_reverse_proxyable_services_additional_network }}" +matrix_mautrix_discord_container_labels_traefik_entrypoints: "{{ traefik_entrypoint_primary }}" +matrix_mautrix_discord_container_labels_traefik_tls_certResolver: "{{ traefik_certResolver_primary }}" + matrix_mautrix_discord_systemd_required_services_list_auto: | {{ matrix_addons_homeserver_systemd_services_list @@ -1118,9 +1125,11 @@ matrix_mautrix_discord_appservice_token: "{{ '%s' | format(matrix_homeserver_gen matrix_mautrix_discord_homeserver_address: "{{ matrix_addons_homeserver_client_api_url }}" matrix_mautrix_discord_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'maudisc.hs.tok', rounds=655555) | to_uuid }}" -matrix_mautrix_discord_bridge_public_address: "{{ 'https' if matrix_playbook_ssl_enabled else 'http' }}://{{ matrix_server_fqn_matrix }}" matrix_mautrix_discord_bridge_avatar_proxy_key: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'maudisc.avatar', rounds=655555) | to_uuid }}" +matrix_mautrix_discord_hostname: "{{ matrix_server_fqn_matrix }}" +matrix_mautrix_discord_scheme: "{{ 'https' if matrix_playbook_ssl_enabled else 'http' }}" + matrix_mautrix_discord_bridge_login_shared_secret_map_auto: |- {{ ({ diff --git a/roles/custom/matrix-bridge-mautrix-discord/defaults/main.yml b/roles/custom/matrix-bridge-mautrix-discord/defaults/main.yml index 913f2d363da..f362a702ac8 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/defaults/main.yml +++ b/roles/custom/matrix-bridge-mautrix-discord/defaults/main.yml @@ -4,6 +4,10 @@ matrix_mautrix_discord_enabled: true +matrix_mautrix_discord_hostname: "" +matrix_mautrix_discord_path_prefix: / +matrix_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 }}" @@ -30,7 +34,7 @@ matrix_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_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 '' }}" # 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: '' @@ -60,6 +64,38 @@ matrix_mautrix_discord_container_additional_networks: "{{ matrix_mautrix_discord matrix_mautrix_discord_container_additional_networks_auto: [] matrix_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. +# 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 }}" +# 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 + +# 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 `../templates/labels.j2` for details. +# +# Example: +# matrix_mautrix_discord_container_labels_additional_labels: | +# my.label=1 +# another.label="here" +matrix_mautrix_discord_container_labels_additional_labels: '' + # A list of extra arguments to pass to the container matrix_mautrix_discord_container_extra_arguments: [] 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 4775b5fee0f..a830929737f 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/tasks/setup_install.yml +++ b/roles/custom/matrix-bridge-mautrix-discord/tasks/setup_install.yml @@ -93,6 +93,16 @@ owner: "{{ matrix_user_username }}" group: "{{ matrix_user_groupname }}" +- name: Ensure mautrix-discord support files installed + ansible.builtin.template: + src: "{{ role_path }}/templates/{{ item }}.j2" + dest: "{{ matrix_mautrix_discord_base_path }}/{{ item }}" + mode: 0640 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - labels + - name: Ensure mautrix-discord container network is created community.general.docker_network: enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}" 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 5251564e5a8..25b4773c954 100644 --- a/roles/custom/matrix-bridge-mautrix-discord/tasks/validate_config.yml +++ b/roles/custom/matrix-bridge-mautrix-discord/tasks/validate_config.yml @@ -12,6 +12,8 @@ - {'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: (Deprecation) Catch and report renamed settings ansible.builtin.fail: diff --git a/roles/custom/matrix-bridge-mautrix-discord/templates/labels.j2 b/roles/custom/matrix-bridge-mautrix-discord/templates/labels.j2 new file mode 100644 index 00000000000..adc265db22b --- /dev/null +++ b/roles/custom/matrix-bridge-mautrix-discord/templates/labels.j2 @@ -0,0 +1,58 @@ +{% if matrix_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 }} +{% endif %} + +traefik.http.services.matrix-mautrix-discord.loadbalancer.server.port=8080 + +{% if matrix_mautrix_discord_container_labels_avatar_proxy_enabled %} +############################################################ +# # +# Avatar proxy # +# # +############################################################ + +{% 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 }})$ +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 }} +{% 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 }} + +{% 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 }} +{% endif %} + +{% if middlewares | length > 0 %} +traefik.http.routers.matrix-mautrix-discord-avatar-proxy.middlewares={{ middlewares | join(',') }} +{% 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.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 }} +{% endif %} + +############################################################ +# # +# /Avatar proxy # +# # +############################################################ +{% endif %} + + +{% endif %} + +{{ matrix_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 0a5167baf72..cd853e1a975 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 @@ -23,6 +23,7 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --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 \ --workdir=/data \