fix(nextcloud): make occ-driven config tasks idempotent

Every `occ config:app:set` / `ldap:set-config` / `notify_push:setup`
call previously fired on every play, marking changed even when the
stored value already matched. Now we read the current value first and
only invoke the setter when it differs:

* richdocuments (collabora): pre-read wopi_url, public_wopi_url,
  disable_certificate_verification, wopi_allowlist into a fact map;
  guard each `config:app:set` and tag `richdocuments:activate-config`
  with `changed_when: false` since it's a discovery refresh.

* drawio: same pattern for DrawioUrl, DrawioTheme, DrawioOffline,
  comparing as strings (occ stores booleans as "1"/"0").

* user_ldap: pre-read `ldap:show-config s01 --output=json`, parse JSON
  defensively (occ logs interleave on stderr), and skip per-key
  `ldap:set-config` calls when the stored value already equals the
  desired one.

* notify_push: skip `notify_push:setup` when the stored base_endpoint
  already matches the computed URL.

* plugins: `app:install`/`app:enable` were treating "already installed/
  enabled" output as a change. Add the negative match to `changed_when`
  so re-runs of a fully-provisioned site report ok rather than changed.
This commit is contained in:
Simon Bärlocher 2026-05-26 14:04:17 +02:00
parent 1157448d59
commit aea6dec081
No known key found for this signature in database
GPG key ID: 63DE20495932047A
5 changed files with 89 additions and 7 deletions

View file

@ -1,28 +1,55 @@
#SPDX-License-Identifier: MIT-0
---
# tasks file for configuring Collabora in Nextcloud
- name: Read current richdocuments config values
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ config:app:get richdocuments {{ item }}
loop:
- wopi_url
- public_wopi_url
- disable_certificate_verification
- wopi_allowlist
register: _richdocuments_current
changed_when: false
failed_when: false
- name: Build map of current richdocuments config
ansible.builtin.set_fact:
_richdocuments_cfg: "{{ _richdocuments_cfg | default({}) | combine({item.item: (item.stdout | default('')).strip()}) }}"
loop: "{{ _richdocuments_current.results }}"
loop_control:
label: "{{ item.item }}"
- name: Configure Collabora WOPI URL (server-to-server)
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ config:app:set richdocuments wopi_url --value=https://{{ nextcloud_collabora_domain }}
when: _richdocuments_cfg.wopi_url != ('https://' ~ nextcloud_collabora_domain)
- name: Configure Collabora public WOPI URL (browser-facing)
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ config:app:set richdocuments public_wopi_url --value=https://{{ nextcloud_collabora_public_domain }}
when: nextcloud_collabora_public_domain is defined and nextcloud_collabora_public_domain != nextcloud_collabora_domain
when:
- nextcloud_collabora_public_domain is defined
- nextcloud_collabora_public_domain != nextcloud_collabora_domain
- _richdocuments_cfg.public_wopi_url != ('https://' ~ nextcloud_collabora_public_domain)
- name: Configure certificate verification for Collabora
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ config:app:set richdocuments disable_certificate_verification --value={{ nextcloud_collabora_disable_cert_verification | ternary('yes', 'no') }}
when: _richdocuments_cfg.disable_certificate_verification != (nextcloud_collabora_disable_cert_verification | ternary('yes', 'no'))
- name: Set Collabora WOPI allowlist
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ config:app:set richdocuments wopi_allowlist --value=''
when: _richdocuments_cfg.wopi_allowlist | default('') != ''
- name: Activate richdocuments configuration (fetch discovery from Collabora)
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ richdocuments:activate-config
command: php /var/www/html/occ richdocuments:activate-config
changed_when: false

View file

