Restart Synapse only when its files or image changed

With conditional restart (install-* tags), the homeserver entry for
Synapse fell through to `restart_necessary: true`, and the worker
entries carried no flag at all, which systemd_service_manager also
treats as "restart". Every install-all and install-service synapse
therefore restarted Synapse and all of its workers, even when nothing
had changed. Without workers, systemd also restarted most bridges and
bots, whose units require matrix-synapse.service.

Compute matrix_synapse_restart_necessary from the tasks that install
what Synapse runs: homeserver.yaml, the initial config and signing key,
the log config, labels and systemd service, the container image (pulled,
self-built or customized), each worker's config, labels and systemd
service, and the downloaded or cloned extension modules. Workers follow
the same decision, as they read the same files.

Synapse also mounts the appservice registration files written by other
roles. Add matrix_homeserver_app_service_registration_changed in
group_vars/matrix_servers, which checks the registered result of each
task installing one of the files listed in
matrix_homeserver_container_extra_arguments_auto, so that a changed
registration still restarts Synapse and its workers. The double-puppet
role did not register its result; it does now.

The Synapse image pull and three extension downloads all registered
their result as `result`. The downloads run first, so the pull's result
overwrote theirs before the restart decision could read them; they now
use role-prefixed names.
This commit is contained in:
QEDeD
2026-10-19 09:08:29 +03:00
committed by Slavi Pantaleev
parent c909ff65bd
commit 7b44e13276
11 changed files with 135 additions and 9 deletions
+74 -1
View File
@@ -247,6 +247,78 @@ matrix_homeserver_app_service_config_files_auto: |
(['/matrix-steam-bridge-registration.yaml'] if matrix_bridge_steam_enabled else [])
}}
# Tells whether any appservice registration file mounted into the homeserver (see `matrix_homeserver_container_extra_arguments_auto`)
# changed during this run, so that the homeserver is restarted to pick it up.
# Each entry is the registered result of the task which installs that file.
# Synapse workers read the same configuration and registration files as the main Synapse process,
# so their entries in `devture_systemd_service_manager_services_list_auto` follow the same restart decision.
matrix_homeserver_app_service_registration_changed: |
{{
(
([matrix_bridge_appservice_discord_registration_result | default({})] if matrix_bridge_appservice_discord_enabled else [])
+
([matrix_appservice_draupnir_for_all_registration_config_result | default({})] if matrix_appservice_draupnir_for_all_enabled else [])
+
([matrix_bot_meowlnir_registration_result | default({})] if matrix_bot_meowlnir_enabled else [])
+
([matrix_appservice_double_puppet_registration_result | default({})] if matrix_appservice_double_puppet_enabled else [])
+
([matrix_bridge_appservice_irc_registration_result | default({})] if matrix_bridge_appservice_irc_enabled else [])
+
([matrix_bridge_beeper_linkedin_registration_result | default({})] if matrix_bridge_beeper_linkedin_enabled else [])
+
([matrix_bridge_beeper_line_registration_result | default({})] if matrix_bridge_beeper_line_enabled else [])
+
([matrix_bridge_wechat_registration_result | default({})] if matrix_bridge_wechat_enabled else [])
+
([matrix_bridge_heisenbridge_registration_result | default({})] if matrix_bridge_heisenbridge_enabled else [])
+
([matrix_bridge_hookshot_registration_result | default({})] if matrix_bridge_hookshot_enabled else [])
+
([matrix_bridge_mautrix_bluesky_registration_result | default({})] if matrix_bridge_mautrix_bluesky_enabled else [])
+
([matrix_bridge_rustpush_registration_result | default({})] if matrix_bridge_rustpush_enabled else [])
+
([matrix_bridge_mautrix_discord_registration_result | default({})] if matrix_bridge_mautrix_discord_enabled else [])
+
([matrix_bridge_mautrix_slack_registration_result | default({})] if matrix_bridge_mautrix_slack_enabled else [])
+
([matrix_bridge_mautrix_googlechat_registration_result | default({})] if matrix_bridge_mautrix_googlechat_enabled else [])
+
([matrix_bridge_mautrix_signal_registration_result | default({})] if matrix_bridge_mautrix_signal_enabled else [])
+
([matrix_bridge_mautrix_meta_messenger_registration_result | default({})] if matrix_bridge_mautrix_meta_messenger_enabled else [])
+
([matrix_bridge_mautrix_meta_instagram_registration_result | default({})] if matrix_bridge_mautrix_meta_instagram_enabled else [])
+
([matrix_bridge_mautrix_telegram_registration_result | default({})] if matrix_bridge_mautrix_telegram_enabled else [])
+
([matrix_bridge_mautrix_twitter_registration_result | default({})] if matrix_bridge_mautrix_twitter_enabled else [])
+
([matrix_bridge_mautrix_gmessages_registration_result | default({})] if matrix_bridge_mautrix_gmessages_enabled else [])
+
([matrix_bridge_mautrix_gvoice_registration_result | default({})] if matrix_bridge_mautrix_gvoice_enabled else [])
+
([matrix_bridge_mautrix_linkedin_registration_result | default({})] if matrix_bridge_mautrix_linkedin_enabled else [])
+
([matrix_bridge_mautrix_whatsapp_registration_result | default({})] if matrix_bridge_mautrix_whatsapp_enabled else [])
+
([matrix_bridge_mautrix_wsproxy_registration_androidsms_result | default({})] if matrix_bridge_mautrix_wsproxy_enabled else [])
+
([matrix_bridge_mautrix_wsproxy_registration_imessage_result | default({})] if matrix_bridge_mautrix_wsproxy_enabled else [])
+
([matrix_bridge_mx_puppet_groupme_registration_result | default({})] if matrix_bridge_mx_puppet_groupme_enabled else [])
+
([matrix_bridge_mx_puppet_steam_registration_result | default({})] if matrix_bridge_mx_puppet_steam_enabled else [])
+
([matrix_bridge_sms_registration_result | default({})] if matrix_bridge_sms_enabled else [])
+
([matrix_bridge_steam_registration_result | default({})] if matrix_bridge_steam_enabled else [])
+
([matrix_cactus_comments_config_appservice_result | default({})] if matrix_cactus_comments_enabled else [])
) | selectattr('changed', 'defined') | selectattr('changed') | list | length > 0
}}
matrix_addons_homeserver_container_network: "{{ matrix_playbook_reverse_proxy_container_network if matrix_playbook_internal_matrix_client_api_traefik_entrypoint_enabled else matrix_homeserver_container_network }}"
matrix_addons_homeserver_client_api_url: "{{ ('http://' + matrix_playbook_reverse_proxy_hostname + ':' + matrix_playbook_internal_matrix_client_api_traefik_entrypoint_port | string) if matrix_playbook_internal_matrix_client_api_traefik_entrypoint_enabled else matrix_homeserver_container_url }}"
matrix_addons_homeserver_systemd_services_list: |
@@ -681,6 +753,7 @@ devture_systemd_service_manager_services_list_auto: |
else (matrix_continuwuity_restart_necessary | bool) if matrix_homeserver_implementation == 'continuwuity'
else (matrix_tuwunel_restart_necessary | bool) if matrix_homeserver_implementation == 'tuwunel'
else (matrix_dendrite_restart_necessary | bool) if matrix_homeserver_implementation == 'dendrite'
else ((matrix_synapse_restart_necessary | bool) or (matrix_homeserver_app_service_registration_changed | bool)) if matrix_homeserver_implementation == 'synapse'
else true
),
'groups': ['matrix', 'homeservers', matrix_homeserver_implementation],
@@ -959,7 +1032,7 @@ devture_systemd_service_manager_services_list_auto: |
'groups': ['matrix', 'traefik-certs-dumper'],
}] if traefik_certs_dumper_enabled else [])
+
(matrix_synapse_worker_systemd_services_list if matrix_synapse_enabled else [])
(matrix_synapse_worker_systemd_services_list | map('combine', {'restart_necessary': ((matrix_synapse_restart_necessary | bool) or (matrix_homeserver_app_service_registration_changed | bool))}) | list if matrix_synapse_enabled else [])
}}
########################################################################
@@ -25,3 +25,4 @@
mode: '0644'
owner: "{{ matrix_user_name }}"
group: "{{ matrix_group_name }}"
register: matrix_appservice_double_puppet_registration_result
@@ -135,6 +135,18 @@ matrix_synapse_ext_s3_storage_provider_container_arguments: []
# installation tasks haven't run (e.g., due to --tags skipping them).
matrix_synapse_s3_storage_provider_restart_necessary: false
# matrix_synapse_restart_necessary controls whether Synapse and its workers
# 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
# the Synapse or worker configuration, support files, systemd service files,
# container image or extension modules changed.
# The playbook also restarts Synapse when an appservice registration file it mounts changes.
# 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_restart_necessary: false
matrix_synapse_container_client_api_port: 8008
# Controls the `x_forwarded` setting for the "Insecure HTTP listener (Client API)".
@@ -13,10 +13,10 @@
mode: '0440'
owner: "{{ matrix_synapse_uid }}"
group: "{{ matrix_synapse_gid }}"
register: result
register: matrix_synapse_ext_encryption_disabler_download_result
retries: "{{ devture_playbook_help_geturl_retries_count }}"
delay: "{{ devture_playbook_help_geturl_retries_delay }}"
until: result is not failed
until: matrix_synapse_ext_encryption_disabler_download_result is not failed
- ansible.builtin.set_fact:
matrix_synapse_modules: |
@@ -34,6 +34,7 @@
GIT_CONFIG_COUNT: "1"
GIT_CONFIG_KEY_0: safe.directory
GIT_CONFIG_VALUE_0: "{{ matrix_synapse_ext_path }}/mjolnir"
register: matrix_synapse_ext_spam_checker_mjolnir_antispam_git_result
- ansible.builtin.set_fact:
matrix_synapse_modules: >
@@ -20,10 +20,10 @@
mode: '0440'
owner: "{{ matrix_synapse_uid }}"
group: "{{ matrix_synapse_gid }}"
register: result
register: matrix_synapse_ext_password_provider_rest_auth_download_result
retries: "{{ devture_playbook_help_geturl_retries_count }}"
delay: "{{ devture_playbook_help_geturl_retries_delay }}"
until: result is not failed
until: matrix_synapse_ext_password_provider_rest_auth_download_result is not failed
- ansible.builtin.set_fact:
matrix_synapse_password_providers_enabled: true
@@ -25,10 +25,10 @@
mode: '0440'
owner: "{{ matrix_synapse_uid }}"
group: "{{ matrix_synapse_gid }}"
register: result
register: matrix_synapse_ext_password_provider_shared_secret_auth_download_result
retries: "{{ devture_playbook_help_geturl_retries_count }}"
delay: "{{ devture_playbook_help_geturl_retries_delay }}"
until: result is not failed
until: matrix_synapse_ext_password_provider_shared_secret_auth_download_result is not failed
- ansible.builtin.set_fact:
matrix_synapse_modules: |
@@ -32,6 +32,7 @@
GIT_CONFIG_COUNT: "1"
GIT_CONFIG_KEY_0: safe.directory
GIT_CONFIG_VALUE_0: "{{ matrix_synapse_ext_path }}/synapse-http-antispam"
register: matrix_synapse_ext_synapse_http_antispam_git_result
- ansible.builtin.set_fact:
matrix_synapse_modules: >
@@ -41,6 +41,7 @@
GIT_CONFIG_COUNT: "1"
GIT_CONFIG_KEY_0: safe.directory
GIT_CONFIG_VALUE_0: "{{ matrix_synapse_ext_path }}/synapse-simple-antispam"
register: matrix_synapse_ext_spam_checker_synapse_simple_antispam_git_result
- ansible.builtin.set_fact:
matrix_synapse_modules: >
@@ -79,16 +79,17 @@
DOCKER_BUILDKIT: 1
changed_when: true
when: "matrix_synapse_git_pull_results.changed | bool or matrix_synapse_container_image_check_result.stdout == ''"
register: matrix_synapse_container_image_build_result
- name: Ensure Synapse Docker image is pulled
community.docker.docker_image_pull:
name: "{{ matrix_synapse_container_image }}"
pull: always
when: "not matrix_synapse_container_image_self_build"
register: result
register: matrix_synapse_container_image_pull_result
retries: "{{ devture_playbook_help_container_retries_count }}"
delay: "{{ devture_playbook_help_container_retries_delay }}"
until: result is not failed
until: matrix_synapse_container_image_pull_result is not failed
- when: "matrix_synapse_container_image_customizations_enabled | bool"
block:
@@ -133,6 +134,7 @@
{{ matrix_synapse_container_image }}
generate
creates: "{{ matrix_synapse_config_dir_path }}/{{ matrix_server_fqn_matrix }}.signing.key"
register: matrix_synapse_initial_config_result
- name: Ensure Synapse homeserver config installed
ansible.builtin.copy:
@@ -141,6 +143,7 @@
mode: '0644'
owner: "{{ matrix_synapse_uid }}"
group: "{{ matrix_synapse_gid }}"
register: matrix_synapse_config_result
- name: Ensure Synapse container network is created
when: matrix_synapse_container_network != 'host'
@@ -168,6 +171,7 @@
- src: "{{ role_path }}/templates/synapse/systemd/matrix-synapse.service.j2"
dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-synapse.service"
mode: '0644'
register: matrix_synapse_support_files_result
- name: Generate sample prometheus.yml for external scraping
ansible.builtin.template:
@@ -177,3 +181,22 @@
group: "{{ matrix_synapse_gid }}"
mode: '0644'
when: matrix_synapse_metrics_proxying_enabled | bool
- name: Determine whether Synapse needs a restart
ansible.builtin.set_fact:
matrix_synapse_restart_necessary: >-
{{
matrix_synapse_config_result.changed | default(false)
or matrix_synapse_initial_config_result.changed | default(false)
or matrix_synapse_support_files_result.changed | default(false)
or matrix_synapse_container_image_pull_result.changed | default(false)
or matrix_synapse_container_image_build_result.changed | default(false)
or matrix_synapse_container_image_customized_build_result.changed | default(false)
or matrix_synapse_workers_files_changed | default(false) | bool
or matrix_synapse_ext_encryption_disabler_download_result.changed | default(false)
or matrix_synapse_ext_password_provider_rest_auth_download_result.changed | default(false)
or matrix_synapse_ext_password_provider_shared_secret_auth_download_result.changed | default(false)
or matrix_synapse_ext_spam_checker_mjolnir_antispam_git_result.changed | default(false)
or matrix_synapse_ext_spam_checker_synapse_simple_antispam_git_result.changed | default(false)
or matrix_synapse_ext_synapse_http_antispam_git_result.changed | default(false)
}}
@@ -20,6 +20,7 @@
mode: '0644'
owner: "{{ matrix_synapse_uid }}"
group: "{{ matrix_synapse_gid }}"
register: matrix_synapse_worker_config_result
- name: Ensure labels exists for {{ matrix_synapse_worker_systemd_service_name }}
ansible.builtin.template:
@@ -28,9 +29,22 @@
mode: '0644'
owner: "{{ matrix_synapse_uid }}"
group: "{{ matrix_synapse_gid }}"
register: matrix_synapse_worker_labels_result
- name: Ensure systemd service exists for {{ matrix_synapse_worker_systemd_service_name }}
ansible.builtin.template:
src: "{{ role_path }}/templates/synapse/systemd/matrix-synapse-worker.service.j2"
dest: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_synapse_worker_systemd_service_name }}.service"
mode: '0644'
register: matrix_synapse_worker_systemd_service_result
# Workers share Synapse's restart decision (see `matrix_synapse_restart_necessary`),
# so a change to any one worker's files marks it as needed.
- ansible.builtin.set_fact:
matrix_synapse_workers_files_changed: >-
{{
matrix_synapse_workers_files_changed | default(false) | bool
or matrix_synapse_worker_config_result.changed | default(false)
or matrix_synapse_worker_labels_result.changed | default(false)
or matrix_synapse_worker_systemd_service_result.changed | default(false)
}}