# nextcloud/check_stack_nextcloud.yml - name: Run Nextcloud maintenance on VM via Proxmox hosts: proxmox_nextcloud gather_facts: false become: true become_user: root become_method: sudo vars: vm_password: "{{ lookup('ansible.builtin.env', 'vm_pass') }}" vm_use_sudo: "{{ use_sudo | default(false) | bool }}" nextcloud_container: "nextcloud" nextcloud_db_container: "nextcloud-db" redis_container: "redis" nextcloud_local_status_url: "http://127.0.0.1:8080/status.php" collabora_url: "https://collabora.martinfencl.eu/" collabora_discovery_url: "https://collabora.martinfencl.eu/hosting/discovery" vm_commands: - name: Run Nextcloud cron command: >- docker exec -u www-data {{ nextcloud_container }} php -f /var/www/html/cron.php - name: Update Nextcloud applications command: >- docker exec -u www-data {{ nextcloud_container }} php occ app:update --all - name: Run Nextcloud maintenance repair command: >- docker exec -u www-data {{ nextcloud_container }} php occ maintenance:repair --include-expensive - name: Read Nextcloud status command: >- docker exec -u www-data {{ nextcloud_container }} php occ status - name: Check required containers command: >- for container in {{ nextcloud_container | quote }} {{ nextcloud_db_container | quote }} {{ redis_container | quote }}; do state="$(docker inspect --format '{% raw %}{{.State.Running}}{% endraw %}' "${container}" 2>/dev/null)"; if [ "${state}" != "true" ]; then echo "Container ${container} is not running" >&2; exit 1; fi; done - name: Check MariaDB readiness command: >- docker exec {{ nextcloud_db_container }} sh -c 'mariadb-admin ping -h 127.0.0.1 --silent 2>/dev/null || mysqladmin ping -h 127.0.0.1 --silent 2>/dev/null' - name: Check Redis readiness command: >- set -o pipefail; docker exec {{ redis_container }} redis-cli -h 127.0.0.1 ping | grep -qx PONG - name: Check Nextcloud local status endpoint command: >- set -o pipefail; curl --fail --silent --show-error --max-time 15 {{ nextcloud_local_status_url | quote }} | grep -q '"installed":true' pre_tasks: - name: Validate VM connection variables ansible.builtin.assert: that: - vm_ip is defined - vm_ip | string | trim | length > 0 - vm_user is defined - vm_user | string | trim | length > 0 - vm_password | length > 0 fail_msg: >- Missing vm_ip, vm_user or vm_pass. Check the attached Semaphore Variable Group. quiet: true no_log: true tasks: - name: Ensure sshpass is installed ansible.builtin.apt: name: sshpass state: present update_cache: true - name: Run Nextcloud checks on VM ansible.builtin.command: argv: - sshpass - -e - ssh - -o - StrictHostKeyChecking=no - -o - UserKnownHostsFile=/dev/null - -o - LogLevel=ERROR - -o - ConnectTimeout=15 - -o - ServerAliveInterval=10 - -o - ServerAliveCountMax=3 - "{{ vm_user }}@{{ vm_ip }}" - >- {{ ('sudo -n bash -lc ' ~ (item.command | quote)) if vm_use_sudo else ('bash -lc ' ~ (item.command | quote)) }} environment: SSHPASS: "{{ vm_password }}" loop: "{{ vm_commands }}" loop_control: label: "{{ item.name }}" register: vm_cmds changed_when: false failed_when: false no_log: true - name: Show outputs for each VM command ansible.builtin.debug: msg: | CHECK: {{ item.item.name }} CMD: {{ item.item.command }} RC: {{ item.rc }} STDOUT: {{ item.stdout | default('') | trim }} STDERR: {{ item.stderr | default('') | trim }} loop: "{{ vm_cmds.results }}" loop_control: label: "{{ item.item.name }}" - name: Fail if any Nextcloud VM command failed ansible.builtin.assert: that: - item.rc == 0 fail_msg: | Nextcloud check failed: {{ item.item.name }} Command: {{ item.item.command }} RC: {{ item.rc }} STDERR: {{ item.stderr | default('') | trim }} quiet: true loop: "{{ vm_cmds.results }}" loop_control: label: "{{ item.item.name }}" - name: Check external Collabora root endpoint ansible.builtin.uri: url: "{{ collabora_url }}" method: GET return_content: true validate_certs: true status_code: 200 timeout: 20 register: collabora_root delegate_to: localhost run_once: true changed_when: false failed_when: >- collabora_root.status | default(0) != 200 or 'OK' not in (collabora_root.content | default('')) - name: Check external Collabora discovery endpoint ansible.builtin.uri: url: "{{ collabora_discovery_url }}" method: GET return_content: true validate_certs: true status_code: 200 timeout: 20 register: collabora_discovery delegate_to: localhost run_once: true changed_when: false failed_when: >- collabora_discovery.status | default(0) != 200 or '