Update playbooks/nextcloud-upgrade.yml

This commit is contained in:
2025-11-14 13:09:01 +00:00
parent 9431e69a1b
commit e47ab0e538
+131 -88
View File
@@ -1,21 +1,32 @@
- name: Resilient Nextcloud upgrade on Rocky Linux - name: Resilient & Environment-Aware Nextcloud Upgrade
hosts: all hosts: all
become: yes become: yes
vars:
# --- Configuration Variables ---
nextcloud_dir: /var/www/nextcloud
web_user: apache
php_cli: /usr/bin/php
service_name: httpd
# --- Environment for occ commands --- # ----------------------------------------------------------------------
# This avoids setting TMPDIR on every single task # ⚠️ REQUIRED USER VARIABLES
# ----------------------------------------------------------------------
# YOU MUST EDIT THESE 3 VARIABLES TO MATCH YOUR SERVER
vars:
# 1. The full path to your Nextcloud installation
nextcloud_dir: /var/www/nextcloud
# 2. The *exact* PHP CLI binary your Nextcloud uses
# (e.g., /usr/bin/php, /usr/bin/php8.1, /opt/remi/php81/root/bin/php)
php_cli_path: /usr/bin/php
# 3. The service name for your webserver or PHP-FPM
# (e.g., httpd, apache2, nginx, php8.1-fpm)
web_service_name: httpd
# ----------------------------------------------------------------------
# INTERNAL PLAYBOOK VARIABLES
# ----------------------------------------------------------------------
vars:
# Environment for all occ commands
occ_env: occ_env:
TMPDIR: /tmp TMPDIR: /tmp
# --- Core Apps --- # Core apps to NOT disable during upgrade
# Add any app you consider "core" and do NOT want to disable.
# user_ldap is a good example if you use it for auth.
core_apps: core_apps:
- activity - activity
- twofactor_nextcloud_notification - twofactor_nextcloud_notification
@@ -34,91 +45,123 @@
tasks: tasks:
- name: Reminder - ensure backups exist # ----------------------------------------------------------------------
debug: # 🛡️ STAGE 1: PREFLIGHT CHECKS & FACT GATHERING
msg: "⚠️ CRITICAL: Ensure you have valid DB + data directory backups BEFORE PROCEEDING!" # ----------------------------------------------------------------------
- name: 1.1 - Validate 'nextcloud_dir'
stat:
path: "{{ nextcloud_dir }}/config/config.php"
register: config_stat
- name: Pause playbook for 10 seconds to allow backup cancellation - name: 1.2 - Fail if 'config.php' not found
pause: fail:
seconds: 10 msg: |
prompt: "Press Ctrl+C and then 'A' to abort if you do not have backups." 'config.php' not found at '{{ nextcloud_dir }}/config/config.php'.
Please correct the 'nextcloud_dir' variable in the playbook.
when: not config_stat.stat.exists
# ---------------------------------------------------------------------- - name: 1.3 - 🧠 DISCOVER 'nc_web_user' from 'config.php' owner
# Step 1: Check current version set_fact:
# ---------------------------------------------------------------------- nc_web_user: "{{ config_stat.stat.owner }}"
- name: Get current Nextcloud version
command: "{{ php_cli }} occ status" - name: 1.4 - Display discovered file owner
debug:
msg: "Discovered Nextcloud web user: {{ nc_web_user }}"
- name: 1.5 - Validate 'php_cli_path'
stat:
path: "{{ php_cli_path }}"
register: php_stat
- name: 1.6 - Fail if 'php_cli_path' is not an executable file
fail:
msg: |
'php_cli_path' ('{{ php_cli_path }}') does not exist or is not executable.
Please correct the 'php_cli_path' variable.
when: not php_stat.stat.exists or not php_stat.stat.isexe
- name: 1.7 - Validate 'web_service_name'
service_facts:
- name: 1.8 - Fail if 'web_service_name' is not a known service
fail:
msg: |
'web_service_name' ('{{ web_service_name }}') is not a valid service on this host.
Please correct the 'web_service_name' variable.
when: "web_service_name not in ansible_facts.services"
- name: 1.9 - Get current NC status (and check if installed)
command: "{{ php_cli_path }} occ status"
args: args:
chdir: "{{ nextcloud_dir }}" chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}" become_user: "{{ nc_web_user }}"
register: occ_status register: occ_status
changed_when: false changed_when: false
failed_when: "'installed: true' not in occ_status.stdout" failed_when: "'installed: true' not in occ_status.stdout"
- name: Parse and show current version - name: 1.10 - Parse and show current version
set_fact: set_fact:
current_version: "{{ occ_status.stdout | regex_search('versionstring: (.*)', '\\1') | first | default('unknown') }}" current_version: "{{ occ_status.stdout | regex_search('versionstring: (.*)', '\\1') | first | default('unknown') }}"
when: occ_status.stdout is defined when: occ_status.stdout is defined
- name: Show current version - name: 1.11 - Show current version
debug: debug:
msg: "Current Nextcloud version: {{ current_version }}" msg: "Current Nextcloud version: {{ current_version }}"
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Step 2: Disable 3rd party apps # 🔄 STAGE 2: PRE-UPGRADE PREPARATION
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
- name: Get list of installed apps - name: 2.1 - Backup Reminder
command: "{{ php_cli }} occ app:list" debug:
msg: "⚠️ CRITICAL: Ensure you have valid DB + data directory backups BEFORE PROCEEDING!"
- name: 2.2 - Pause playbook for 10 seconds to allow cancellation
pause:
seconds: 10
prompt: "Press Ctrl+C and then 'A' to abort if you do not have backups."
- name: 2.3 - Get list of installed apps
command: "{{ php_cli_path }} occ app:list"
args: args:
chdir: "{{ nextcloud_dir }}" chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}" become_user: "{{ nc_web_user }}"
register: app_list register: app_list
changed_when: false changed_when: false
- name: Disable all non-core 3rd party apps - name: 2.4 - Disable all non-core 3rd party apps
command: "{{ php_cli }} occ app:disable {{ item }}" command: "{{ php_cli_path }} occ app:disable {{ item }}"
args: args:
chdir: "{{ nextcloud_dir }}" chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}" become_user: "{{ nc_web_user }}"
environment: "{{ occ_env }}" environment: "{{ occ_env }}"
loop: "{{ app_list.stdout_lines | select('match', '^[ ]*-[ ](.*):[ ]enabled$') | map('regex_replace', '^[ ]*-[ ](.*):[ ]enabled$', '\\1') | list }}" loop: "{{ app_list.stdout_lines | select('match', '^[ ]*-[ ](.*):[ ]enabled$') | map('regex_replace', '^[ ]*-[ ](.*):[ ]enabled$', '\\1') | list }}"
register: app_disable_result register: app_disable_result
when: item not in core_apps when: item not in core_apps
ignore_errors: yes # Don't fail if an app can't be disabled ignore_errors: yes # Don't fail if an app can't be disabled
- name: Save list of successfully disabled apps for re-enabling - name: 2.5 - Save list of successfully disabled apps
set_fact: set_fact:
disabled_apps: "{{ app_disable_result.results | selectattr('changed', 'defined') | selectattr('changed') | map(attribute='item') | list }}" 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 when: app_disable_result is defined and app_disable_result.results is defined
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Step 3: Begin Upgrade Transaction Block # 🚀 STAGE 3: TRANSACTIONAL UPGRADE BLOCK
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
- name: Perform Nextcloud Upgrade (Transactional) - name: 3.0 - Perform Nextcloud Upgrade (Transactional)
block: block:
- name: Check if maintenance mode is already active - name: 3.1 - Enable maintenance mode
command: "{{ php_cli }} occ maintenance:mode" command: "{{ php_cli_path }} occ maintenance:mode --on"
args: args:
chdir: "{{ nextcloud_dir }}" chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}" become_user: "{{ nc_web_user }}"
register: maint_status
changed_when: false
failed_when: false # Don't fail, just check output
- name: Enable maintenance mode
command: "{{ php_cli }} occ maintenance:mode --on"
args:
chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}"
environment: "{{ occ_env }}" environment: "{{ occ_env }}"
when: "'maintenance mode is not active' in maint_status.stdout"
- name: Run Nextcloud CLI updater (with retry logic) - name: 3.2 - Run Nextcloud CLI updater (with retry logic)
command: "{{ php_cli }} updater/updater.phar --no-interaction" command: "{{ php_cli_path }} updater/updater.phar --no-interaction"
args: args:
chdir: "{{ nextcloud_dir }}" chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}" become_user: "{{ nc_web_user }}"
environment: "{{ occ_env }}" environment: "{{ occ_env }}"
register: updater_result register: updater_result
until: until:
@@ -126,93 +169,93 @@
- "'Update successful' in updater_result.stdout or 'Nextcloud is already latest version' in updater_result.stdout" - "'Update successful' in updater_result.stdout or 'Nextcloud is already latest version' in updater_result.stdout"
retries: 3 retries: 3
delay: 10 delay: 10
# This is the final failure check for the updater itself
failed_when: failed_when:
- updater_result.rc != 0 - updater_result.rc != 0
- "'Nextcloud is already latest version' not in updater_result.stdout" - "'Nextcloud is already latest version' not in updater_result.stdout"
- name: Run occ upgrade - name: 3.3 - Run occ upgrade (This is the most critical step)
command: "{{ php_cli }} occ upgrade" command: "{{ php_cli_path }} occ upgrade"
args: args:
chdir: "{{ nextcloud_dir }}" chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}" become_user: "{{ nc_web_user }}"
environment: "{{ occ_env }}" environment: "{{ occ_env }}"
# CRITICAL: Do NOT ignore errors here. This is the main failure point. # CRITICAL: Do NOT ignore errors here. If this fails, we must stop.
- name: Add missing indices (optional cleanup) - name: 3.4 - Run optional cleanup commands
command: "{{ php_cli }} occ db:add-missing-indices" command: "{{ item }}"
args: args:
chdir: "{{ nextcloud_dir }}" chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}" become_user: "{{ nc_web_user }}"
environment: "{{ occ_env }}" environment: "{{ occ_env }}"
ignore_errors: yes loop:
- "{{ php_cli_path }} occ db:add-missing-indices"
- "{{ php_cli_path }} occ db:convert-filecache-bigint --no-interaction"
ignore_errors: yes # These are optional, so we ignore failures
- name: Convert filecache bigint fields (optional cleanup) - name: 3.5 - Disable maintenance mode (SUCCESS)
command: "{{ php_cli }} occ db:convert-filecache-bigint --no-interaction" command: "{{ php_cli_path }} occ maintenance:mode --off"
args: args:
chdir: "{{ nextcloud_dir }}" chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}" become_user: "{{ nc_web_user }}"
environment: "{{ occ_env }}"
ignore_errors: yes
- name: Disable maintenance mode (SUCCESS)
command: "{{ php_cli }} occ maintenance:mode --off"
args:
chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}"
environment: "{{ occ_env }}" environment: "{{ occ_env }}"
- name: Re-enable previously disabled 3rd party apps - name: 3.6 - Re-enable previously disabled 3rd party apps
command: "{{ php_cli }} occ app:enable {{ item }}" command: "{{ php_cli_path }} occ app:enable {{ item }}"
args: args:
chdir: "{{ nextcloud_dir }}" chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}" become_user: "{{ nc_web_user }}"
environment: "{{ occ_env }}" environment: "{{ occ_env }}"
loop: "{{ disabled_apps | default([]) }}" loop: "{{ disabled_apps | default([]) }}"
when: disabled_apps is defined and disabled_apps | length > 0 when: disabled_apps is defined and disabled_apps | length > 0
ignore_errors: yes # Don't let a single app fail the whole restart ignore_errors: yes # Don't let a single app fail the whole restart
- name: Restart web service - name: 3.7 - Restart web service
service: service:
name: "{{ service_name }}" name: "{{ web_service_name }}"
state: restarted state: restarted
- name: Check new Nextcloud version - name: 3.8 - Verify new version
command: "{{ php_cli }} occ status" command: "{{ php_cli_path }} occ status"
args: args:
chdir: "{{ nextcloud_dir }}" chdir: "{{ nextcloud_dir }}"
become_user: "{{ web_user }}" become_user: "{{ nc_web_user }}"
environment: "{{ occ_env }}" environment: "{{ occ_env }}"
register: occ_status_after register: occ_status_after
changed_when: false
- name: Display new version info - name: 3.9 - Display new version info
debug: debug:
var: occ_status_after.stdout var: occ_status_after.stdout
- name: ✅ Upgrade Complete - name: 3.10 - ✅ Upgrade Complete
debug: debug:
msg: "Nextcloud successfully upgraded!" msg: "Nextcloud successfully upgraded!"
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Step 4: Rescue Block (This ONLY runs if the 'block' above fails) # 🆘 STAGE 4: RESCUE BLOCK (This ONLY runs if STAGE 3 fails)
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
rescue: rescue:
- name: ❌ UPGRADE FAILED - REPORTING - name: ❌ UPGRADE FAILED - REPORTING
debug: debug:
msg: | msg: |
!!!!!!!!!! UPGRADE FAILED !!!!!!!!!! !!!!!!!!!! CRITICAL UPGRADE FAILURE !!!!!!!!!!
The playbook has failed during the upgrade block.
The server is being LEFT IN MAINTENANCE MODE for manual inspection. The server is being LEFT IN MAINTENANCE MODE for manual inspection.
Host: {{ inventory_hostname }} Host: {{ inventory_hostname }}
Discovered Web User: {{ nc_web_user }}
Please SSH to the host and check logs to fix manually. Please SSH to the host and check logs to fix manually.
Logs to check: Logs to check:
- {{ nextcloud_dir }}/data/updater.log - {{ nextcloud_dir }}/data/updater.log
- {{ nextcloud_dir }}/data/nextcloud.log - {{ nextcloud_dir }}/data/nextcloud.log
Run '{{ php_cli }} occ maintenance:mode --off' manually when fixed. Once fixed, run this command manually as the web user:
'{{ php_cli_path }} occ maintenance:mode --off'
- name: Fail the playbook run - name: 4.1 - Fail the playbook run
fail: fail:
msg: "Nextcloud upgrade failed. Host is in maintenance mode." msg: "Nextcloud upgrade failed. Host is in maintenance mode."