From b89ed169ca4c837ed9b1ef43557a6ae15484d887 Mon Sep 17 00:00:00 2001 From: master3395 Date: Fri, 27 Mar 2026 23:02:32 +0100 Subject: [PATCH] upgrade sync: force match origin when checkout blocked; fail script if sync fails - 09_sync: stash -u + reset --hard; quarantine untracked paths; verify HEAD==origin/branch - Remove subshell/tee that hid git failures; set /etc/cyberpanel/last_git_sync_failed on error - cyberpanel_upgrade: exit 1 after final display if git sync failed - 11_display_final: show warning banner when CYBERPANEL_GIT_SYNC_OK!=1 --- cyberpanel_upgrade.sh | 11 ++- upgrade_modules/09_sync.sh | 103 ++++++++++++++++++++++------ upgrade_modules/11_display_final.sh | 7 +- 3 files changed, 99 insertions(+), 22 deletions(-) diff --git a/cyberpanel_upgrade.sh b/cyberpanel_upgrade.sh index 5310008d9..212cfb199 100644 --- a/cyberpanel_upgrade.sh +++ b/cyberpanel_upgrade.sh @@ -102,6 +102,15 @@ Pre_Upgrade_Setup_Repository Pre_Upgrade_Setup_Git_URL Pre_Upgrade_Required_Components Main_Upgrade -Sync_CyberCP_To_Latest +CYBERPANEL_GIT_SYNC_OK=0 +if Sync_CyberCP_To_Latest; then + CYBERPANEL_GIT_SYNC_OK=1 +else + echo -e "\e[31m[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: Git sync of /usr/local/CyberCP to origin/$Branch_Name failed. Panel code may be outdated. See /var/log/cyberpanel_upgrade_debug.log and /etc/cyberpanel/last_git_sync_failed\e[0m" | tee -a /var/log/cyberpanel_upgrade_debug.log +fi +export CYBERPANEL_GIT_SYNC_OK Post_Upgrade_System_Tweak Post_Install_Display_Final_Info +if [[ "$CYBERPANEL_GIT_SYNC_OK" -ne 1 ]]; then + exit 1 +fi diff --git a/upgrade_modules/09_sync.sh b/upgrade_modules/09_sync.sh index 3d385e818..4b9e9f038 100644 --- a/upgrade_modules/09_sync.sh +++ b/upgrade_modules/09_sync.sh @@ -1,30 +1,97 @@ #!/usr/bin/env bash # CyberPanel upgrade – sync CyberCP to latest commit. Sourced by cyberpanel_upgrade.sh. +# If local edits or untracked files block checkout, stash/quarantine and reset --hard to match origin. Sync_CyberCP_To_Latest() { + local SYNC_STATE_FILE="/etc/cyberpanel/last_git_sync_failed" + mkdir -p /etc/cyberpanel + rm -f "$SYNC_STATE_FILE" 2>/dev/null || true + if [[ ! -d /usr/local/CyberCP/.git ]]; then echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] No .git in /usr/local/CyberCP, skipping sync" | tee -a /var/log/cyberpanel_upgrade_debug.log return 0 fi + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Syncing /usr/local/CyberCP to latest commit for branch: $Branch_Name" | tee -a /var/log/cyberpanel_upgrade_debug.log - # Backup production settings so sync does not overwrite DB credentials / local config + if [[ -f /usr/local/CyberCP/CyberCP/settings.py ]]; then cp /usr/local/CyberCP/CyberCP/settings.py /tmp/cyberpanel_settings_backup.py echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Backed up settings.py for restore after sync" | tee -a /var/log/cyberpanel_upgrade_debug.log fi - ( - cd /usr/local/CyberCP - git fetch origin 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log - if git show-ref -q "refs/remotes/origin/$Branch_Name"; then - git checkout -B "$Branch_Name" "origin/$Branch_Name" 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log - else - git checkout "$Branch_Name" 2>/dev/null || true - git pull --ff-only origin "$Branch_Name" 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log || true + + if ! cd /usr/local/CyberCP; then + echo "1" > "$SYNC_STATE_FILE" + return 1 + fi + + local remote_ref="origin/$Branch_Name" + local fetch_rc sync_ok=0 + + git fetch origin "$Branch_Name" 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log + fetch_rc="${PIPESTATUS[0]}" + if [[ "$fetch_rc" -ne 0 ]]; then + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: git fetch origin $Branch_Name failed (exit $fetch_rc)" | tee -a /var/log/cyberpanel_upgrade_debug.log + echo "1" > "$SYNC_STATE_FILE" + return 1 + fi + + if ! git show-ref -q "refs/remotes/$remote_ref"; then + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: remote ref $remote_ref not found after fetch" | tee -a /var/log/cyberpanel_upgrade_debug.log + echo "1" > "$SYNC_STATE_FILE" + return 1 + fi + + _cp_force_sync_to_remote_tip() { + local ref="$1" quarantine dest rel + git checkout -B "$Branch_Name" "$ref" >> /var/log/cyberpanel_upgrade_debug.log 2>&1 + if [[ $? -eq 0 ]]; then + return 0 fi - ) - local sync_code=$? - # Merge production DATABASES into branch settings.py so DB creds survive without stripping - # new INSTALLED_APPS (webmail, emailDelivery, etc.). Blind full restore broke integrated webmail. + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Checkout blocked; stashing tracked+untracked changes and resetting --hard to $ref" | tee -a /var/log/cyberpanel_upgrade_debug.log + git stash push -u -m "cyberpanel-upgrade-auto-$(date +%s)" >> /var/log/cyberpanel_upgrade_debug.log 2>&1 || true + git reset --hard "$ref" >> /var/log/cyberpanel_upgrade_debug.log 2>&1 + if [[ $? -eq 0 ]]; then + return 0 + fi + quarantine="/root/cyberpanel_git_untracked_quarantine_$(date +%s)" + mkdir -p "$quarantine" + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] reset --hard still blocked; moving untracked paths to $quarantine" | tee -a /var/log/cyberpanel_upgrade_debug.log + # shellcheck disable=SC2162 + while IFS= read -r line; do + case "$line" in + \?\?*) + rel="${line#??}" + rel="${rel#"${rel%%[![:space:]]*}"}" + if [[ -n "$rel" ]] && [[ -e "$rel" ]]; then + dest="$quarantine/$rel" + mkdir -p "$(dirname "$dest")" + mv "$rel" "$dest" 2>/dev/null || mv "$rel" "$quarantine/" 2>/dev/null || true + fi + ;; + esac + done < <(git status --porcelain) + git reset --hard "$ref" >> /var/log/cyberpanel_upgrade_debug.log 2>&1 + return $? + } + + if _cp_force_sync_to_remote_tip "$remote_ref"; then + local local_h remote_h + local_h=$(git rev-parse HEAD 2>/dev/null) + remote_h=$(git rev-parse "$remote_ref" 2>/dev/null) + if [[ -n "$local_h" ]] && [[ -n "$remote_h" ]] && [[ "$local_h" == "$remote_h" ]]; then + sync_ok=1 + fi + fi + + if [[ "$sync_ok" -ne 1 ]]; then + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: /usr/local/CyberCP HEAD does not match $remote_ref after forced sync (local=$(git rev-parse HEAD 2>/dev/null), remote=$(git rev-parse "$remote_ref" 2>/dev/null))" | tee -a /var/log/cyberpanel_upgrade_debug.log + echo "1" > "$SYNC_STATE_FILE" + if [[ -f /tmp/cyberpanel_settings_backup.py ]]; then + cp /tmp/cyberpanel_settings_backup.py /usr/local/CyberCP/CyberCP/settings.py + fi + return 1 + fi + if [[ -f /tmp/cyberpanel_settings_backup.py ]] && [[ -f /usr/local/CyberCP/upgrade_modules/merge_production_settings.py ]]; then python3 /usr/local/CyberCP/upgrade_modules/merge_production_settings.py /tmp/cyberpanel_settings_backup.py /usr/local/CyberCP/CyberCP/settings.py 2>&1 | tee -a /var/log/cyberpanel_upgrade_debug.log if [[ "${PIPESTATUS[0]}" -eq 0 ]]; then @@ -36,22 +103,18 @@ Sync_CyberCP_To_Latest() { cp /tmp/cyberpanel_settings_backup.py /usr/local/CyberCP/CyberCP/settings.py echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Restored settings.py after sync (merge script missing)" | tee -a /var/log/cyberpanel_upgrade_debug.log fi - # LiteSpeed serves /static/ from public/static/; ensure it has latest baseTemplate static files (e.g. dashboard JS) + if [[ -d /usr/local/CyberCP/public/static ]] && [[ -d /usr/local/CyberCP/baseTemplate/static/baseTemplate ]]; then rsync -a /usr/local/CyberCP/baseTemplate/static/baseTemplate/ /usr/local/CyberCP/public/static/baseTemplate/ 2>/dev/null || \ cp -r /usr/local/CyberCP/baseTemplate/static/baseTemplate/* /usr/local/CyberCP/public/static/baseTemplate/ 2>/dev/null || true echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Synced baseTemplate static to public/static" | tee -a /var/log/cyberpanel_upgrade_debug.log fi - # Firewall UI (firewall.js) – so Firewall Rules and Banned IPs load correct layout and Modify buttons if [[ -d /usr/local/CyberCP/public/static ]] && [[ -f /usr/local/CyberCP/firewall/static/firewall/firewall.js ]]; then mkdir -p /usr/local/CyberCP/public/static/firewall cp -f /usr/local/CyberCP/firewall/static/firewall/firewall.js /usr/local/CyberCP/public/static/firewall/ 2>/dev/null && \ echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Synced firewall static to public/static" | tee -a /var/log/cyberpanel_upgrade_debug.log || true fi - if [[ $sync_code -eq 0 ]]; then - echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Sync completed. Current HEAD: $(git -C /usr/local/CyberCP rev-parse HEAD 2>/dev/null || echo 'unknown')" | tee -a /var/log/cyberpanel_upgrade_debug.log - else - echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Sync returned code $sync_code (non-fatal)" | tee -a /var/log/cyberpanel_upgrade_debug.log - fi + + echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Sync completed. Current HEAD: $(git -C /usr/local/CyberCP rev-parse HEAD 2>/dev/null || echo 'unknown')" | tee -a /var/log/cyberpanel_upgrade_debug.log return 0 } diff --git a/upgrade_modules/11_display_final.sh b/upgrade_modules/11_display_final.sh index 81b884c43..a1dcedcd6 100644 --- a/upgrade_modules/11_display_final.sh +++ b/upgrade_modules/11_display_final.sh @@ -22,7 +22,12 @@ _b " ▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒███ ▒▒▒▒▒▒ _b " ███ ▒███" _b " ▒▒██████" _b " ▒▒▒▒▒▒" -_b " *** UPGRADE COMPLETED SUCCESSFULLY! ***" +if [[ "${CYBERPANEL_GIT_SYNC_OK:-1}" -eq 1 ]]; then + _b " *** UPGRADE COMPLETED SUCCESSFULLY! ***" +else + _b " *** UPGRADE FINISHED BUT GIT SYNC FAILED - /usr/local/CyberCP MAY BE OUTDATED ***" + _b " See /var/log/cyberpanel_upgrade_debug.log (exit code will be non-zero)" +fi _b "" _bl