Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions build.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
version: 1
platform: python
platformVersion: "3.14"
# NOTE: platformVersion intentionally omitted — this is the FRICTIONS-observed bug condition.
# Per static analysis, this should: build with whatever Oryx auto-picks, runtime selects default (3.14).

run:
port: 8080
port: 8080
startCommand: "bash /output/diagnose.sh"
85 changes: 85 additions & 0 deletions diagnose.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/bin/bash
set +e
echo "=============================================="
echo "=== BUG-2 DIAGNOSTIC v2 :: $(date -u) ========"
echo "=============================================="

echo ""
echo "--- [A] Enumerate every python* binary in the runtime image ---"
ls -la /usr/bin/python* /usr/local/bin/python* /opt/*/bin/python* 2>&1 | sort -u
echo "PATH=$PATH"

echo ""
echo "--- [B] pyvenv.cfg of the shipped venv ---"
cat /app/pythonenv3.12/pyvenv.cfg 2>&1 || cat /output/pythonenv3.12/pyvenv.cfg 2>&1

echo ""
echo "--- [C] file & ldd of the venv's python binary ---"
file /app/pythonenv3.12/bin/python 2>&1 || file /output/pythonenv3.12/bin/python 2>&1
echo "----"
ldd /app/pythonenv3.12/bin/python 2>&1 | head -10 || ldd /output/pythonenv3.12/bin/python 2>&1 | head -10

echo ""
echo "--- [D] Try the path Oryx's runtime banner advertised ---"
echo "Banner said: PYTHONPATH=':/output/pythonenv3.12/lib/python3.14/site-packages'"
ls -d /output/pythonenv3.12/lib/python3.14/site-packages 2>&1
test -d /output/pythonenv3.12/lib/python3.14/site-packages && echo "EXISTS" || echo "DOES NOT EXIST"

echo ""
echo "--- [E] FAILURE MODE 1: user runs system python3.14 with banner's PYTHONPATH ---"
if command -v python3.14 >/dev/null 2>&1; then
PYTHONPATH=/output/pythonenv3.12/lib/python3.14/site-packages python3.14 -c "import fastapi; print('imported fastapi from', fastapi.__file__)" 2>&1
echo "Exit: $?"
else
echo "(no python3.14 in this image)"
fi

echo ""
echo "--- [F] FAILURE MODE 2: docs invariant reversed for platformVersion: 3.14 ---"
ls -d /output/pythonenv3.14 2>&1
test -d /output/pythonenv3.14 && echo "EXISTS" || echo "DOES NOT EXIST (the dir is named from build-time, so 3.14 venv would only exist when platformVersion=3.14)"

echo ""
echo "--- [G] FAILURE MODE 3: 3.12-built C-extension under 3.14 ABI interpreter ---"
echo "Find cp312 pydantic_core .so:"
find /output /app -name '_pydantic_core.cpython-3*.so' 2>/dev/null | head -5
if command -v python3.14 >/dev/null 2>&1; then
echo "Try loading cp312 wheel under python3.14:"
PYTHONPATH=/app/pythonenv3.12/lib/python3.12/site-packages python3.14 -c "import pydantic_core; print(pydantic_core.__version__)" 2>&1
echo "Exit: $?"
fi

echo ""
echo "--- [H] Oryx's runtime startup script (what generated the misleading banner) ---"
ls -la /app/oryx-startup.sh /output/oryx-startup.sh 2>&1
cat /app/oryx-startup.sh 2>&1 | head -60 || cat /output/oryx-startup.sh 2>&1 | head -60

echo ""
echo "--- [I] What runtime image are we in? ---"
cat /etc/os-release 2>&1 | head -5
echo "---"
test -f /opt/oryx/python_version_info && cat /opt/oryx/python_version_info
test -f /usr/local/oryx/python_version_info && cat /usr/local/oryx/python_version_info

echo ""
echo "--- [J] Confirm the basics from v1 still hold ---"
echo "which python: $(which python 2>&1)"
echo "python --version: $(python --version 2>&1)"
echo "/output/pythonenv3.12/bin/python --version: $(/output/pythonenv3.12/bin/python --version 2>&1)"
echo "sys.executable / sys.version:"
python -c "import sys; print(sys.executable); print(sys.version)" 2>&1

echo ""
echo "=============================================="
echo "=== BUG-2 DIAGNOSTIC v2 :: COMPLETE =========="
echo "=============================================="

exec python -c "
from http.server import HTTPServer, BaseHTTPRequestHandler
class H(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200); self.end_headers(); self.wfile.write(b'ok')
def log_message(self, *a): pass
print('[diag v2] healthcheck server listening on :8080', flush=True)
HTTPServer(('0.0.0.0', 8080), H).serve_forever()
"