diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers index c1dd03a06..af230afd8 100755 --- a/group_vars/matrix_servers +++ b/group_vars/matrix_servers @@ -1827,17 +1827,11 @@ matrix_bot_matrix_registration_bot_container_additional_networks_auto: |- # We don't enable bots by default. matrix_bot_maubot_enabled: false -matrix_bot_maubot_container_image_self_build: "{{ matrix_architecture not in ['amd64'] }}" - -matrix_bot_maubot_systemd_required_services_list: | +matrix_bot_maubot_systemd_required_services_list_auto: | {{ - ['docker.service'] + matrix_addons_homeserver_systemd_services_list + - ['matrix-' + matrix_homeserver_implementation + '.service'] - + - ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) - + - (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + ([devture_postgres_identifier ~ '.service'] if (devture_postgres_enabled and matrix_bot_maubot_database_hostname == devture_postgres_connection_hostname) else []) }} matrix_bot_maubot_registration_shared_secret: |- @@ -1848,7 +1842,29 @@ matrix_bot_maubot_registration_shared_secret: |- }[matrix_homeserver_implementation] }} -matrix_bot_maubot_management_interface_http_bind_port: "{{ (matrix_playbook_service_host_bind_interface_prefix ~ '' ~ matrix_bot_maubot_management_interface_port | string) if matrix_playbook_service_host_bind_interface_prefix else '' }}" +matrix_bot_maubot_container_image_self_build: "{{ matrix_architecture not in ['amd64'] }}" + +matrix_bot_maubot_container_management_interface_http_bind_port: "{{ (matrix_playbook_service_host_bind_interface_prefix ~ '' ~ matrix_bot_maubot_server_port | string) if matrix_playbook_service_host_bind_interface_prefix else '' }}" + +matrix_bot_maubot_container_network: "{{ matrix_addons_container_network }}" + +matrix_bot_maubot_container_additional_networks_auto: |- + {{ + ( + ([] if matrix_addons_homeserver_container_network == '' else [matrix_addons_homeserver_container_network]) + + + ([devture_postgres_container_network] if (devture_postgres_enabled and matrix_bot_maubot_database_hostname == devture_postgres_connection_hostname and matrix_bot_maubot_container_network != devture_postgres_container_network) else []) + + + ([matrix_playbook_reverse_proxyable_services_additional_network] if matrix_playbook_reverse_proxyable_services_additional_network and matrix_bot_maubot_container_labels_traefik_enabled else []) + ) | unique + }} + +matrix_bot_maubot_container_labels_traefik_enabled: "{{ matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] }}" +matrix_bot_maubot_container_labels_traefik_docker_network: "{{ matrix_playbook_reverse_proxyable_services_additional_network }}" +matrix_bot_maubot_container_labels_traefik_entrypoints: "{{ devture_traefik_entrypoint_primary }}" +matrix_bot_maubot_container_labels_traefik_tls_certResolver: "{{ devture_traefik_certResolver_primary }}" + +matrix_bot_maubot_container_labels_management_hostname: "{{ matrix_server_fqn_matrix }}" # Postgres is the default, except if not using internal Postgres server matrix_bot_maubot_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" diff --git a/roles/custom/matrix-bot-maubot/defaults/main.yml b/roles/custom/matrix-bot-maubot/defaults/main.yml index 3c93b8ab5..1e47c2247 100644 --- a/roles/custom/matrix-bot-maubot/defaults/main.yml +++ b/roles/custom/matrix-bot-maubot/defaults/main.yml @@ -4,12 +4,16 @@ # Project source code URL: https://mau.dev/maubot/maubot matrix_bot_maubot_enabled: true + +matrix_bot_maubot_scheme: https +matrix_bot_maubot_hostname: '' +matrix_bot_maubot_path_prefix: /_matrix/maubot + matrix_bot_maubot_container_image_self_build: false matrix_bot_maubot_docker_repo: "https://mau.dev/maubot/maubot.git" matrix_bot_maubot_docker_src_files_path: "{{ matrix_bot_maubot_base_path }}/docker-src" matrix_bot_maubot_docker_repo_version: "{{ 'master' if matrix_bot_maubot_version == 'latest' else matrix_bot_maubot_version }}" - # renovate: datasource=docker depName=dock.mau.dev/maubot/maubot matrix_bot_maubot_version: v0.4.2 matrix_bot_maubot_docker_image: "{{ matrix_bot_maubot_docker_image_name_prefix }}maubot/maubot:{{ matrix_bot_maubot_version }}" @@ -20,7 +24,12 @@ matrix_bot_maubot_base_path: "{{ matrix_base_data_path }}/maubot" matrix_bot_maubot_data_path: "{{ matrix_bot_maubot_base_path }}/data" matrix_bot_maubot_config_path: "{{ matrix_bot_maubot_base_path }}/config" -matrix_bot_maubot_bot_server_public_url: "https://{{ matrix_server_fqn_matrix }}" +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_proxy_management_interface: true matrix_bot_maubot_database_engine: sqlite @@ -43,30 +52,65 @@ matrix_bot_maubot_database_uri: "{{ }[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_management_interface_http_bind_port` -matrix_bot_maubot_management_interface_port: 29316 - -# Controls whether the maubot container exposes its HTTP management interface port (tcp/29316 in the container). -# -# Takes an ":" or "" value (e.g. "127.0.0.1:29316"), or empty string to not expose. -# If you'll be setting this at all, it should be defined in terms of `matrix_bot_maubot_management_interface_port`. -# Example: -# matrix_bot_maubot_management_interface_http_bind_port: "127.0.0.1:{{ matrix_bot_maubot_management_interface_port }}" -matrix_bot_maubot_management_interface_http_bind_port: '' - +# To actually expose the management interface outside of the container, use `matrix_bot_maubot_container_management_interface_http_bind_port` +matrix_bot_maubot_server_port: 29316 matrix_bot_maubot_unshared_secret: 'generate' # Specifies the default log level for all bot loggers. matrix_bot_maubot_logging_level: WARNING +# Controls whether the maubot container exposes its HTTP management interface port (tcp/29316 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:29316"), or empty string to not expose. +# If you'll be setting this at all, it should be defined in terms of `matrix_bot_maubot_server_port`. +# Example: +# matrix_bot_maubot_container_management_interface_http_bind_port: "127.0.0.1:{{ matrix_bot_maubot_server_port }}" +matrix_bot_maubot_container_management_interface_http_bind_port: '' + +matrix_bot_maubot_container_network: "" + +matrix_bot_maubot_container_additional_networks: "{{ matrix_bot_maubot_container_additional_networks_auto + matrix_bot_maubot_container_additional_networks_custom }}" +matrix_bot_maubot_container_additional_networks_auto: [] +matrix_bot_maubot_container_additional_networks_custom: [] + +# matrix_bot_maubot_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_maubot_container_labels_additional_labels`. +matrix_bot_maubot_container_labels_traefik_enabled: true +matrix_bot_maubot_container_labels_traefik_docker_network: "{{ matrix_bot_maubot_container_network }}" +matrix_bot_maubot_container_labels_traefik_entrypoints: web-secure +matrix_bot_maubot_container_labels_traefik_tls_certResolver: default # noqa var-naming + +# Controls whether labels will be added that expose maubot's management endpoints +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_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' }}" +matrix_bot_maubot_container_labels_management_traefik_tls_certResolver: "{{ matrix_bot_maubot_container_labels_traefik_tls_certResolver }}" # noqa var-naming + +# matrix_bot_maubot_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_maubot_container_labels_additional_labels: | +# my.label=1 +# another.label="here" +matrix_bot_maubot_container_labels_additional_labels: '' + # A list of extra arguments to pass to the container matrix_bot_maubot_container_extra_arguments: [] # List of systemd services that matrix-bot-maubot.service depends on -matrix_bot_maubot_systemd_required_services_list: ['docker.service'] +matrix_bot_maubot_systemd_required_services_list: "{{ matrix_bot_maubot_systemd_required_services_list_default + matrix_bot_maubot_systemd_required_services_list_auto + matrix_bot_maubot_systemd_required_services_list_custom }}" +matrix_bot_maubot_systemd_required_services_list_default: ['docker.service'] +matrix_bot_maubot_systemd_required_services_list_auto: [] +matrix_bot_maubot_systemd_required_services_list_custom: [] # List of systemd services that matrix-bot-maubot.service wants matrix_bot_maubot_systemd_wanted_services_list: [] diff --git a/roles/custom/matrix-bot-maubot/tasks/inject_into_nginx_proxy.yml b/roles/custom/matrix-bot-maubot/tasks/inject_into_nginx_proxy.yml deleted file mode 100644 index f7aec6273..000000000 --- a/roles/custom/matrix-bot-maubot/tasks/inject_into_nginx_proxy.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- - -- name: Configure nginx for maubot - block: - - name: Generate Maubot proxying configuration for matrix-nginx-proxy - ansible.builtin.set_fact: - matrix_bot_maubot_matrix_nginx_proxy_configuration: | - location ~ ^/(_matrix/maubot/.*) { - {% if matrix_nginx_proxy_enabled | default(False) %} - {# Use the embedded DNS resolver in Docker containers to discover the service #} - resolver 127.0.0.11 valid=5s; - set $backend "matrix-bot-maubot:{{ matrix_bot_maubot_management_interface_port }}"; - proxy_pass http://$backend$request_uri; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - {% else %} - {# Generic configuration for use outside of our container setup #} - proxy_pass http://127.0.0.1:{{ matrix_bot_maubot_management_interface_port }}$request_uri; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - {% endif %} - } - when: matrix_bot_maubot_proxy_management_interface | bool - - - name: Register Maubot's proxying configuration with matrix-nginx-proxy - ansible.builtin.set_fact: - matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks: | - {{ - matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks | default([]) - + - [matrix_bot_maubot_matrix_nginx_proxy_configuration] - }} - when: matrix_bot_maubot_proxy_management_interface | bool - - - name: Warn about reverse-proxying if matrix-nginx-proxy not used - ansible.builtin.debug: - msg: >- - NOTE: You've enabled Maubot but are not using the matrix-nginx-proxy - reverse proxy. - Please make sure that you're proxying the `/_matrix/maubot` - URL endpoint to the matrix-maubot container. - when: "matrix_bot_maubot_enabled | bool and matrix_bot_maubot_proxy_management_interface | bool and matrix_nginx_proxy_enabled is not defined" diff --git a/roles/custom/matrix-bot-maubot/tasks/main.yml b/roles/custom/matrix-bot-maubot/tasks/main.yml index 3241795b5..d954a452a 100644 --- a/roles/custom/matrix-bot-maubot/tasks/main.yml +++ b/roles/custom/matrix-bot-maubot/tasks/main.yml @@ -1,14 +1,5 @@ --- -- tags: - - setup-all - - setup-nginx-proxy - - install-all - - install-nginx-proxy - block: - - when: matrix_bot_maubot_enabled | bool - ansible.builtin.include_tasks: "{{ role_path }}/tasks/inject_into_nginx_proxy.yml" - - tags: - setup-all - setup-bot-maubot diff --git a/roles/custom/matrix-bot-maubot/tasks/setup_install.yml b/roles/custom/matrix-bot-maubot/tasks/setup_install.yml index 60b87861e..0d3bb4cae 100644 --- a/roles/custom/matrix-bot-maubot/tasks/setup_install.yml +++ b/roles/custom/matrix-bot-maubot/tasks/setup_install.yml @@ -60,6 +60,21 @@ pull: true when: "matrix_bot_maubot_container_image_self_build|bool" +- name: Ensure maubot support files installed + ansible.builtin.template: + src: "{{ role_path }}/templates/{{ item }}.j2" + dest: "{{ matrix_bot_maubot_base_path }}/{{ item }}" + mode: 0640 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - labels + +- name: Ensure maubot container network is created + community.general.docker_network: + name: "{{ matrix_bot_maubot_container_network }}" + driver: bridge + - name: Ensure matrix-bot-maubot.service installed ansible.builtin.template: src: "{{ role_path }}/templates/systemd/matrix-bot-maubot.service.j2" diff --git a/roles/custom/matrix-bot-maubot/tasks/validate_config.yml b/roles/custom/matrix-bot-maubot/tasks/validate_config.yml index d8bac550a..dfe6a1033 100644 --- a/roles/custom/matrix-bot-maubot/tasks/validate_config.yml +++ b/roles/custom/matrix-bot-maubot/tasks/validate_config.yml @@ -1,11 +1,24 @@ --- +- name: (Deprecation) Catch and report renamed maubot variables + ansible.builtin.fail: + msg: >- + Your configuration contains a variable, which now has a different name. + Please change your configuration to rename the variable (`{{ item.old }}` -> `{{ item.new }}`). + when: "item.old in vars" + with_items: + - {'old': 'matrix_bot_maubot_management_interface_port', 'new': 'matrix_bot_maubot_server_port'} + - {'old': 'matrix_bot_maubot_management_interface_http_bind_port', 'new': 'matrix_bot_maubot_container_management_interface_http_bind_port'} + - name: Fail if required maubot settings not defined ansible.builtin.fail: msg: >- You need to define a required configuration setting (`{{ item.name }}`). when: "item.when | bool and vars[item.name] == ''" with_items: + - {'name': 'matrix_bot_maubot_hostname', when: true} + - {'name': 'matrix_bot_maubot_path_prefix', when: true} - {'name': 'matrix_bot_maubot_unshared_secret', when: true} - {'name': 'matrix_bot_maubot_admins', when: true} - {'name': 'matrix_bot_maubot_database_hostname', when: "{{ matrix_bot_maubot_database_engine == 'postgres' }}"} + - {'name': 'matrix_bot_maubot_container_network', when: true} diff --git a/roles/custom/matrix-bot-maubot/templates/config/config.yaml.j2 b/roles/custom/matrix-bot-maubot/templates/config/config.yaml.j2 index 7750ec9a3..f321db78a 100644 --- a/roles/custom/matrix-bot-maubot/templates/config/config.yaml.j2 +++ b/roles/custom/matrix-bot-maubot/templates/config/config.yaml.j2 @@ -35,23 +35,23 @@ plugin_databases: server: # The IP and port to listen to. hostname: 0.0.0.0 - port: {{ matrix_bot_maubot_management_interface_port|to_json }} + 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 }} + public_url: {{ matrix_bot_maubot_bot_server_public_url | to_json }} # The base management API path. - base_path: /_matrix/maubot/v1 + base_path: {{ matrix_bot_maubot_bot_server_base_path | to_json }} # The base path for the UI. - ui_base_path: /_matrix/maubot + 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. - plugin_base_path: /_matrix/maubot/plugin/ + plugin_base_path: {{ matrix_bot_maubot_bot_server_plugin_base_path | to_json }} # 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/app/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 }} + unshared_secret: {{ matrix_bot_maubot_unshared_secret | to_json }} # Known homeservers. This is required for the `mbc auth` command and also allows # more convenient access from the management UI. This is not required to create diff --git a/roles/custom/matrix-bot-maubot/templates/labels.j2 b/roles/custom/matrix-bot-maubot/templates/labels.j2 new file mode 100644 index 000000000..b375a12e3 --- /dev/null +++ b/roles/custom/matrix-bot-maubot/templates/labels.j2 @@ -0,0 +1,25 @@ +{% if matrix_bot_maubot_container_labels_traefik_enabled %} +traefik.enable=true + +{% if matrix_bot_maubot_container_labels_traefik_docker_network %} +traefik.docker.network={{ matrix_bot_maubot_container_labels_traefik_docker_network }} +{% endif %} + +{# Management #} +{% if matrix_bot_maubot_container_labels_management_enabled %} +traefik.http.routers.matrix-bot-maubot-management.rule={{ matrix_bot_maubot_container_labels_management_traefik_rule }} +{% if matrix_bot_maubot_container_labels_management_traefik_priority | int > 0 %} +traefik.http.routers.matrix-bot-maubot-management.priority={{ matrix_bot_maubot_container_labels_management_traefik_priority }} +{% endif %} +traefik.http.routers.matrix-bot-maubot-management.service=matrix-mautrix-facebook-appservice +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 }} +{% if matrix_bot_maubot_container_labels_management_traefik_tls %} +traefik.http.routers.matrix-bot-maubot-management.tls.certResolver={{ matrix_bot_maubot_container_labels_management_traefik_tls_certResolver }} +{% endif %} +traefik.http.services.matrix-mautrix-facebook-appservice.loadbalancer.server.port={{ matrix_bot_maubot_server_port }} +{% endif %} + +{% endif %} + +{{ matrix_bot_maubot_container_labels_additional_labels }} 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 20bf16bf0..9e0d57ade 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 @@ -16,23 +16,32 @@ 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 --time={{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-bot-maubot 2>/dev/null || true' ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-bot-maubot 2>/dev/null || true' -ExecStart={{ devture_systemd_docker_base_host_command_docker }} run --rm --name matrix-bot-maubot \ +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ + --rm \ + --name=matrix-bot-maubot \ --log-driver=none \ --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ --read-only \ --cap-drop=ALL \ --mount type=bind,src={{ matrix_bot_maubot_config_path }},dst=/config,ro \ --mount type=bind,src={{ matrix_bot_maubot_data_path }},dst=/data \ + --label-file={{ matrix_bot_maubot_base_path }}/labels \ {% for arg in matrix_bot_maubot_container_extra_arguments %} {{ arg }} \ {% endfor %} --network={{ matrix_docker_network }} \ - {% if matrix_bot_maubot_management_interface_http_bind_port %} - -p {{ matrix_bot_maubot_management_interface_http_bind_port }}:{{ matrix_bot_maubot_management_interface_port }} \ + {% if matrix_bot_maubot_container_management_interface_http_bind_port %} + -p {{ matrix_bot_maubot_container_management_interface_http_bind_port }}:{{ matrix_bot_maubot_server_port }} \ {% endif %} {{ matrix_bot_maubot_docker_image }} \ python3 -m maubot -c /config/config.yaml --no-update +{% for network in matrix_bot_maubot_container_additional_networks %} +ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-bot-maubot +{% endfor %} + +ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-bot-maubot + ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop --time={{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-bot-maubot 2>/dev/null || true' ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-bot-maubot 2>/dev/null || true' Restart=always