diff --git a/playbooks/nextcloud-upgrade.yml b/playbooks/nextcloud-upgrade.yml index 9c21932..1d7decd 100644 --- a/playbooks/nextcloud-upgrade.yml +++ b/playbooks/nextcloud-upgrade.yml @@ -1,130 +1,140 @@ --- -- name: Nextcloud Upgrade +- name: Safe Nextcloud Upgrade Playbook hosts: nextcloud become: yes - vars: - ansible_remote_tmp: "/var/tmp/.ansible" - nextcloud_path: "/var/www/nextcloud" - php_bin: "/usr/bin/php" - - pre_tasks: - - name: Ensure remote tmp exists - file: - path: "/var/tmp/.ansible" - state: directory - owner: root - group: root - mode: "0755" + nc_path: /var/www/nextcloud + php_bin: /usr/bin/php tasks: - - name: Pause playbook for 3 seconds - pause: - seconds: 3 + - name: Pause playbook for 3 seconds + pause: + seconds: 3 + prompt: "Press Ctrl+C then A to abort if no backups exist." - - name: 1.1 - Get current Nextcloud status - command: "{{ php_bin }} occ status --output=json" + ########################################################################### + # 1 - CHECK CURRENT INSTALLED VERSION + ########################################################################### + - name: 1.1 - Get current NC status + command: "{{ php_bin }} occ status" + args: + chdir: "{{ nc_path }}" + register: nc_status + + - name: 1.2 - Extract installed version + set_fact: + installed_version: "{{ nc_status.stdout | regex_search('versionstring: (.*)', '\\1') }}" + + - name: 1.3 - Show installed version + debug: + msg: "Current installed version: {{ installed_version }}" + + ########################################################################### + # 2 - CHECK LATEST AVAILABLE VERSION (via updater.phar) + ########################################################################### + - name: 2.1 - Check for available update + command: "{{ php_bin }} updater/updater.phar --check" + args: + chdir: "{{ nc_path }}" + register: update_check + failed_when: false # we want to parse output even if exit code != 0 + + - name: 2.2 - Parse latest available version + set_fact: + available_version: "{{ update_check.stdout | regex_search('Update to version (.*) available', '\\1') }}" + when: update_check.stdout is search('Update to version') + + - name: 2.3 - Show available version + debug: + msg: "Latest available version: {{ available_version | default('NONE') }}" + + ########################################################################### + # 2.4 - SKIP IF ALREADY UP TO DATE + ########################################################################### + - name: 2.4 - Skip upgrade if already on latest version + debug: + msg: "Nextcloud is already up to date ({{ installed_version }}). Skipping upgrade." + when: available_version is not defined + tags: skip_upgrade + changed_when: false + + - name: End play if up to date + meta: end_play + when: available_version is not defined + + ########################################################################### + # 3 - DISABLE APPS + MAINTENANCE MODE + ########################################################################### + - name: 3.1 - Enable maintenance mode + command: "{{ php_bin }} occ maintenance:mode --on" + args: + chdir: "{{ nc_path }}" + + ########################################################################### + # 3.2 - RUN UPDATER WITH RETRIES + ########################################################################### + - name: 3.2 - Run Nextcloud CLI updater (retry) + command: "{{ php_bin }} updater/updater.phar --no-interaction" + args: + chdir: "{{ nc_path }}" + register: updater_output + retries: 3 + delay: 5 + until: updater_output.rc == 0 + failed_when: updater_output.rc != 0 + + ########################################################################### + # 3.3 - OCC UPGRADE (DB MIGRATIONS) + ########################################################################### + - block: + - name: 3.3 - Run occ upgrade + command: "{{ php_bin }} occ upgrade" args: - chdir: "{{ nextcloud_path }}" - register: nc_status_json + chdir: "{{ nc_path }}" + register: upgrade_run + failed_when: > + upgrade_run.rc != 0 and + "already in process" not in upgrade_run.stdout and + "maintenance mode" not in upgrade_run.stdout - - name: 1.2 - Parse current version - set_fact: - nc_current_version: "{{ (nc_status_json.stdout | from_json).versionstring }}" + rescue: + - name: 3.3R - Handle locked upgrade + debug: + msg: "Upgrade appears stuck. Removing maintenance lock and retrying." - - name: 1.3 - Show current version - debug: - msg: "Current Nextcloud version: {{ nc_current_version }}" + - name: Remove maintenance mode flag from config.php + lineinfile: + path: "{{ nc_path }}/config/config.php" + regexp: "'maintenance' => true" + line: " 'maintenance' => false," + backrefs: yes - - name: 2.1 - Get list of installed apps - command: "{{ php_bin }} occ app:list --output=json" - args: - chdir: "{{ nextcloud_path }}" - register: app_list + - name: Retry OCC upgrade + command: "{{ php_bin }} occ upgrade" + args: + chdir: "{{ nc_path }}" + register: upgrade_retry + failed_when: upgrade_retry.rc != 0 - - name: 2.2 - Disable 3rd-party apps (non-core) - command: "{{ php_bin }} occ app:disable {{ item }}" - args: - chdir: "{{ nextcloud_path }}" - loop: "{{ (app_list.stdout | from_json).enabled | difference(['files','activity','dav','federation','files_external','files_sharing','files_trashbin','files_versions','lookup_server_connector','notifications','provisioning_api','settings','systemtags','theming','updatenotification','user_status']) }}" - register: disabled_apps - changed_when: "'Disabled' in disabled_apps.stdout" - when: false # Optional: Disabled if you want. + ########################################################################### + # 4 - ALWAYS DISABLE MAINTENANCE MODE + ########################################################################### + - name: ALWAYS disable maintenance mode + command: "{{ php_bin }} occ maintenance:mode --off" + args: + chdir: "{{ nc_path }}" + ignore_errors: true - - name: 2.3 - Save disabled apps list - set_fact: - nc_disabled_apps: "{{ disabled_apps.results | map(attribute='item') | list }}" - - - name: 3.1 - Enable maintenance mode - command: "{{ php_bin }} occ maintenance:mode --on" - args: - chdir: "{{ nextcloud_path }}" - register: maintenance_on - changed_when: true - - - block: - - # ─────────────────────────────── - # 3.2 — RUN NEXTCLOUD UPDATER - # ─────────────────────────────── - - name: 3.2 - Run Nextcloud CLI updater - command: "{{ php_bin }} updater/updater.phar --no-interaction" - args: - chdir: "{{ nextcloud_path }}" - register: updater_output - retries: 3 - delay: 3 - until: updater_output.rc == 0 - - - name: Check if update actually happened - set_fact: - update_message: "{{ updater_output.stdout }}" - - - name: If already newest version, show message - debug: - msg: "Nextcloud is already at the latest version. Nothing to upgrade." - when: "'No update available' in updater_output.stdout" - - # ─────────────────────────────── - # 3.3 — DATABASE UPGRADE - # ─────────────────────────────── - - name: 3.3 - Run occ upgrade (only if update occurred) - command: "{{ php_bin }} occ upgrade" - args: - chdir: "{{ nextcloud_path }}" - register: occ_upgrade_output - when: "'No update available' not in updater_output.stdout" - - rescue: - - name: ❌ UPGRADE FAILED - Details - debug: - msg: | - !!!!!!!!!!! NEXTCLOUD UPGRADE FAILED !!!!!!!!!!!! - Check logs: - - {{ nextcloud_path }}/data/updater.log - - {{ nextcloud_path }}/data/nextcloud.log - - - name: Mark failure - set_fact: - upgrade_failed: true - - always: - - - name: ALWAYS disable maintenance mode - command: "{{ php_bin }} occ maintenance:mode --off" - args: - chdir: "{{ nextcloud_path }}" - - post_tasks: - - - name: Final status - debug: - msg: >- - Upgrade finished successfully (or nothing to update). - when: upgrade_failed is not defined - - - name: Final failure - debug: - msg: "Nextcloud upgrade failed — maintenance mode disabled." - when: upgrade_failed is defined + ########################################################################### + # 5 - FINAL RESULT + ########################################################################### + - name: Show final upgrade result + debug: + msg: | + ✔ Nextcloud upgrade completed. + Installed: {{ installed_version }} + Updated to: {{ available_version }} + Check logs if issues appear: + - {{ nc_path }}/data/updater.log + - {{ nc_path }}/data/nextcloud.log