mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
fix(nextcloud): run occ on the node that hosts the task
NEXTCLOUD_DOCKER_EXEC resolved the container id through a subshell evaluated on the manager. When the manager holds no running replica, resolve_container_id.sh falls back to a cluster-wide lookup with no node filter and returns the id of a task on another node, which the local daemon does not know: 'No such container', sixty times, then the wait in 02_config.yml fails the deploy. 08_manager_ops.yml now resolves the hosting node and its node-local container id once via resolve_host_cid.yml and delegates every include there with apply:. Redefining NEXTCLOUD_DOCKER_EXEC in terms of NEXTCLOUD_LOCAL_CID lets all seventeen consumers inherit the fix without touching a task line. It re-resolves after the handler flush and after the upgrade, the two points where a rolling restart can move the task. Compose degenerates to delegate-to-self with the previous container name. Four call sites built their exec inline because they need -u root or -e flags, and their subshell would have run on the worker where resolve-container-id exits 64 for want of a manager. Without converting them, delegation would have made things worse rather than better. This is the outermost of four stacked defects and not the reason the job was red: the manager was empty because the object store had no free volume slots, which left a half-installed instance holding the init lock. Those layers are fixed separately. This one is a genuine cross-node bug that the rest of the repo already solved with the same pattern. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
1f91114ce5
commit
a963280c1c
6 files changed
+38
-8
No files matched your search
@@ -20,11 +20,10 @@
|
||||
(occ_status.stdout | default('')) is search('installed: true')
|
||||
changed_when: false
|
||||
|
||||
# nocheck: container-exec-resolver NEXTCLOUD_CONTAINER_ADDRESS is a swarm-mode subshell that only a shell can expand; command/argv would pass it literally
|
||||
- name: "📄 Install the infinito additional-config loader into config/"
|
||||
ansible.builtin.shell:
|
||||
cmd: >-
|
||||
container exec -i -u root {{ NEXTCLOUD_CONTAINER_ADDRESS }}
|
||||
cmd: >- # nocheck: container-exec-resolver NEXTCLOUD_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
||||
container exec -i -u root {{ NEXTCLOUD_LOCAL_CID | quote }}
|
||||
sh -c 'cat > /var/www/html/config/zzz-infinito.config.php
|
||||
&& chmod 0444 /var/www/html/config/zzz-infinito.config.php'
|
||||
stdin: "{{ lookup('template', 'include.php.j2') }}"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
- name: ✅ Ensure Nextcloud administrator is in the 'admin' group
|
||||
shell: >
|
||||
container exec -u {{ NEXTCLOUD_DOCKER_USER }} {{ NEXTCLOUD_CONTAINER_ADDRESS }}
|
||||
{{ NEXTCLOUD_DOCKER_EXEC }}
|
||||
php occ group:adduser admin {{ NEXTCLOUD_ADMINISTRATOR_USERNAME }}
|
||||
register: add_admin_to_group
|
||||
changed_when: "not ASYNC_ENABLED and 'Added user' in add_admin_to_group.stdout"
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
---
|
||||
- name: 🔍 Resolve the Nextcloud hosting node and container id
|
||||
include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}"
|
||||
vars:
|
||||
resolve_service_key: "{{ NEXTCLOUD_SERVICE }}"
|
||||
resolve_output_prefix: NEXTCLOUD
|
||||
resolve_compose_cid: "{{ NEXTCLOUD_CONTAINER_ADDRESS }}"
|
||||
|
||||
- name: 🔧 Setup config.php
|
||||
include_tasks: 02_config.yml
|
||||
apply:
|
||||
delegate_to: "{{ NEXTCLOUD_HOST_NODE }}"
|
||||
|
||||
- name: 🚿 Flush all handlers immediately so that occ can be used
|
||||
meta: flush_handlers
|
||||
|
||||
- name: 🔍 Re-resolve the hosting node after the handler flush
|
||||
include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}"
|
||||
vars:
|
||||
resolve_service_key: "{{ NEXTCLOUD_SERVICE }}"
|
||||
resolve_output_prefix: NEXTCLOUD
|
||||
resolve_compose_cid: "{{ NEXTCLOUD_CONTAINER_ADDRESS }}"
|
||||
|
||||
- name: ⏳ Wait until Redis is ready (PONG)
|
||||
shell: "container exec {{ NEXTCLOUD_REDIS_CONTAINER_ADDRESS }} redis-cli ping"
|
||||
register: redis_ping
|
||||
@@ -16,6 +32,15 @@
|
||||
|
||||
- name: 🔄 Update\Upgrade Nextcloud
|
||||
include_tasks: 03_upgrade.yml
|
||||
apply:
|
||||
delegate_to: "{{ NEXTCLOUD_HOST_NODE }}"
|
||||
|
||||
- name: 🔍 Re-resolve the hosting node after the upgrade restarts
|
||||
include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}"
|
||||
vars:
|
||||
resolve_service_key: "{{ NEXTCLOUD_SERVICE }}"
|
||||
resolve_output_prefix: NEXTCLOUD
|
||||
resolve_compose_cid: "{{ NEXTCLOUD_CONTAINER_ADDRESS }}"
|
||||
|
||||
- name: 📂 Load system configuration steps
|
||||
include_tasks: "{{ nextcloud_step }}"
|
||||
@@ -24,6 +49,8 @@
|
||||
- 05_system_config.yml
|
||||
loop_control:
|
||||
loop_var: nextcloud_step
|
||||
apply:
|
||||
delegate_to: "{{ NEXTCLOUD_HOST_NODE }}"
|
||||
|
||||
- name: 🔧 Setup Nextcloud Plugins
|
||||
include_tasks: 06_plugin.yml
|
||||
@@ -34,6 +61,10 @@
|
||||
plugin_key: "{{ plugin_item.key }}"
|
||||
plugin_value: "{{ plugin_item.value }}"
|
||||
when: NEXTCLOUD_PLUGINS_ENABLED | bool
|
||||
apply:
|
||||
delegate_to: "{{ NEXTCLOUD_HOST_NODE }}"
|
||||
|
||||
- name: 🔧 Reconcile administrator identities after plugin setup
|
||||
include_tasks: 07_admin_identities.yml
|
||||
apply:
|
||||
delegate_to: "{{ NEXTCLOUD_HOST_NODE }}"
|
||||
@@ -96,7 +96,7 @@
|
||||
register: nextcloud_mm_oauth_url_set
|
||||
changed_when: "' set to ' in nextcloud_mm_oauth_url_set.stdout"
|
||||
|
||||
# nocheck: container-exec-resolver NEXTCLOUD_CONTAINER_ADDRESS is a swarm-mode subshell that only a shell can expand; command/argv would pass it literally
|
||||
# nocheck: container-exec-resolver NEXTCLOUD_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
||||
- name: 🔐 Store integration_mattermost OAuth credentials Nextcloud-encrypted (lazy)
|
||||
ansible.builtin.shell:
|
||||
cmd: >-
|
||||
@@ -104,7 +104,7 @@
|
||||
-e NC_APP_ID=integration_mattermost
|
||||
-e NC_ENC_MODE=sensitive
|
||||
-e "NC_ENC_B64={{ {'client_id': nextcloud_mm_client_id, 'client_secret': nextcloud_mm_client_secret} | to_json | b64encode }}"
|
||||
{{ NEXTCLOUD_CONTAINER_ADDRESS }} php
|
||||
{{ NEXTCLOUD_LOCAL_CID | quote }} php
|
||||
stdin: "{{ lookup('file', 'set_encrypted_appconfig.php') }}"
|
||||
register: nextcloud_mm_enc_set
|
||||
changed_when: "'OK' in nextcloud_mm_enc_set.stdout"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
-e 'NC_APP_ID=integration_zammad'
|
||||
-e 'NC_ENC_MODE=sensitive'
|
||||
-e 'NC_ENC_B64={{ {'client_id': nextcloud_zammad_client_id, 'client_secret': nextcloud_zammad_client_secret} | to_json | b64encode }}'
|
||||
{{ NEXTCLOUD_CONTAINER_ADDRESS }}
|
||||
{{ NEXTCLOUD_LOCAL_CID | quote }}
|
||||
php
|
||||
stdin: "{{ lookup('file', 'set_encrypted_appconfig.php') }}"
|
||||
register: nextcloud_zammad_enc_set
|
||||
|
||||
@@ -150,7 +150,7 @@ NEXTCLOUD_DOCKER_USER_ID: 82
|
||||
NEXTCLOUD_DOCKER_USER: "www-data"
|
||||
|
||||
NEXTCLOUD_INTERNAL_OCC_COMMAND: "{{ [ NEXTCLOUD_DOCKER_WORK_DIRECTORY, 'occ'] | path_join }}"
|
||||
NEXTCLOUD_DOCKER_EXEC: "container exec -u {{ NEXTCLOUD_DOCKER_USER }} {{ NEXTCLOUD_CONTAINER_ADDRESS }}"
|
||||
NEXTCLOUD_DOCKER_EXEC: "container exec -u {{ NEXTCLOUD_DOCKER_USER }} {{ NEXTCLOUD_LOCAL_CID | quote }}" # nocheck: container-exec-resolver NEXTCLOUD_LOCAL_CID resolved at delegate_to runtime; container_address would return a manager-only subshell
|
||||
NEXTCLOUD_DOCKER_EXEC_OCC: "{{ NEXTCLOUD_DOCKER_EXEC }} {{ NEXTCLOUD_INTERNAL_OCC_COMMAND }}"
|
||||
|
||||
NEXTCLOUD_REDIS_CONTAINER_ADDRESS: "{{ lookup('container_address', application_id, 'redis') }}"
|
||||
Reference in new issue
Block a user