diff --git a/agent-node/bootstrap_installer.py b/agent-node/bootstrap_installer.py index 8d6f464..9aee2db 100644 --- a/agent-node/bootstrap_installer.py +++ b/agent-node/bootstrap_installer.py @@ -188,8 +188,12 @@ if os.path.exists(daemon_script): os.chdir(install_dir) sys.path.insert(0, install_dir) - import subprocess - subprocess.run([sys.executable, daemon_script]) + try: + import install_service + install_service.main() + except Exception as e: + _print(f"ERROR: install_service.py failed: {e}") + sys.exit(1) _print("Bootstrap complete. Agent is running in the background.") sys.exit(0) else: diff --git a/ai-hub/app/core/templates/provisioning/provision.py.j2 b/ai-hub/app/core/templates/provisioning/provision.py.j2 index 7cafb28..e507398 100644 --- a/ai-hub/app/core/templates/provisioning/provision.py.j2 +++ b/ai-hub/app/core/templates/provisioning/provision.py.j2 @@ -31,21 +31,24 @@ print(f"❌ Downloaded file is too small or corrupt ({size} bytes): {content}") sys.exit(1) -# 4. Run installer with --daemon (or --non-interactive) -print("[*] Bootstrapping agent...") -cmd = [ - sys.executable, "bootstrap_installer.py", +# 4. Import and run installer natively to avoid memory Map/SIGBUS errors from fork() +print("[*] Bootstrapping agent directly in-process...") +sys.argv = [ + "bootstrap_installer.py", "--daemon", "--hub", "{{ base_url }}", "--token", "{{ invite_token }}", "--node-id", "{{ node_id }}" ] + try: - subprocess.run(cmd, check=True) - print("✅ Provisioning complete! Node should be online in the Mesh Dashboard shortly.") -except subprocess.CalledProcessError as e: - print(f"❌ Provisioning failed! Installer exited with code {e.returncode}") - sys.exit(e.returncode) + sys.path.insert(0, install_dir) + import bootstrap_installer + bootstrap_installer.main() +except SystemExit as e: + if str(e) != "0" and e.code != 0: + print(f"❌ Provisioning failed! Installer exited with code {e}") + sys.exit(e.code if isinstance(e.code, int) else 1) except Exception as e: print(f"❌ Provisioning crashed: {e}") sys.exit(1)