@ -2,18 +2,41 @@
---
# tasks file for configuring draw.io in Nextcloud
- name: Read current drawio config values
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ config:app:get drawio {{ item }}
loop:
- DrawioUrl
- DrawioTheme
- DrawioOffline
register: _drawio_current
changed_when: false
failed_when: false
- name: Build map of current drawio config
ansible.builtin.set_fact:
_drawio_cfg: "{{ _drawio_cfg | default({}) | combine({item.item: (item.stdout | default('')).strip()}) }}"
loop: "{{ _drawio_current.results }}"
loop_control:
label: "{{ item.item }}"
- name: Configure draw.io URL
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ config:app:set drawio DrawioUrl --value={{ nextcloud_drawio_url }}
when: nextcloud_drawio_url | length > 0
when:
- nextcloud_drawio_url | length > 0
- _drawio_cfg.DrawioUrl != nextcloud_drawio_url
- name: Configure draw.io theme
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ config:app:set drawio DrawioTheme --value={{ nextcloud_drawio_theme }}
when: _drawio_cfg.DrawioTheme != (nextcloud_drawio_theme | string)
- name: Configure draw.io offline mode
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ config:app:set drawio DrawioOffline --value={{ nextcloud_drawio_offline }}
command: php /var/www/html/occ config:app:set drawio DrawioOffline --value={{ nextcloud_drawio_offline }}
when: _drawio_cfg.DrawioOffline != (nextcloud_drawio_offline | string)

View file

@ -15,6 +15,24 @@
command: php /var/www/html/occ ldap:create-empty-config
when: "'s01' not in ldap_show_config.stdout"
- name: Read current LDAP config for s01
community.docker.docker_container_exec:
container: "{{ nextcloud_service_name }}-nextcloud-1"
command: php /var/www/html/occ ldap:show-config s01 --output=json
register: _ldap_show_s01
changed_when: false
failed_when: false
- name: Parse current LDAP config
ansible.builtin.set_fact:
_ldap_current: >-
{{
(_ldap_show_s01.stdout | from_json) if (
(_ldap_show_s01.stdout | default('') | trim) is match('^[\\[{]')
) else {}
}}
when: _ldap_show_s01.rc | default(1) == 0
- name: Configure LDAP settings
community.docker.docker_container_exec:
container: "{{ nextcloud_service_name }}-nextcloud-1"
@ -29,6 +47,7 @@
loop_control:
label: "{{ item.key }}"
no_log: true
when: ((_ldap_current | default({})).get(item.key) | default(none) | string) != (item.value | string)
- name: Test LDAP configuration
community.docker.docker_container_exec:

View file

@ -2,7 +2,16 @@
---
# tasks file for configuring notify_push in Nextcloud
- name: Read current notify_push base endpoint
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ config:app:get notify_push base_endpoint
register: _notify_push_current
changed_when: false
failed_when: false
- name: Configure notify_push base endpoint
community.docker.docker_container_exec:
container: "{{ nextcloud_docker_compose_dir | basename }}-nextcloud-1"
command: php /var/www/html/occ notify_push:setup https://{{ nextcloud_notify_push_domain | default(nextcloud_domains[0]) }}/push
command: php /var/www/html/occ notify_push:setup https://{{ nextcloud_notify_push_domain | default(nextcloud_domains[0]) }}/push
when: (_notify_push_current.stdout | default('') | trim) != ('https://' ~ (nextcloud_notify_push_domain | default(nextcloud_domains[0])) ~ '/push')

View file

@ -8,7 +8,9 @@
chdir: "{{ nextcloud_docker_compose_dir }}"
loop: "{{ nextcloud_apps_to_install }}"
register: app_install_result
changed_when: "'installed' in app_install_result.stdout"
changed_when:
- "'already installed' not in app_install_result.stdout"
- "'installed' in app_install_result.stdout"
failed_when:
- app_install_result.rc != 0
- "'already installed' not in app_install_result.stdout"
@ -19,7 +21,9 @@
chdir: "{{ nextcloud_docker_compose_dir }}"
loop: "{{ nextcloud_apps_to_install }}"
register: app_enable_result
changed_when: "'enabled' in app_enable_result.stdout"
changed_when:
- "'already enabled' not in app_enable_result.stdout"
- "'enabled' in app_enable_result.stdout"
failed_when:
- app_enable_result.rc != 0
- "'already enabled' not in app_enable_result.stdout"