# """ # Run the command and check the response. # # :parameter command: The command to be executed. # :parameter add_command: Whether to include the command in the database values. # :parameter add_response: Whether to include the response in the database values. # :parameter measurement: The measurement index for the command. # :parameter measure_retries: The number of retries for measurement in case of failure. # :parameter check_port: Whether to check the port before sending the command. # :parameter response_equals: The expected response string to compare against. # :parameter response_length: The expected length or format of the response. # :parameter send_skipped: Whether to mark the test as skipped without execution. # :parameter no_response: Whether to expect no response from the command. # :parameter expect_patch_id_decimal: The expected patch ID in decimal format for validation. # :parameter response_equals_match: The expected response string to match against. # :return: RunResultType # """ - name: Run Nextcloud maintenance on VM via Proxmox hosts: proxmox gather_facts: false become: true become_user: root become_method: sudo vars: vm_ip: "{{ lookup('env', 'VM_IP') }}" vm_user: "{{ lookup('env', 'VM_USER') }}" vm_pass: "{{ lookup('env', 'VM_PASS') }}" # Flip to true if Docker needs sudo on the VM use_sudo: false # ---------- Collabora defaults (can be overridden by detection) ---------- collabora_project: "nextcloud-collabora" collabora_candidate_files: # English comments: ordered list of likely compose file locations - "/data/compose/nextcloud/collabora-only.yml" - "/data/compose/nextcloud/collabora.yml" - "/data/compose/collabora/docker-compose.yml" - "/data/compose/collabora/compose.yml" # ---------- Nextcloud commands ---------- vm_commands: - "docker exec -u www-data nextcloud php -f /var/www/html/cron.php" - "docker exec -u www-data nextcloud php occ app:update --all" - "docker exec -u www-data nextcloud php occ maintenance:repair --include-expensive" - "docker exec -u www-data nextcloud php occ status" # English comments: run health script non-interactively with a timeout and xtrace for debugging - "set -o pipefail; timeout 180s bash -x /data/compose/nextcloud/stack-health.sh if {{ 'sudo ' if use_sudo else '' }}docker compose version >/dev/null 2>&1; then echo "docker compose"; elif {{ 'sudo ' if use_sudo else '' }}docker-compose version >/dev/null 2>&1; then echo "docker-compose"; else echo "none"; fi register: compose_cli changed_when: false failed_when: false - name: Collabora | Set compose command fact # English comments ansible.builtin.set_fact: docker_compose_cmd: "{{ (compose_cli.stdout | trim) if (compose_cli.stdout | trim) else 'none' }}" - name: Collabora | Warn if compose CLI not found ansible.builtin.debug: msg: "Collabora update skipped: no docker compose CLI found on VM." when: docker_compose_cmd == 'none' - name: Collabora | Find first existing compose file on VM # English comments ansible.builtin.command: argv: - sshpass - -p - "{{ vm_pass }}" - ssh - -o - StrictHostKeyChecking=no - -o - ConnectTimeout=15 - "{{ vm_user }}@{{ vm_ip }}" - bash - -lc - | set -euo pipefail for f in {{ collabora_candidate_files | map('quote') | join(' ') }}; do if {{ 'sudo ' if use_sudo else '' }}test -f "$f"; then echo "$f" exit 0 fi done exit 3 register: collab_file_probe changed_when: false failed_when: false when: docker_compose_cmd != 'none' - name: Collabora | Set resolved compose file fact ansible.builtin.set_fact: collabora_compose_file_resolved: "{{ (collab_file_probe.stdout | trim) if (collab_file_probe.rc == 0) else '' }}" when: docker_compose_cmd != 'none' - name: Collabora | Warn if compose file not found ansible.builtin.debug: msg: "Collabora update skipped: no compose file found in candidates: {{ collabora_candidate_files }}" when: - docker_compose_cmd != 'none' - collabora_compose_file_resolved | default('') == '' - name: Collabora | Verify 'collabora' service exists in compose # English comments ansible.builtin.command: argv: - sshpass - -p - "{{ vm_pass }}" - ssh - -o - StrictHostKeyChecking=no - -o - ConnectTimeout=15 - "{{ vm_user }}@{{ vm_ip }}" - bash - -lc - > {{ ('sudo ' if use_sudo else '') }}{{ docker_compose_cmd }} -p {{ collabora_project }} -f {{ collabora_compose_file_resolved }} config --services | grep -qx collabora register: collab_service_check changed_when: false failed_when: false when: - docker_compose_cmd != 'none' - collabora_compose_file_resolved | default('') != '' - name: Collabora | Warn if service 'collabora' missing ansible.builtin.debug: msg: "Collabora update skipped: service 'collabora' not found in compose file {{ collabora_compose_file_resolved }}." when: - docker_compose_cmd != 'none' - collabora_compose_file_resolved | default('') != '' - collab_service_check.rc != 0 - name: Collabora | Run update commands (pull + up -d) # English comments ansible.builtin.command: argv: - sshpass - -p - "{{ vm_pass }}" - ssh - -o - StrictHostKeyChecking=no - -o - ConnectTimeout=15 - -o - ServerAliveInterval=15 - -o - ServerAliveCountMax=2 - "{{ vm_user }}@{{ vm_ip }}" - bash - -lc - > set -o pipefail; {{ ('sudo ' if use_sudo else '') }}timeout 600s docker pull collabora/code:latest; {{ ('sudo ' if use_sudo else '') }}timeout 600s {{ docker_compose_cmd }} -p {{ collabora_project }} -f {{ collabora_compose_file_resolved }} pull collabora; {{ ('sudo ' if use_sudo else '') }}timeout 600s {{ docker_compose_cmd }} -p {{ collabora_project }} -f {{ collabora_compose_file_resolved }} up -d --no-deps --force-recreate collabora register: collab_update changed_when: false failed_when: false when: - docker_compose_cmd != 'none' - collabora_compose_file_resolved | default('') != '' - collab_service_check.rc == 0 - name: Collabora | Show update output ansible.builtin.debug: msg: | Collabora update output: RC: {{ collab_update.rc | default('n/a') }} STDOUT: {{ (collab_update.stdout | default('')).strip() }} STDERR: {{ (collab_update.stderr | default('')).strip() }} when: - docker_compose_cmd != 'none' - collabora_compose_file_resolved | default('') != '' - collab_service_check.rc == 0 - name: Collabora | Fail if update command failed ansible.builtin.assert: that: "collab_update.rc == 0" fail_msg: "Collabora update failed (rc={{ collab_update.rc }}) {{ ' -- likely timeout' if collab_update.rc == 124 else '' }}" success_msg: "Collabora updated successfully." when: - docker_compose_cmd != 'none' - collabora_compose_file_resolved | default('') != '' - collab_service_check.rc == 0