diff --git a/agent-node/VERSION b/agent-node/VERSION index c442f5e..32ffe12 100644 --- a/agent-node/VERSION +++ b/agent-node/VERSION @@ -1 +1 @@ -1.1.22 +1.1.23 diff --git a/agent-node/src/agent_node/core/updater.py b/agent-node/src/agent_node/core/updater.py index 29e1d3b..7900eb9 100644 --- a/agent-node/src/agent_node/core/updater.py +++ b/agent-node/src/agent_node/core/updater.py @@ -70,32 +70,23 @@ logger.error(f"[Updater] bootstrap_installer.py not found at {_BOOTSTRAPPER}") return False - logger.info("[Updater] Delegating update to bootstrap_installer.py ...") - result = subprocess.run( - [sys.executable, _BOOTSTRAPPER, - "--hub", _HUB_HTTP_URL, - "--token", _AUTH_TOKEN, - "--update-only", - "--install-dir", _AGENT_ROOT], - cwd=_AGENT_ROOT - ) - - if result.returncode == 0: - logger.info("[Updater] Update applied successfully. Handing over to new version...") - sys.stdout.flush() - sys.stderr.flush() - - # M7: On Windows, os.execv is sometimes unreliable or creates orphans. - # However, for a simple python script restart, it is the cleanest in-place method. - # We ensure all handles are flushed first. - try: - os.execv(sys.executable, [sys.executable] + sys.argv) - except Exception as e: - logger.error(f"[Updater] In-place restart failed: {e}. Falling back to Popen.") - subprocess.Popen([sys.executable] + sys.argv) - sys.exit(0) - else: - logger.error(f"[Updater] bootstrap_installer.py failed (exit {result.returncode}). Continuing with current version.") + logger.info("[Updater] Spawning detached bootstrap_installer.py ...") + try: + # We do NOT pass --update-only. This forces the bootstrapper to fully + # reinstall dependencies, download resources, and re-launch the agent cleanly. + # We immediately exit this process so Windows releases DLL file locks. + subprocess.Popen( + [sys.executable, _BOOTSTRAPPER, + "--hub", _HUB_HTTP_URL, + "--token", _AUTH_TOKEN, + "--install-dir", _AGENT_ROOT], + cwd=_AGENT_ROOT, + creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if os.name == 'nt' else 0 + ) + logger.info("[Updater] Detached bootstrapper spawned. Exiting parent process for update.") + sys.exit(0) + except Exception as e: + logger.error(f"[Updater] Failed to spawn bootstrapper: {e}") return False