v2.5.6: fix 404 after update without tunnel

This commit is contained in:
orohi
2026-07-28 11:00:34 +03:00
parent 2808a49fa5
commit ff7cc5c592
5 changed files with 95 additions and 24 deletions
+35 -13
View File
@@ -333,6 +333,15 @@ class UpdateManager:
return only
return extract_dir
def _verify_tree(self, root: str) -> Optional[str]:
app_py = os.path.join(root, 'app.py')
if not os.path.isfile(app_py):
return 'Release archive is missing app.py'
code, _, err = _run([sys.executable, '-m', 'py_compile', app_py], root, timeout=60)
if code != 0:
return f'Updated app.py failed validation: {err or code}'
return None
def _sync_tree(self, src_root: str) -> None:
for root, dirs, files in os.walk(src_root):
dirs[:] = [d for d in dirs if d not in ARCHIVE_SKIP_DIRS]
@@ -358,6 +367,9 @@ class UpdateManager:
src_root = self._extract_zip_root(extract_dir)
if not os.path.isdir(src_root):
return {'status': 'error', 'message': 'Invalid release archive layout'}
verify_err = self._verify_tree(src_root)
if verify_err:
return {'status': 'error', 'message': verify_err, 'method': 'archive'}
self._sync_tree(src_root)
except Exception as e:
return {'status': 'error', 'message': str(e), 'method': 'archive'}
@@ -406,25 +418,35 @@ class UpdateManager:
@staticmethod
def schedule_restart(app_root: str, delay_sec: float = 1.5) -> None:
in_docker = os.path.exists('/.dockerenv') or os.environ.get('PANEL_IN_DOCKER') == '1'
def _restart():
time.sleep(max(0.5, float(delay_sec)))
argv = [sys.executable] + sys.argv
cwd = os.path.abspath(app_root or os.getcwd())
logger.info('Restarting panel after update: %s (cwd=%s)', argv, cwd)
argv = [sys.executable] + sys.argv
logger.info('Restarting panel after update: %s (cwd=%s, docker=%s)', argv, cwd, in_docker)
if in_docker:
# Let Docker restart policy bring the container back with updated /app files.
os._exit(0)
try:
os.chdir(cwd)
proc = subprocess.Popen(
argv,
cwd=cwd,
start_new_session=True,
close_fds=(os.name != 'nt'),
)
time.sleep(2.0)
if proc.poll() is None:
logger.info('New panel process started (pid=%s), stopping old process', proc.pid)
os._exit(0)
except Exception:
logger.exception('subprocess restart failed; trying execv')
try:
os.chdir(cwd)
os.execv(sys.executable, argv)
except Exception:
logger.exception('execv restart failed; trying subprocess fallback')
try:
subprocess.Popen(
argv,
cwd=cwd,
close_fds=True,
start_new_session=True,
)
except Exception:
logger.exception('Failed to restart after update')
os._exit(0)
logger.exception('Failed to restart after update')
os._exit(1)
threading.Thread(target=_restart, name='panel-update-restart', daemon=False).start()