- name: Fast-Track Nextcloud Upgrade (Skip Discovery) hosts: all become: yes vars: nextcloud_dir: /var/www/nextcloud php_cli_path: /usr/bin/php web_service_name: httpd nc_web_user: apache occ_env: TMPDIR: /tmp core_apps: - activity - twofactor_nextcloud_notification - files - settings - dav - updater - workflowengine - theming - user_ldap - dashboard - federation - updatestatus - accessibility - serverinfo tasks: - name: Reminder - ensure backups exist debug: msg: "⚠️ CRITICAL: Ensure you have valid DB + data backups BEFORE proceeding!" - name: Pause playbook for 3 seconds pause: seconds: 3 prompt: "Press Ctrl+C then A to abort if no backups exist." # ---------------------------------------------------------------------- # VERSION CHECK # ---------------------------------------------------------------------- - name: 1.1 - Get current NC status command: "{{ php_cli_path }} occ status" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" register: occ_status changed_when: false failed_when: "'installed: true' not in occ_status.stdout" - name: 1.2 - Parse current version set_fact: current_version: "{{ occ_status.stdout | regex_search('versionstring: (.*)', '\\1') | first | default('unknown') }}" - name: 1.3 - Show current version debug: msg: "Current Nextcloud version: {{ current_version }}" # ---------------------------------------------------------------------- # PRE-UPGRADE PREPARATION # ---------------------------------------------------------------------- - name: 2.1 - Get list of installed apps command: "{{ php_cli_path }} occ app:list" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" register: app_list changed_when: false - name: 2.2 - Disable all non-core 3rd party apps command: "{{ php_cli_path }} occ app:disable {{ item }}" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" environment: "{{ occ_env }}" loop: "{{ app_list.stdout_lines | select('match', '^[ ]*-[ ](.*):[ ]enabled$') | map('regex_replace', '^[ ]*-[ ](.*):[ ]enabled$', '\\1') | list }}" register: app_disable_result when: item not in core_apps ignore_errors: yes - name: 2.3 - Save disabled apps list set_fact: disabled_apps: "{{ app_disable_result.results | selectattr('changed', 'defined') | selectattr('changed') | map(attribute='item') | list }}" when: app_disable_result is defined and app_disable_result.results is defined # ---------------------------------------------------------------------- # UPGRADE BLOCK WITH RESCUE + ALWAYS # ---------------------------------------------------------------------- - name: 3.0 - Perform Nextcloud Upgrade (Transactional) block: - name: 3.1 - Enable maintenance mode command: "{{ php_cli_path }} occ maintenance:mode --on" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" environment: "{{ occ_env }}" - name: 3.2 - Run Nextcloud CLI updater (retry) command: "{{ php_cli_path }} updater/updater.phar --no-interaction" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" environment: "{{ occ_env }}" register: updater_result until: - updater_result.rc == 0 - "'Update successful' in updater_result.stdout or 'Nextcloud is already latest version' in updater_result.stdout" retries: 3 delay: 10 failed_when: - updater_result.rc != 0 - "'Nextcloud is already latest version' not in updater_result.stdout" - name: 3.3 - Run occ upgrade (DB update) command: "{{ php_cli_path }} occ upgrade" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" environment: "{{ occ_env }}" - name: 3.4 - Cleanup commands command: "{{ item }}" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" environment: "{{ occ_env }}" loop: - "{{ php_cli_path }} occ db:add-missing-indices" - "{{ php_cli_path }} occ db:convert-filecache-bigint --no-interaction" ignore_errors: yes - name: 3.5 - Disable maintenance mode (success) command: "{{ php_cli_path }} occ maintenance:mode --off" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" environment: "{{ occ_env }}" - name: 3.6 - Re-enable disabled apps command: "{{ php_cli_path }} occ app:enable {{ item }}" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" environment: "{{ occ_env }}" loop: "{{ disabled_apps | default([]) }}" when: disabled_apps is defined and disabled_apps | length > 0 ignore_errors: yes - name: 3.7 - Restart web service service: name: "{{ web_service_name }}" state: restarted - name: 3.8 - Verify version after upgrade command: "{{ php_cli_path }} occ status" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" environment: "{{ occ_env }}" register: occ_status_after changed_when: false - name: 3.9 - Final version info debug: var: occ_status_after.stdout - name: 3.10 - Upgrade complete debug: msg: "Nextcloud successfully upgraded!" rescue: - name: ❌ UPGRADE FAILED - Details debug: msg: | !!!!!!!!!!! NEXTCLOUD UPGRADE FAILED !!!!!!!!!!!! Host: {{ inventory_hostname }} Maintenance mode will be disabled. Check logs: - {{ nextcloud_dir }}/data/updater.log - {{ nextcloud_dir }}/data/nextcloud.log always: - name: ALWAYS disable maintenance mode (success or failure) command: "{{ php_cli_path }} occ maintenance:mode --off" args: chdir: "{{ nextcloud_dir }}" become_user: "{{ nc_web_user }}" environment: "{{ occ_env }}" ignore_errors: yes - name: Final failure (only triggered if rescue was hit) fail: msg: "Nextcloud upgrade failed — maintenance mode disabled." when: ansible_failed_task is defined