diff --git a/cyberpanel.sh b/cyberpanel.sh index acbff7055..bea973188 100644 --- a/cyberpanel.sh +++ b/cyberpanel.sh @@ -654,6 +654,9 @@ install_cyberpanel_direct() { systemctl enable mariadb 2>/dev/null || true systemctl enable lsws 2>/dev/null || true + # Clear any previous install temp folders so we never use stale extracted files + rm -rf /tmp/cyberpanel_install_* 2>/dev/null || true + # Create temporary directory for installation local temp_dir="/tmp/cyberpanel_install_$$" mkdir -p "$temp_dir" @@ -872,6 +875,8 @@ except: if [ -z "$archive_url" ] || [ "$installer_url" = "https://raw.githubusercontent.com/master3395/cyberpanel/stable/cyberpanel.sh" ]; then archive_url="https://github.com/master3395/cyberpanel/archive/stable.tar.gz" fi + # Append cache-bust so CDNs/proxies don't serve old installer (GitHub ignores query params) + archive_url="${archive_url}?nocache=$(date +%s 2>/dev/null || echo 0)" curl --silent -L -o install_files.tar.gz "$archive_url" 2>/dev/null if [ $? -ne 0 ] || [ ! -s "install_files.tar.gz" ]; then diff --git a/install/install_utils.py b/install/install_utils.py index 7a5f65974..82fb0656c 100644 --- a/install/install_utils.py +++ b/install/install_utils.py @@ -548,6 +548,17 @@ def call(command, distro, bracket, message, log=0, do_exit=0, code=os.EX_OK, she Returns: bool: True if successful, False if failed """ + # CRITICAL (first): Replace missing CyberPanel Python so old/cached installers never hit FileNotFoundError + if isinstance(command, str): + bad_path = '/usr/local/CyberPanel/bin/python' + if bad_path in command and not os.path.isfile(bad_path): + fallback = '/usr/bin/python3' + if not os.path.isfile(fallback): + fallback = '/usr/local/bin/python3' + if os.path.isfile(fallback): + command = command.replace(bad_path, fallback) + shell = True + # Check for apt lock before running apt commands if 'apt-get' in command or 'apt ' in command: if not wait_for_apt_lock(): @@ -573,23 +584,30 @@ def call(command, distro, bracket, message, log=0, do_exit=0, code=os.EX_OK, she command = re.sub(r'^(\s*)(?:sudo\s+)?(mysql|mariadb)(\s)', r'\g<1>' + mysql_bin + r'\g<3>', command, count=1) shell = True - # CRITICAL: /usr/local/CyberPanel/bin/python often missing on fresh install; use system Python for manage.py - if '/usr/local/CyberPanel/bin/python' in command and not os.path.isfile('/usr/local/CyberPanel/bin/python'): - fallback = '/usr/bin/python3' - if not os.path.isfile(fallback): - fallback = '/usr/local/bin/python3' - if os.path.isfile(fallback): - command = command.replace('/usr/local/CyberPanel/bin/python', fallback, 1) - shell = True # ensure shell so path with spaces is not split - finalMessage = 'Running: %s' % (message) stdOut(finalMessage, log) count = 0 while True: - if shell: - res = subprocess.call(command, shell=True) - else: - res = subprocess.call(shlex.split(command)) + try: + if shell: + res = subprocess.call(command, shell=True) + else: + res = subprocess.call(shlex.split(command)) + except FileNotFoundError as e: + # Old installer may pass /usr/local/CyberPanel/bin/python; retry with system python once + if isinstance(command, str) and '/usr/local/CyberPanel/bin/python' in command: + fallback = '/usr/bin/python3' + if not os.path.isfile(fallback): + fallback = '/usr/local/bin/python3' + if os.path.isfile(fallback): + command = command.replace('/usr/local/CyberPanel/bin/python', fallback) + shell = True + stdOut("Retrying with %s (CyberPanel python missing)" % fallback, log) + res = subprocess.call(command, shell=True) + else: + raise + else: + raise if resFailed(distro, res): count = count + 1