fix(web-app-nextcloud): hand occ config values over on stdin, not on the exec line

The plugin configuration loop and the OpenProject and SuiteCRM
provisioning ran one `container exec ... occ config:app:set --value <v>`
per value, so the Talk, OnlyOffice, whiteboard and BBB secrets and the
OAuth client secrets sat on the host-side exec command line, where host
ps and the daemon's exec_create event show them (#1213).

Each task now renders its occ calls as a shell script on the task's
stdin and runs it through one `container exec -i ... sh -s`. The values
no longer reach a host argv or Ansible's environment prefix; the plugin
loop also needs one exec per addon instead of one per value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5.5 committed 2026-10-25 13:00:57 +01:00
1 parent a758ce71f9
commit 7f72e53a58
3 files changed
+25 -29

No files matched your search

@@ -5,17 +5,17 @@
file: "{{ [role_path, 'meta/addons', plugin_key ~ '.yml'] | path_join }}"
name: addon_spec
- name: "🔧 Set plugin configuration (batched shell, no async)"
ansible.builtin.shell: |
set -euo pipefail
{% for item in (addon_spec.config.plugin_configuration | default([])) %}
{{ NEXTCLOUD_DOCKER_EXEC_OCC }} \
config:app:set {{ item.appid }} {{ item.configkey }}{{ (' --no-interaction --type=' ~ item.type) if item.type is defined else '' }} \
--value '{{ ( (item.configvalue | to_json) if (item.configvalue is mapping or (item.configvalue is sequence and item.configvalue is not string)) else (item.configvalue | string) )
| regex_replace("'", "'" ~ '"' ~ "'" ~ '"' ~ "'") }}'
{% endfor %}
args:
executable: /bin/bash
- name: "🔧 Set plugin configuration (one exec, occ calls on stdin)"
ansible.builtin.shell:
cmd: "{{ NEXTCLOUD_DOCKER_EXEC_INTERACTIVE }} sh -s"
stdin: |
set -eu
{% for item in (addon_spec.config.plugin_configuration | default([])) %}
{{ NEXTCLOUD_INTERNAL_OCC_COMMAND | quote }} \
config:app:set {{ item.appid }} {{ item.configkey }}{{ (' --no-interaction --type=' ~ item.type) if item.type is defined else '' }} \
--value '{{ ( (item.configvalue | to_json) if (item.configvalue is mapping or (item.configvalue is sequence and item.configvalue is not string)) else (item.configvalue | string) )
| regex_replace("'", "'" ~ '"' ~ "'" ~ '"' ~ "'") }}'
{% endfor %}
when: (addon_spec.config.plugin_configuration | default([])) | length > 0
register: config_set_shell
changed_when: config_set_shell.stdout is search(' set to ')
@@ -57,15 +57,13 @@
openproject_client_secret, nc_oauth_client_id) and the OpenProject storage to re-provision.
- name: ⬆️ Push the OpenProject OAuth application credentials into Nextcloud
shell: >
{{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:set integration_openproject {{ item.key }}
--value={{ item.value | quote }}
loop:
- { key: "authorization_method", value: "oauth2" }
- { key: "openproject_client_id", value: "{{ nextcloud_op_oauth.openproject_client_id }}" }
- { key: "openproject_client_secret", value: "{{ nextcloud_op_client_secret }}" }
loop_control:
label: "{{ item.key }}"
ansible.builtin.shell:
cmd: "{{ NEXTCLOUD_DOCKER_EXEC_INTERACTIVE }} sh -s"
stdin: |
set -eu
{{ NEXTCLOUD_INTERNAL_OCC_COMMAND | quote }} config:app:set integration_openproject authorization_method --value=oauth2
{{ NEXTCLOUD_INTERNAL_OCC_COMMAND | quote }} config:app:set integration_openproject openproject_client_id --value={{ nextcloud_op_oauth.openproject_client_id | quote }}
{{ NEXTCLOUD_INTERNAL_OCC_COMMAND | quote }} config:app:set integration_openproject openproject_client_secret --value={{ nextcloud_op_client_secret | quote }}
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
- name: 📝 Register a Nextcloud OAuth2 client for OpenProject
@@ -35,13 +35,11 @@
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
- name: 🔗 Link the SuiteCRM OAuth password client into integration_suitecrm
shell: >
{{ NEXTCLOUD_DOCKER_EXEC_OCC }} config:app:set integration_suitecrm {{ item.key }}
--value={{ item.value | quote }}
loop:
- { key: "oauth_instance_url", value: "{{ nextcloud_crm_base_url }}" }
- { key: "client_id", value: "{{ nextcloud_crm_client_id }}" }
- { key: "client_secret", value: "{{ nextcloud_crm_client_secret }}" }
loop_control:
label: "{{ item.key }}"
ansible.builtin.shell:
cmd: "{{ NEXTCLOUD_DOCKER_EXEC_INTERACTIVE }} sh -s"
stdin: |
set -eu
{{ NEXTCLOUD_INTERNAL_OCC_COMMAND | quote }} config:app:set integration_suitecrm oauth_instance_url --value={{ nextcloud_crm_base_url | quote }}
{{ NEXTCLOUD_INTERNAL_OCC_COMMAND | quote }} config:app:set integration_suitecrm client_id --value={{ nextcloud_crm_client_id | quote }}
{{ NEXTCLOUD_INTERNAL_OCC_COMMAND | quote }} config:app:set integration_suitecrm client_secret --value={{ nextcloud_crm_client_secret | quote }}
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"