mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-15 17:25:26 -04:00
fix(setup): clear error when setup runs under x86/Rosetta Python (#941)
Add a check_arch() guard that fails fast with actionable guidance when setup runs on Apple Silicon under an Intel (x86_64) Python via Rosetta — otherwise compiled deps (bcrypt, pydantic-core, …) load as the wrong architecture and crash later with a cryptic "incompatible architecture" import error. Also catch that specific error around the bcrypt import and print rebuild steps. Rebased onto current main: the start-macos.sh venv-Python changes that were part of this branch are dropped, since they're already on main via PR #978. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,9 @@ initial admin user. Safe to re-run (skips what already exists).
|
||||
"""
|
||||
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -117,7 +119,16 @@ def create_default_admin():
|
||||
print(f" Temporary password: {password}")
|
||||
print(f" ** Change it after first login. Set ODYSSEUS_ADMIN_PASSWORD to choose your own. **")
|
||||
return "created"
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
if "incompatible architecture" in str(e).lower():
|
||||
# bcrypt is present but built for the wrong CPU architecture — the
|
||||
# same Apple Silicon mismatch check_arch() guards against, caught here
|
||||
# for the rarer case of an x86 wheel inside an arm64 venv.
|
||||
print(" [error] bcrypt loaded with the wrong CPU architecture.")
|
||||
print(" Rebuild the venv with an arm64 Python:")
|
||||
print(" rm -rf venv && /opt/homebrew/bin/python3.11 -m venv venv")
|
||||
print(" ./venv/bin/pip install -r requirements.txt")
|
||||
return "skipped"
|
||||
print(" [warn] bcrypt not installed — skipping admin user creation")
|
||||
print(" Run: pip install bcrypt")
|
||||
return "skipped"
|
||||
@@ -167,9 +178,52 @@ def check_deps():
|
||||
print(" [ok] tmux installed")
|
||||
|
||||
|
||||
def check_arch():
|
||||
"""Stop early, with guidance, if we're on Apple Silicon but running an
|
||||
Intel (x86_64) Python through Rosetta.
|
||||
|
||||
A venv built with such an interpreter installs and loads compiled packages
|
||||
(bcrypt, pydantic-core, onnxruntime, …) for the wrong CPU architecture, then
|
||||
dies deep inside an import with a cryptic
|
||||
"(mach-o file, but is an incompatible architecture)" error. Catching it here
|
||||
turns that into one clear, actionable message.
|
||||
"""
|
||||
if sys.platform != "darwin" or platform.machine() == "arm64":
|
||||
return # Not macOS, or already an arm64-native interpreter — nothing to do.
|
||||
|
||||
# platform.machine() == "x86_64": either a genuine Intel Mac (fine) or an x86
|
||||
# interpreter running under Rosetta on Apple Silicon (the case we must catch).
|
||||
try:
|
||||
translated = subprocess.run(
|
||||
["sysctl", "-n", "sysctl.proc_translated"],
|
||||
capture_output=True, text=True, timeout=5,
|
||||
).stdout.strip()
|
||||
except Exception:
|
||||
translated = ""
|
||||
if translated != "1":
|
||||
return # Genuine Intel Mac — carry on.
|
||||
|
||||
print("\n [error] This is an Apple Silicon Mac, but setup is running under an")
|
||||
print(" Intel (x86_64) Python through Rosetta. Compiled packages would")
|
||||
print(' load as the wrong architecture and crash with "incompatible')
|
||||
print(' architecture" later on.')
|
||||
print("\n Rebuild the environment with Homebrew's arm64 Python:")
|
||||
print(" brew install python@3.11 # if you don't have it yet")
|
||||
print(" rm -rf venv")
|
||||
print(" /opt/homebrew/bin/python3.11 -m venv venv")
|
||||
print(" ./venv/bin/pip install -r requirements.txt")
|
||||
print(" ./venv/bin/python setup.py")
|
||||
print("\n Tip: ./start-macos.sh does all of this with the right Python.\n")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
print("\n=== Odysseus Setup ===\n")
|
||||
|
||||
# Fail fast with a clear message if the CPU architecture is wrong (Apple
|
||||
# Silicon under an x86/Rosetta Python) before importing anything native.
|
||||
check_arch()
|
||||
|
||||
print("1. Creating directories...")
|
||||
create_dirs()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user