diff --git a/playbooks/nextcloud-upgrade.yml b/playbooks/nextcloud-upgrade.yml index 302e57a..14c0d62 100644 --- a/playbooks/nextcloud-upgrade.yml +++ b/playbooks/nextcloud-upgrade.yml @@ -1,18 +1,34 @@ ---- -- name: Safe Nextcloud upgrade on Rocky Linux +- name: Safe Nextcloud upgrade on Rocky Linux (Fixed and Updated) hosts: all become: yes vars: + # --- Configuration Variables --- nextcloud_dir: /var/www/nextcloud web_user: apache php_cli: /usr/bin/php service_name: httpd + # List of core apps to ensure we don't try to disable them + 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: "⚠️ Ensure you have valid DB + data directory backups before upgrade!" + msg: "⚠️ CRITICAL: Ensure you have valid DB + data directory backups BEFORE PROCEEDING!" # ---------------------------------------------------------------------- # Step 1: Check current version @@ -24,9 +40,10 @@ become_user: "{{ web_user }}" register: occ_status changed_when: false - failed_when: occ_status.rc != 0 and "'installed: true'" not in occ_status.stdout + # FIX: Only fail if Nextcloud is NOT installed/ready for upgrade + failed_when: "'installed: true' not in occ_status.stdout" - - name: Parse current version + - name: Parse and show current version set_fact: current_version: "{{ occ_status.stdout | regex_search('versionstring: (.*)', '\\1') | first | default('unknown') }}" when: occ_status.stdout is defined @@ -35,6 +52,35 @@ debug: msg: "Current Nextcloud version: {{ current_version }}" + # ---------------------------------------------------------------------- + # Step 1.5: Disable 3rd party apps (Best Practice Addition) + # ---------------------------------------------------------------------- + - name: Get list of enabled apps + command: "{{ php_cli }} occ app:list --installed" + args: + chdir: "{{ nextcloud_dir }}" + become_user: "{{ web_user }}" + register: app_list + changed_when: false + + - name: Disable all non-core 3rd party apps + command: "{{ php_cli }} occ app:disable {{ item }}" + args: + chdir: "{{ nextcloud_dir }}" + become_user: "{{ web_user }}" + environment: + TMPDIR: /tmp + loop: "{{ app_list.stdout_lines | select('match', '^[ ]*-[ ](.*):[ ]enabled$') | map('regex_replace', '^[ ]*-[ ](.*):[ ]enabled$', '\\1') | list }}" + register: app_disable_result + # Only process apps that are not in the core_apps list + when: item not in core_apps + ignore_errors: yes + + - name: Save list of successfully disabled apps for re-enabling + 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 + # ---------------------------------------------------------------------- # Step 2: Enable maintenance mode # ---------------------------------------------------------------------- @@ -47,51 +93,26 @@ TMPDIR: /tmp # ---------------------------------------------------------------------- - # Step 3: Run updater safely with retry + # Step 3: Run updater safely with retry (Fixed and Simplified) # ---------------------------------------------------------------------- - - name: Run Nextcloud CLI updater (non-interactive) - block: - - - name: Execute updater (first attempt) - command: "{{ php_cli }} updater/updater.phar --no-interaction" - args: - chdir: "{{ nextcloud_dir }}" - become_user: "{{ web_user }}" - environment: - TMPDIR: /tmp - register: updater_result - failed_when: false - - - name: Detect signature verification failure - debug: - msg: "Signature verification failed, cleaning downloads before retry." - when: "'Signature of update is not valid' in updater_result.stdout" - - - name: Clean failed update downloads if signature invalid - file: - path: "{{ nextcloud_dir }}/data" - state: directory - when: "'Signature of update is not valid' in updater_result.stdout" - - - name: Retry updater if signature invalid - command: "{{ php_cli }} updater/updater.phar --no-interaction" - args: - chdir: "{{ nextcloud_dir }}" - become_user: "{{ web_user }}" - environment: - TMPDIR: /tmp - when: "'Signature of update is not valid' in updater_result.stdout" - register: updater_result_retry - failed_when: false - - - name: Check updater success - fail: - msg: "Nextcloud updater failed. Check updater log or rerun manually." - when: - - updater_result.rc != 0 - - "'Nextcloud is already latest version' not in updater_result.stdout" - - "'Update successful' not in updater_result.stdout" - - "'Update successful' not in (updater_result_retry.stdout | default(''))" + - name: Run Nextcloud CLI updater (non-interactive) with retry logic + command: "{{ php_cli }} updater/updater.phar --no-interaction" + args: + chdir: "{{ nextcloud_dir }}" + become_user: "{{ web_user }}" + environment: + TMPDIR: /tmp + register: updater_result + # FIX: Use Ansible's retry mechanism for transient errors (e.g., signature fails, temporary network issue) + 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 + # Final failure condition + failed_when: + - updater_result.rc != 0 + - "'Nextcloud is already latest version' not in updater_result.stdout" # ---------------------------------------------------------------------- # Step 4: Run database upgrade + cleanup @@ -104,7 +125,7 @@ environment: TMPDIR: /tmp - - name: Add missing indices (optional) + - name: Add missing indices (optional cleanup) command: "{{ php_cli }} occ db:add-missing-indices" args: chdir: "{{ nextcloud_dir }}" @@ -113,7 +134,7 @@ TMPDIR: /tmp ignore_errors: yes - - name: Convert filecache bigint fields (optional) + - name: Convert filecache bigint fields (optional cleanup) command: "{{ php_cli }} occ db:convert-filecache-bigint --no-interaction" args: chdir: "{{ nextcloud_dir }}" @@ -134,6 +155,20 @@ TMPDIR: /tmp ignore_errors: yes + # ---------------------------------------------------------------------- + # Step 5.5: Re-enable disabled apps (Best Practice Addition) + # ---------------------------------------------------------------------- + - name: Re-enable previously disabled 3rd party apps + command: "{{ php_cli }} occ app:enable {{ item }}" + args: + chdir: "{{ nextcloud_dir }}" + become_user: "{{ web_user }}" + environment: + TMPDIR: /tmp + loop: "{{ disabled_apps | default([]) }}" + when: disabled_apps is defined and disabled_apps | length > 0 + ignore_errors: yes + # ---------------------------------------------------------------------- # Step 6: Restart web service # ---------------------------------------------------------------------- @@ -156,4 +191,4 @@ - name: Display new version info debug: - var: occ_status_after.stdout + var: occ_status_after.stdout \ No newline at end of file