mirror of
https://github.com/spantaleev/matrix-docker-ansible-deploy.git
synced 2026-06-30 12:00:31 +03:00
Add Synology DSM support (#5315)
Adds optional support for running the playbook on Synology DSM 7+, detected automatically via /etc/synoinfo.conf so that non-Synology hosts are unaffected. Includes DSM-native user/group management (synouser/synogroup), a requests version constraint for Docker SDK compatibility, and a boot-fix service that re-shares the volume mount and starts matrix services skipped by DSM's boot ordering. The shared-mount volume path is configurable via matrix_base_synology_volume_path, and the make-shared step only runs when the volume is not already shared. Co-authored-by: CKSit <sitchiuki@gmail.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }}"
|
||||
@@ -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
|
||||
}}
|
||||
@@ -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
|
||||
@@ -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"
|
||||
Reference in New Issue
Block a user